iOS PCM音频数据转wav
2022-01-19 本文已影响0人
发疯的code
// 将pcm存为wav文件
- (NSString *) getAndCreatePlayableFileFromPcmData{
NSArray *arrDocumentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentPath = [arrDocumentPaths objectAtIndex:0];
NSString *dirFilePath = [documentPath stringByAppendingPathComponent:@"audio"];
// 注意这里必须要有这个文件夹,下面存储音频时才不会报错
if (![[NSFileManager defaultManager] fileExistsAtPath:dirFilePath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dirFilePath withIntermediateDirectories:YES attributes:nil
error:NULL];
}
NSDate *date = [NSDate date];
NSString *fileName = [NSString stringWithFormat:@"iOS_%@.wav",[self.dateFormatter stringFromDate:date]];
NSString *wavFilePath = [dirFilePath stringByAppendingPathComponent:fileName];
short NumChannels = 1; //录音通道数
short BitsPerSample = 16; //线性采样位数
int SamplingRate = 16000; //录音采样率(Hz)
int numOfSamples = (int)self.recordedData.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;
const char *wavFilePathChar = [wavFilePath cStringUsingEncoding:NSUTF8StringEncoding];
@synchronized (self) {
FILE *fout = fopen(wavFilePathChar, "w");
if(fout == NULL){
return nil;
}
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);
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForUpdatingAtPath:wavFilePath];
[handle seekToEndOfFile];
// self.recordedData 为需要保存的pcm数据
[handle writeData:self.recordedData];
[handle closeFile];
return wavFilePath;
}
}