Thoughts on the Playhead [Titled Changed]
-
@Christoph-Hart, As the Transport Handler appears to only a subset, please add back into at least the Development branch:
void MainController::storePlayheadIntoDynamicObject(AudioPlayHead::CurrentPositionInfo &) { static const Identifier bpmId("bpm"); static const Identifier timeSigNumerator("timeSigNumerator"); static const Identifier timeSigDenominator("timeSigDenominator"); static const Identifier timeInSamples("timeInSamples"); static const Identifier timeInSeconds("timeInSeconds"); static const Identifier editOriginTime("editOriginTime"); static const Identifier ppqPosition("ppqPosition"); static const Identifier ppqPositionOfLastBarStart("ppqPositionOfLastBarStart"); // static const Identifier frameRate("frameRate"); static const Identifier isPlaying("isPlaying"); static const Identifier isRecording("isRecording"); static const Identifier ppqLoopStart("ppqLoopStart"); static const Identifier ppqLoopEnd("ppqLoopEnd"); static const Identifier isLooping("isLooping"); ScopedLock sl(getLock()); hostInfo->setProperty(bpmId, newPosition.bpm); hostInfo->setProperty(timeSigNumerator, newPosition.timeSigNumerator); hostInfo->setProperty(timeSigDenominator, newPosition.timeSigDenominator); hostInfo->setProperty(timeInSamples, newPosition.timeInSamples); hostInfo->setProperty(timeInSeconds, newPosition.timeInSeconds); hostInfo->setProperty(editOriginTime, newPosition.editOriginTime); hostInfo->setProperty(ppqPosition, newPosition.ppqPosition); hostInfo->setProperty(ppqPositionOfLastBarStart, newPosition.ppqPositionOfLastBarStart); // hostInfo->setProperty(frameRate, newPosition.frameRate); hostInfo->setProperty(isPlaying, newPosition.isPlaying); hostInfo->setProperty(isRecording, newPosition.isRecording); hostInfo->setProperty(ppqLoopStart, newPosition.ppqLoopStart); hostInfo->setProperty(ppqLoopEnd, newPosition.ppqLoopEnd); hostInfo->setProperty(isLooping, newPosition.isLooping); }
-
@clevername27 And are you able to get something from
Engine.getPlayHead()
? It appears to be an empty object...
I'm opening a new thread for related issues and info... -
@ustk Engine.getPlayHead() is empty because the code above is commented out. This code provides direct access to JUCE's AudioPlayHead::CurrentPositionInfo. @Christoph-Hart instead implemented the semi-wrapper, TransportHandler. But he left the code in place (just commented out) in case you want to use the struct. I agree this is the way to do it, because TransportHanlder can ultimately provide higher-level functionality, which is the whole point of HISE—and he left the direct stuff in case you want that. The bug is in the documentation (which is still a bug, of course; a bug is any difference between expected and actual behavior).
-
@clevername27 Do you have a minimal snippet to demonstrate the playHead object? When I print it it's empty...
-
Console.print(Engine.getPlayHead().bpm);
This is especially helpful as, at least for me, TransportHandler's init callbacks sometimes fail. Use the structs in your own init or wherever to get initial values.
-
@clevername27 Oh I see it's commented out by default... Then we can push a pull request ourselves with all the lines un-commented
-
@ustk Lol, I just wrote that—it was the point of the post.
-
@clevername27 Lol sorry my English isn't good enough, I thought you meant to ask Chris to do it
-
@clevername27 Sorry but I don't see any pull request in the git
-
@ustk EDIT: I misunderstood; you mean the request is correct place for me to do it—you're right, and I will do.
-
Not sure about that - it will increase the CPU load for each buffer callback (not much, but since 99% don't use it it will be too much).
TransportHandler's init callbacks sometimes fail.
When is this the case? I'd rather fix those than reintroduce the JSON object.
-
@clevername27 said in Source Change Request:
@ustk I did; or somebody. I'm not an employee.
Me neither... But that's the only option we have to add things sometimes since Chris can't do it all, unfortunately. Making simple stuff ourselves allows Chris to have more time for the things we can't do. I'd like to get a quicker reaction for our requests too. But participating to Hise at our level brings many advantages like having fixes and implementations as fast as we want, give more time to Chris for important things, and learn C++ and the Hise structure...
-
@Christoph-Hart Thank you for your response. My $0.2 is that since the TransportHandler (currently) doesn't provide access to the same data, and doesn't seem to allow it the same way, then there's no need to keep that code commented out—especially when the documentation says it is. As to when is the case, I appreciate you asking, but I'm not sure how to answer that—it happens in my code, but maybe I'm doing something wrong that breaks it. (That's why I wrote "seems to", instead of saying there was a problem; it works in your demo code.)
-
@ustk (Yes you're right; my bad.)
-
it happens in my code, but maybe I'm doing something wrong that breaks it.
Can you make a minimal snippet that triggers the issue?
-
@d-healey I really appreciate the offer—it's just too much code to go through and untangle. But thank you, kindly.
-
What property are you missing in the TransportHandler? I don't think that reenabling those properties is a good default - it's old, deprecated and slow and is only there for people who started projects before the TransportHandler and I'd rather remove the entire method altogether than reenabling the properties.
-
@Christoph-Hart Thank you for your question. Just the kinds of things that lower-level access allows. I realize the struct is deprecated and may go away at some point.
-
Polling parameters (e.g., bpm and time signature) when needed, instead of keeping track of them with callbacks — it's a cool feature when you need to know when something has changed, but otherwise can be a little clumsy?
-
This may be my own issue, but the callbacks aren't being called at init. (They obviously work in your code example.)
-
Writing your own callbacks — for example, I want to show the user the seconds and samples of the DAW's playhead with high granularity—like the display in the MIDI keyboard. Another is example is doing calculations on the playhead in real-time.
-
The specific things in CurrentPositionInfo that simply aren't available in the Transport API, such as whether the DAW is recording or not.
-