我正在编写C++代码,它同时播放数字音频(合成音乐)和MIDI音乐(使用RtMidi库)。数字化音乐将通过计算机的音频设备播放,但MIDI音乐可以通过外部合成器播放。我想播放一首同时使用数字化乐器和MIDI乐器的歌曲,我不确定有什么最佳方法来同步这两种音频流:
目前,我使用的只是在Linux下才能工作的nanosleep(),而不是Windows --等待笔记之间的正确时间。这允许数字音频和MIDI数据保持同步,但是Nanos休眠()并不十分一致,因此产生的速度非常不均匀。
有谁能想出一种方法来为数字音频和MIDI数据保留准确的音符之间的时间?
发布于 2012-06-10 14:30:40
如果你愿意使用Boost,它有CPU精密定时器。如果不是,在Windows上有一些函数QueryPerformanceCounter和QueryPerformanceFrequency,它们可以用于基于CPU的计时,这肯定适合您的所有需求。web上有大量的计时器类实现,其中一些在windows和*ix系统上都可以使用。
发布于 2012-06-11 14:51:21
第一个问题是,您需要知道有多少音频通过音频设备。如果您的延迟足够低,您可能可以根据您所推送的数据量进行猜测,但该延迟与回放之间的延迟是一个移动目标,因此您应该尝试从音频硬件中获取这些信息。这些信息是可用的,所以请使用它,因为从延迟度量的错误中得到的“抖动”可以以一种音乐上明显的方式影响同步。
如果您必须使用睡眠来计时,则有两个问题会使其睡眠时间更长: 1.优先级(如果另一个进程/线程具有更高的优先级,则如果计时器已用完,则该优先级将运行)和2.系统延迟(如果系统需要5毫秒来交换进程/线程,则可能会将其添加到所请求的延迟时间)。这类延迟在音乐上是相关的。大多数midi api都有一个“顺序器”api,它允许您预先对数据进行排队,以避免使用系统定时器。
您可能会发现这个文档很有用,即使您没有将port音频用于音频I/O。
acmc2003.pdf
发布于 2012-06-10 14:42:23
答案不在于小缓冲,而在于大缓冲。
让我们举一首3分钟的歌为例。
其中一个首先呈现数字部分,并用MIDI注释“标记”它。然后,一个人开始播放它,并在时机成熟时触发MIDI音符,可能会使用std::vector来保存一个有序列表。可以通过使用总时间偏移量来更改同步:
可怕的、不完整的,但希望是关于这个主题的示范性伪码:
start_digital_playing_thread();
int midi_time_sync = 10; // ms
if (time >= (midi_note[50]->time + midi_time_sync)) // play notehttps://stackoverflow.com/questions/10969254
复制相似问题