2

这是学习核心音频http://www.amazon.com/Learning-Core-Audio-Hands-On-Programming/dp/0321636848
的代码 就像书中说的那样,生成立体声应该设置 asbd.mBitsPerChannel 为 8 和 asbd。 mChannelsPerFrame 为 2 。但是我得到的音频只有一个通道。我不知道代码有什么问题,请帮助我。谢谢

#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>

#define SAMPLE_RATE 44100
#define DURATION 5.0
#define FILENAME_FORMAT @"%0.3f-square.aif"

int main(int argc, const char * argv[])
{

@autoreleasepool {
    if (argc < 2) {
        printf("Usage: CAToneFileGenerator n\n(where n is tone in Hz)");
        return -1;
    }

    double hz = atof(argv[1]);
    assert(hz > 0);
    NSLog(@"generating %f hz tone", hz);

    NSString *fileName = [NSString stringWithFormat:FILENAME_FORMAT, hz];
    NSString *filePath = [[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:fileName];
    NSLog(@"%@", filePath);
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];

    AudioStreamBasicDescription asbd;
    memset(&asbd, 0, sizeof(asbd));
    asbd.mSampleRate = SAMPLE_RATE;
    asbd.mFormatID = kAudioFormatLinearPCM;
    asbd.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    asbd.mBitsPerChannel = 8;
    asbd.mChannelsPerFrame = 2;
    asbd.mFramesPerPacket = 1;
    asbd.mBytesPerFrame = 2;
    asbd.mBytesPerPacket = 2;

    AudioFileID audioFile;
    OSStatus audioErr = noErr;
    audioErr = AudioFileCreateWithURL((CFURLRef) fileURL, kAudioFileAIFFType, &asbd, kAudioFileFlags_EraseFile, &audioFile);
    assert(audioErr == noErr);

    long maxSampleCount = SAMPLE_RATE * DURATION;
    long sampleCount = 0;
    UInt32 bytesToWrite = 2;
    double wavelengthInSamples = SAMPLE_RATE / hz;

    while (sampleCount < maxSampleCount) {
        for (int i = 0; i < wavelengthInSamples; i++) {
            SInt16 sample;
            if (i < wavelengthInSamples /2) {
                sample = CFSwapInt16HostToBig(SHRT_MAX);
            }else{
                sample = CFSwapInt16HostToBig(SHRT_MIN);
            }

            audioErr = AudioFileWriteBytes(audioFile, false, sampleCount*2, &bytesToWrite, &sample);
            assert(audioErr == noErr);
            sampleCount ++;
        }
    }
    audioErr = AudioFileClose(audioFile);
    assert(audioErr == noErr);
    NSLog(@"wrote %ld samples", sampleCount);
}
return 0;
}
4

1 回答 1

2

仅仅从书本代码中更改 ASBD 并不能神奇地解决所有问题。您还没有考虑如何将样本写入文件。此外,8 位将听起来像屁股。

回到 mBitsPerChannel = 16,然后考虑每帧写入两个通道的事实,这意味着 mBytesPerFrame 和 mBytesPerPacket 现在将是 4(它们在书中是 2)。想想这是为什么。

然后,您应该能够在第一个调用之后添加对 AudioFileWriteBytes() 的第二个调用 - 或者在计算 mChannelsPerFrame 的位置进行循环。但是您必须考虑文件中的不同偏移量,因为您每次通过写入 4 个字节而不是 2 个字节。我认为这是正确的:

  audioErr = AudioFileWriteBytes(audioFile, false, sampleCount*4, &bytesToWrite, &sample); // left
  audioErr = AudioFileWriteBytes(audioFile, false, (sampleCount*4)+2, &bytesToWrite, &sample); // right

你需要自己弄清楚其中的一些东西才能让它沉入其中。

于 2013-09-25T15:04:26.757 回答