iOS 浮动缓冲区到音频播放

iOS float buffer to audio playback

我是 iOS 编程的新手,我正在尝试操作音频文件的某些音频特征,这需要音频数据作为能够成功获取的浮点值。

我对如何将浮点值作为音频数据播放感到困惑。我使用其文档调查了很多 iOS 框架,但其中大多数不允许我处理浮点数据。它主要是读取和播放音频文件以及控制一些播放参数。

简而言之:

Objective: 将 buffer/array 个浮点值(最初是音频数据)作为音频播放。

总体Process:Audio文件->读取到浮动缓冲区(完成)->操作(可以做)->播放为音频(不想存储为文件)

如果问题太幼稚,我们深表歉意。感谢所有帮助。谢谢

我支持 sbooth 的评论。有关播放的好教程,请查找 2014 WWDC Videos。你想看:

如果你使用AVAudioPlayer,有一个initWithData 以NSData 为参数。所以看起来你的挑战是 loading your float buffer into NSData.

您还没有评论浮动缓冲区的格式(即 pcm、单声道、立体声、交错等)
如果您需要低延迟、更精细的功能或更模糊的音频格式,您还可以正确使用 RemoteIO audio unit to play back buffers of audio. You should be able to feed it a buffer of floats assuming that you initialize the AudioStreamBasicDescription 以使其与您的音频格式兼容。

感谢@jaybers 我采用了类似的解决方案。抱歉没有早点发布。

解决方法: 1) 我 built/coded header 用于在 BYTE * 类型数组中播放(最简单的 PCM)。 2) 将 header 附加到 NSDATA 数组。 3) 将浮点数据附加到 NSDATA 数组 4) 使用 AVAudioPlayer 播放它....

我遇到的一个问题:我的数据是 16 位,而 IOS 中的浮点数是 32 位,所以以 16 位 PCM / 32 位 PCM 播放它会引入噪音 - 我认为是因为额外的零。所以我将浮点数据传输到短数据类型数组并将其附加到 NSDATA 并将其作为 16 位 PCM 播放 - 完美播放。

代码:

//mynewdata1 is a short datatype 16bit array

NSData *Wave1= [NSMutableData dataWithData:mynewdata1]; 

unsigned long totalAudioLen=[Wave1 length];
unsigned long totalDataLen = totalAudioLen + 44;
unsigned long longSampleRate = 4*11025.0;
unsigned int channels = 1;
unsigned long byteRate = (16 * longSampleRate * channels)/8;

Byte *header = (Byte*)malloc(44);
header[0] = 'R';  // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (Byte) (totalDataLen & 0xff);
header[5] = (Byte) ((totalDataLen >> 8) & 0xff);
header[6] = (Byte) ((totalDataLen >> 16) & 0xff);
header[7] = (Byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f';  // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1;  // format = 1 for pcm and 2 for byte integer
header[21] = 0;
header[22] = (Byte) channels;
header[23] = 0;
header[24] = (Byte) (longSampleRate & 0xff);
header[25] = (Byte) ((longSampleRate >> 8) & 0xff);
header[26] = (Byte) ((longSampleRate >> 16) & 0xff);
header[27] = (Byte) ((longSampleRate >> 24) & 0xff);
header[28] = (Byte) (byteRate & 0xff);
header[29] = (Byte) ((byteRate >> 8) & 0xff);
header[30] = (Byte) ((byteRate >> 16) & 0xff);
header[31] = (Byte) ((byteRate >> 24) & 0xff);
header[32] = (Byte) (16*1)/8;  // block align
header[33] = 0;
header[34] = 16;  // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (Byte) (totalAudioLen & 0xff);
header[41] = (Byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (Byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (Byte) ((totalAudioLen >> 24) & 0xff);

NSData *headerData = [NSData dataWithBytes:header length:44];
NSMutableData * soundFileData1 = [NSMutableData alloc];
[soundFileData1 appendData:headerData];
[soundFileData1 appendData:Wave1];

self.avap1 = [[AVAudioPlayer alloc] initWithData:soundFileData1 fileTypeHint:@"wav" error:&error1];
[self.avap3 play]; //to play