在 MIDI 播放线程上降低 CPU
Lowering CPU on MIDI playback thread
下面的函数是 运行 在分离的 std::thread 上。代码本身是使用 JUCE API(因此 Array<> object & MidiMessage)编写的。
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within the bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
//intialise start time
double timestart = Time::getMillisecondCounterHiRes();
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
double elapsedTime = Time::getMillisecondCounterHiRes() - timestart;
//output message whens appropriate
if(elapsedTime > messages[i].getTimeStamp())
{
//output this message
masterMidiOutput->sendMessageNow(messages[i]);
//increment through the array
i++;
}
}
}
}
我需要实时输出 MIDI 消息,但不必 运行 通过循环条件以至于 CPU 运行 非常热。
有什么想法吗?我对如何以不需要用计时器不断检查的顺序播放消息感到困惑。
提前致谢。
//=========================================== ==========================
更新尝试休眠线程...
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within a bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
}
//intialise start time
double previousTimeStamp = 0;
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
//fire off all note on messages
while(messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; //increment to the next
}
//fire off all note off messages
while(!messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; // do the next one
//if the next message is back to a note on command
if(messages[i+1].isNoteOn() == true)
{
//sleep for x amount of time
int sleepTime = messages[i].getTimeStamp() - previousTimeStamp;
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
previousTimeStamp = messages[i].getTimeStamp();
}
}
}
}
}
要停止线程内的构建,最好打开和关闭计时器对象并逐条触发每条消息。
广播消息 (Action Broadcaster ) 可以用来跟踪索引。
这里有一些示例代码来给出总体思路:
MIDIThing::MIDIThing ()
{
startTimer(1); //start a timer
}
void MIDIThing::start ()
{
playstate = 1;
startTime = Time::getCurrentTime().toMilliseconds();
}
void MIDIThing::timerCallback()
{
if (playstate == 1) {
Time::getMillisecondCounterHiRes();
int64 target;
if (Time::getCurrentTime().toMilliseconds() > target) {
//fire off the message
}
//ended (possibly on a condition)
ActionBroadcaster::sendActionMessage(FINISHED_PLAYBACK);
}
}
下面的函数是 运行 在分离的 std::thread 上。代码本身是使用 JUCE API(因此 Array<> object & MidiMessage)编写的。
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within the bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
//intialise start time
double timestart = Time::getMillisecondCounterHiRes();
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
double elapsedTime = Time::getMillisecondCounterHiRes() - timestart;
//output message whens appropriate
if(elapsedTime > messages[i].getTimeStamp())
{
//output this message
masterMidiOutput->sendMessageNow(messages[i]);
//increment through the array
i++;
}
}
}
}
我需要实时输出 MIDI 消息,但不必 运行 通过循环条件以至于 CPU 运行 非常热。
有什么想法吗?我对如何以不需要用计时器不断检查的顺序播放消息感到困惑。
提前致谢。
//=========================================== ========================== 更新尝试休眠线程...
void triggerMidiMessages(Array<Array<MidiMessage>> messageBundle)
{
//for each group of messages (bar) within a bundle
for(int bar = 0; bar < messageBundle.size(); bar ++)
{
//store our message from the bundle for playback
Array<MidiMessage> messages;
messages.clear();
messages = messageBundle[bar];
}
//intialise start time
double previousTimeStamp = 0;
//for each midi inside a single "gene"
for(int i = 0; i <= messages.size();)
{
//fire off all note on messages
while(messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; //increment to the next
}
//fire off all note off messages
while(!messages[i].isNoteOn())
{
masterMidiOutput->sendMessageNow(messages[i]);
i++; // do the next one
//if the next message is back to a note on command
if(messages[i+1].isNoteOn() == true)
{
//sleep for x amount of time
int sleepTime = messages[i].getTimeStamp() - previousTimeStamp;
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
previousTimeStamp = messages[i].getTimeStamp();
}
}
}
}
}
要停止线程内的构建,最好打开和关闭计时器对象并逐条触发每条消息。
广播消息 (Action Broadcaster ) 可以用来跟踪索引。
这里有一些示例代码来给出总体思路:
MIDIThing::MIDIThing ()
{
startTimer(1); //start a timer
}
void MIDIThing::start ()
{
playstate = 1;
startTime = Time::getCurrentTime().toMilliseconds();
}
void MIDIThing::timerCallback()
{
if (playstate == 1) {
Time::getMillisecondCounterHiRes();
int64 target;
if (Time::getCurrentTime().toMilliseconds() > target) {
//fire off the message
}
//ended (possibly on a condition)
ActionBroadcaster::sendActionMessage(FINISHED_PLAYBACK);
}
}