【问题标题】:iOS float buffer to audio playbackiOS 浮动缓冲区到音频播放
【发布时间】:2015-03-31 15:35:12
【问题描述】:
我是 iOS 编程新手,我正在尝试操作音频文件的一些音频特征,这需要音频数据作为能够成功获取的浮点值。
我被困在如何将浮点值作为音频数据播放。我使用它的文档调查了很多 iOS 框架,但大多数都不允许我处理浮点数据。它主要是读取和播放音频文件并控制一些播放参数。
简而言之:
目标:将浮点值(最初是音频数据)的缓冲区/数组作为音频播放。
总体流程:音频文件->读取到浮动缓冲区(完成)->操作(可以做)->作为音频播放(不想存储为文件)
如果问题非常幼稚,请道歉。感谢所有帮助。谢谢。
【问题讨论】:
标签:
ios
objective-c
core-audio
【解决方案3】:
感谢@jaybers,我采用了类似的解决方案。很抱歉没有早点发布。
解决方案:
1)我在 BYTE * 类型数组中构建/编码了用于播放的标头(最简单的是 PCM)。
2) 将标头附加到 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