如何添加可玩(如WAV,WMV)头与iOS的PCM数据/缓冲? [英] How to add playable(such as wav,wmv) header with PCM data/buffer in iOS?
问题描述
我想加一个wav头的原始PCM数据之上,使之通过AVAudioPlayer播放。但我无法找到任何解决方案或源$ C $ C要做到这一点使用的Objective-C /斯威夫特的iOS。虽然我发现<一个href=\"http://stackoverflow.com/questions/24772844/convert-a-pcm-float-buffer-to-a-wav-nsdata\">this但它不具有正确的答案。
I am trying to add a wav header on top of raw PCM data to make it playable via AVAudioPlayer. But i couldn't find any solution or source code to do that on iOS using Objective-C/Swift. Though i found this but it doesn't have correct answer.
但我发现了一张code 这里这是在C和还含有一些问题。 WAV文件无法正常播放的是从code产生的。
But i found a piece of code here which is in C and also contains some issue. The wav file doesn't play properly which is generated from that code.
我已经给我的codeS下面,我有codeD为止。
I have given my codes below which i have coded so far.
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数据/缓冲)。那么,我错过在我的code?任何帮助将是非常美联社preciated。
The file is playing too fast, the sound is distorted and only first 10 to 20(around) seconds are playing. I think, the wav header isn't generating correctly(Because i am able to play same PCM data/buffer using AudioUnit/AudioQueue). So what i am missing in my code ? Any help would be highly appreciated.
先谢谢了。
推荐答案
OK,我回答我的问题,如果它可以帮助别人。经过不懈的努力几天,最后我有它的工作。下面是Objective-C的写了一个完整的功能和C.它需要一个文件路径,其中包含从麦克风直接拍摄的RAW PCM数据,并返回一个包含PCM数据并采取适当的wav头信息的文件路径的参数。然后你就可以玩AVAudioPlayer或AVPlayer该文件。这里是code ...
OK, I am answering my own question if it helps someone else. After few days of tireless trying, at last i have got it working. Below is a complete Function written with Objective-C and C. It takes a file path as a parameter which contains RAW PCM data directly captured from microphone and returns a file path which contains PCM data followed by appropriate wav header info. Then you can play that file with AVAudioPlayer or AVPlayer. Here is the code...
- (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];
}
但是,这功能只下面的音频设置工作。
But that function only works with the following audio settings.
// 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
这篇关于如何添加可玩(如WAV,WMV)头与iOS的PCM数据/缓冲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!