我不确定是否有可能达到我想要的效果,但基本上我有一个代表录音的NSDictionary。这是在什么时间点播放声音id的时间线。
我拥有它可以播放这个时间轴/录音,而且效果很好。
我想知道是否还有这个时间轴,并将其导出为单个声音,如果设备与iTunes同步,可以将其保存到计算机中。
所以基本上我问我是否可以采用声音的时间轴,播放它并将这些声音拼接成一个声音,然后可以导出。
我使用OpenAL作为我的声音框架,声音文件都是CAF。
感谢任何帮助或指导。
谢谢!
答案 0 :(得分:1)
您将需要:
以下是该做什么:
在您的应用中启用文件共享(info.plist中为UIFileSharingEnabled=YES
,并将文件写入/Documents
目录)。
将使用过的声音渲染到包含线性PCM音频数据的内存缓冲区中(如果它们尚未存在,即如果它们已被压缩)。您可以使用音频队列的离线渲染功能执行此操作(请参阅Apple audio queue docs)。如果你将它们全部渲染到相同的PCM格式和采样率(例如16位带符号样本@ 44,100Hz,我会在所有示例中使用这种格式),它会使事情变得更容易很多,并使用相同的格式输出。我建议从Mono格式开始,然后在它工作后添加立体声。
选择未压缩的输出格式并将声音混合到一个流中:
3.1。分配足够大的缓冲区,或打开要写入的文件流。
3.2。写出任何标题(例如,如果使用WAV格式输出而不是原始PCM)并在第一个声音开始之前写入零(或样本范围的中间点,如果不使用带符号的样本格式)进行任何初始静音。例如,如果你想在第一个声音之前静音0.1秒,写入4410(0.1 * 44100)零样本,即写入4410短路(16位)全部为零。
3.3。现在跟踪所有“正在播放”的声音并将它们混合在一起。从一个空的“当前正在播放的声音”列表开始,并跟踪您正在混音的样本的“当前时间”,对于您写出的每个样本,将“当前时间”增加1.0/sample_rate
。当有时间开始另一个声音时,将其添加到“当前正在播放”列表中,样本偏移为0.现在要进行混音,您将遍历所有“当前正在播放”的声音并将其当前样本加在一起,然后增加每个样本的样本偏移量。将求和值写入输出缓冲区。例如,如果soundA从0.1秒开始(在静音之后)并且soundB从0.2秒开始,则对于样本8820,您将执行相当于output[8820] = soundA[4410] + soundB[0];
的操作,对于样本8821,您将执行output[8821] = soundA[4411] + soundB[1];
等等。作为声音结束(你到达其样本的末尾)只需将其从“当前播放”列表中删除,并继续直到音频数据结束。
3.4。上述简单混合(样本总和)确实存在一些问题。例如,如果两个样本的值加起来大于32767,则不能将其存储在有符号的16位数中,这称为剪切。现在,只需将值钳位到32767,然后使其工作......稍后再回来并实现一个简单的限制器(参见最后的说明)。
现在您的音轨的混合版本采用未压缩的线性PCM格式,这可能已足够,因此请将其写入/Documents
。如果您想以压缩格式编写它,您需要获取音频编码器的源并通过它运行线性PCM输出。
简单限制器:
让我们选择限制样本范围的前10%,因此如果绝对值大于29490(int limitBegin = (int)(32767 * 0.9f);
),我们将缩小该值。最大可能峰值为int maxSampleValue = 32767 * numPlayingSounds;
,我们希望将值limitBegin
以上的值扩展到32767处的峰值。因此,根据上述非常简单的混频器求和到sampleValue
,然后:< / p>
if(sampleValue > limitBegin)
{
float overLimit = (sampleValue - limitBegin) / (float)(maxSampleValue - limitBegin);
sampleValue = limitBegin + (int)(overLimit * (32767 - limitBegin));
}
如果您正在注意,您会注意到当numPlayingSounds
发生变化时(例如当新声音开始时),限制器变得更加(或更少)刺耳,这可能会导致音量突然变化(在有限的范围内)以适应额外的声音。您可以使用最大数量的播放声音,或设计一些巧妙的方法来在几毫秒内提升限制器。
请记住,这是以sampleValue
的绝对值运行(在签名格式中可能是负数),因此这里的代码只是为了演示这个想法。您需要正确编写它以处理样品范围两端(峰值和谷值)的限制。此外,在混音过程中你可以采取一些技巧来优化上述所有内容 - 你可能会在编写混音器时发现它们,小心并让它先工作,然后再根据需要重新进行重构/优化。
还要记住要考虑正在使用的平台的字节序以及要写入的文件格式,因为您可能需要进行一些字节交换。
答案 1 :(得分:0)
如果您的文件以简单格式存储,那么一种不太难的方法就是手动将它们组合在一起。也就是说,使用caf格式创建一个新文件,并手动将所需的部分组合在一起。
如果声音未压缩(线性PCM),这将非常简单。但是,请在这里阅读caf文件格式的文件: