如何在iOS中添加可播放的(如wav,wmv)标题与PCM数据/缓冲区?

我正在尝试在原始PCM数据的顶部添加一个wav头文件,以便通过AVAudioPlayer进行播放。 但我找不到任何解决scheme或源代码在iOS上使用Objective-C / Swift进行操作。 虽然我发现这个,但是没有正确的答案。

但是我在这里find了一段代码,里面包含了一些问题。 wav文件无法正确播放该代码生成的文件。

我已经给我的代码下面,我已经编码到目前为止。

int NumChannels = AUDIO_CHANNELS_PER_FRAME; short BitsPerSample = AUDIO_BITS_PER_CHANNEL; int SamplingRate = AUDIO_SAMPLE_RATE; int numOfSamples = [[NSData dataWithContentsOfFile:filePath] length]; int ByteRate = NumChannels*BitsPerSample*SamplingRate/8; short BlockAlign = NumChannels*BitsPerSample/8; int DataSize = NumChannels*numOfSamples*BitsPerSample/8; int chunkSize = 16; int totalSize = 36 + DataSize; short audioFormat = 1; if((fout = fopen([wavFilePath cStringUsingEncoding:1], "w")) == NULL) { printf("Error opening out file "); } fwrite("RIFF", sizeof(char), 4,fout); fwrite(&totalSize, sizeof(int), 1, fout); fwrite("WAVE", sizeof(char), 4, fout); fwrite("fmt ", sizeof(char), 3, fout); fwrite(&chunkSize, sizeof(int),1,fout); fwrite(&audioFormat, sizeof(short), 1, fout); fwrite(&NumChannels, sizeof(short),1,fout); fwrite(&SamplingRate, sizeof(int), 1, fout); fwrite(&ByteRate, sizeof(int), 1, fout); fwrite(&BlockAlign, sizeof(short), 1, fout); fwrite(&BitsPerSample, sizeof(short), 1, fout); fwrite("data", sizeof(char), 3, fout); fwrite(&DataSize, sizeof(int), 1, fout); 

文件播放速度过快,声音失真,只有前10到20(秒)播放。 我认为,wav头没有正确生成(因为我能够使用AudioUnit / AudioQueue播放相同的PCM数据/缓冲区)。 那么我在代码中缺less什么? 任何帮助将不胜感激。

提前致谢。

好的,我正在回答自己的问题,如果它帮助别人。 经过几天的不懈努力,最后我得到了它的工作。 下面是使用Objective-C和C编写的一个完整的函数。它将文件path作为参数,包含从麦克风直接捕获的RAW PCM数据,并返回包含PCM数据的文件path,后面是相应的wav头信息。 然后您可以使用AVAudioPlayer或AVPlayer播放该文件。 这里是代码…

 - (NSURL *) getAndCreatePlayableFileFromPcmData:(NSString *)filePath { NSString *wavFileName = [[filePath lastPathComponent] stringByDeletingPathExtension]; NSString *wavFileFullName = [NSString stringWithFormat:@"%@.wav",wavFileName]; [self createFileWithName:wavFileFullName]; NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsDir = [dirPaths objectAtIndex:0]; NSString *wavFilePath = [docsDir stringByAppendingPathComponent:wavFileFullName]; NSLog(@"PCM file path : %@",filePath); FILE *fout; short NumChannels = AUDIO_CHANNELS_PER_FRAME; short BitsPerSample = AUDIO_BITS_PER_CHANNEL; int SamplingRate = AUDIO_SAMPLE_RATE; int numOfSamples = [[NSData dataWithContentsOfFile:filePath] length]; int ByteRate = NumChannels*BitsPerSample*SamplingRate/8; short BlockAlign = NumChannels*BitsPerSample/8; int DataSize = NumChannels*numOfSamples*BitsPerSample/8; int chunkSize = 16; int totalSize = 46 + DataSize; short audioFormat = 1; if((fout = fopen([wavFilePath cStringUsingEncoding:1], "w")) == NULL) { printf("Error opening out file "); } fwrite("RIFF", sizeof(char), 4,fout); fwrite(&totalSize, sizeof(int), 1, fout); fwrite("WAVE", sizeof(char), 4, fout); fwrite("fmt ", sizeof(char), 4, fout); fwrite(&chunkSize, sizeof(int),1,fout); fwrite(&audioFormat, sizeof(short), 1, fout); fwrite(&NumChannels, sizeof(short),1,fout); fwrite(&SamplingRate, sizeof(int), 1, fout); fwrite(&ByteRate, sizeof(int), 1, fout); fwrite(&BlockAlign, sizeof(short), 1, fout); fwrite(&BitsPerSample, sizeof(short), 1, fout); fwrite("data", sizeof(char), 4, fout); fwrite(&DataSize, sizeof(int), 1, fout); fclose(fout); NSMutableData *pamdata = [NSMutableData dataWithContentsOfFile:filePath]; NSFileHandle *handle; handle = [NSFileHandle fileHandleForUpdatingAtPath:wavFilePath]; [handle seekToEndOfFile]; [handle writeData:pamdata]; [handle closeFile]; return [NSURL URLWithString:wavFilePath]; } 

但是,该function只适用于以下audio设置。

 // Audio settings. #define AUDIO_SAMPLE_RATE 8000 #define AUDIO_FRAMES_PER_PACKET 1 #define AUDIO_CHANNELS_PER_FRAME 1 #define AUDIO_BITS_PER_CHANNEL 16 #define AUDIO_BYTES_PER_PACKET 2 #define AUDIO_BYTES_PER_FRAME 2