2

オーディオデータをWAVファイルに保存しようとしています-通常RemoteIOで使用しているオーディオデータがありますが、データを保存する関数を実装しようとしています。オーディオデータが有効であることがわかっているので、それは問題ではありません。正しい長さの空のWAVファイルを設定できれば、後でデータを入力できます。

現在、コードはファイルを作成し、バイト単位で正しい長さのように見えますが、OSX、QuickTime、iTunesなどがファイルを認識できないため(ファイルを表示し、ファイルを判別できないため、正しくフォーマットされていないようです)長さ、またはそれを再生します)

    NSURL * tvarFilename = [savePanel URL];
    NSLog(@"doSaveAs filename = %@",tvarFilename);        

    //try to create an audio file there

    AudioFileID mRecordFile;

    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate         = 44100.00;
    audioFormat.mFormatID           = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mChannelsPerFrame   = 2;
    audioFormat.mBitsPerChannel     = 16;
    audioFormat.mBytesPerPacket     = 4;
    audioFormat.mBytesPerFrame      = 4;



    OSStatus status = AudioFileCreateWithURL((CFURLRef)tvarFilename, kAudioFileWAVEType, &audioFormat, kAudioFileFlags_EraseFile, &mRecordFile);

    int beatsToRecord = 4; //temporary

    int bpm = 120;

    double intervalInSamples = (double) 60 / bpm;
    intervalInSamples *= (double)44100;

    int inNumberFrames = (intervalInSamples * beatsToRecord);

    UInt32 frameBuffer[inNumberFrames];

    int sampleTime = 0;

    UInt32 thisSubBuffer[inNumberFrames];

    for (int i = 0; i < inNumberFrames; i++) { frameBuffer[i] = 0; }

    UInt32 bytesToWrite = inNumberFrames * sizeof(UInt32);
    status = AudioFileWriteBytes(mRecordFile, false, 0, &bytesToWrite, &frameBuffer);
4

2 に答える 2

1

WAVファイルは非常に単純です。(通常は44バイトの長さの)ヘッダーセクションと、生のPCMデータのみで構成されます。私はWAVファイルを記録する必要のあるライブラリを作成しました。私がそれをどのように達成するかをあなたが理解してくれると確信しています。明確にするために:

/**
 * CD quality: 44100 Hz sample rate, 16 bit per sample, 2 channels (stereo):
**/
struct sprec_wav_header *hdr = sprec_wav_header_from_params(44100, 16, 2);
int filesize = (obtain the filesize somehow here);
/**
 * -8 bytes for the first part of the header, see the WAV specification
**/
hdr->filesize = filesize - 8;
int filedesc = open("/tmp/dummy.wav", O_WRONLY | O_CREAT, 0644);
if (sprec_wav_header_write(filedesc, hdr))
{
    printf("Error writing WAV header!\n");
}
close(filedesc);
free(hdr);

そして私が書いたライブラリ:https ://github.com/H2CO3/libsprec/

お役に立てれば。

于 2012-05-05T18:51:50.183 に答える
1

最初の質問のコードの問題は、AudioFileClose(mRecordFile);最後に行が欠落していることでした。

サードパーティのライブラリを使用せずに動作するサンプルを検索する場合は、少し変更されたコードスニペットを次に示します。

- (void)createSilentWAVFileAtURL:(NSURL *)fileURL {
    AudioFileID mRecordFile;

    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate         = 44100.00;
    audioFormat.mFormatID           = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mChannelsPerFrame   = 2;
    audioFormat.mBitsPerChannel     = 16;
    audioFormat.mBytesPerPacket     = 4;
    audioFormat.mBytesPerFrame      = 4;

    OSStatus status = AudioFileCreateWithURL((__bridge CFURLRef)fileURL, kAudioFileWAVEType, &audioFormat, kAudioFileFlags_EraseFile, &mRecordFile);

    double intervalInSamples = 0.5;
    intervalInSamples *= audioFormat.mSampleRate * audioFormat.mChannelsPerFrame;

    int beatsToRecord = 4; //seconds of silence
    int inNumberFrames = (intervalInSamples * beatsToRecord);

    UInt32 frameBuffer[inNumberFrames];

    for (int i = 0; i < inNumberFrames; i++) { frameBuffer[i] = 0; }

    UInt32 bytesToWrite = inNumberFrames * sizeof(uint32_t);
    status = AudioFileWriteBytes(mRecordFile, false, 0, &bytesToWrite, &frameBuffer);
    status = AudioFileClose(mRecordFile);

    NSAssert(status == noErr, @"");
}

PS:最終的なファイルサイズを減らすmChannelsPerFrameには、2から1に減らしますmSampleRate(例:11000)

于 2016-05-16T15:56:58.527 に答える