簡體   English   中英

如何將WAV / CAF文件的樣本數據轉換為字節數組?

[英]How to convert WAV/CAF file's sample data to byte array?

我需要能夠以編程方式讀取WAV(或CAF)文件,並將樣本(音頻)數據提取為字節數組。 最簡單/最快捷的方法是什么?

假設您使用的是iOS或OS X,您需要AudioToolbox框架,特別是AudioFile.h的API(如果您需要在讀取時將音頻數據轉換為另一種格式,則需要ExtAudioFile.h )。

例如,

#include <AudioToolbox/AudioFile.h>

...

AudioFileID audioFile;
OSStatus err = AudioFileOpenURL(fileURL, kAudioFileReadPermission, 0, &audioFile);
// get the number of audio data bytes
UInt64 numBytes = 0;
UInt32 dataSize = sizeof(numBytes);
err = AudioFileGetProperty(audioFile, kAudioFilePropertyAudioDataByteCount, &dataSize, &numBytes);

unsigned char *audioBuffer = (unsigned char *)malloc(numBytes);

UInt32 toRead = numBytes;
UInt64 offset = 0;
unsigned char *pBuffer = audioBuffer;
while(true) {
    err = AudioFileReadBytes(audioFile, true, offset, &toRead, &pBuffer);
    if (kAudioFileEndOfFileError == err) {
        // cool, we're at the end of the file
        break;
    } else if (noErr != err) {
        // uh-oh, some error other than eof
        break;
    }
    // advance the next read offset
    offset += toRead;
    // advance the read buffer's pointer
    pBuffer += toRead;
    toRead = numBytes - offset;
    if (0 == toRead) {
        // got to the end of file but no eof err
        break;
    }
}

// Process audioBuffer ...

free(audioBuffer);

以下是我從iPhone中獲取NSData的音樂文件並為ARC更新的內容

- (NSData *)readSoundFileSamples:(NSString *)filePath
{

    // Get raw PCM data from the track
    NSURL *assetURL = [NSURL fileURLWithPath:filePath];
    NSMutableData *data = [[NSMutableData alloc] init];

    const uint32_t sampleRate = 16000; // 16k sample/sec
    const uint16_t bitDepth = 16; // 16 bit/sample/channel
    const uint16_t channels = 2; // 2 channel/sample (stereo)

    NSDictionary *opts = [NSDictionary dictionary];
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:assetURL options:opts];
    AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:NULL];
    NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
                              [NSNumber numberWithFloat:(float)sampleRate], AVSampleRateKey,
                              [NSNumber numberWithInt:bitDepth], AVLinearPCMBitDepthKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, nil];

    AVAssetReaderTrackOutput *output = [[AVAssetReaderTrackOutput alloc] initWithTrack:[[asset tracks] objectAtIndex:0] outputSettings:settings];
    [reader addOutput:output];
    [reader startReading];

    // read the samples from the asset and append them subsequently
    while ([reader status] != AVAssetReaderStatusCompleted) {
        CMSampleBufferRef buffer = [output copyNextSampleBuffer];
        if (buffer == NULL) continue;

        CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(buffer);
        size_t size = CMBlockBufferGetDataLength(blockBuffer);
        uint8_t *outBytes = malloc(size);
        CMBlockBufferCopyDataBytes(blockBuffer, 0, size, outBytes);
        CMSampleBufferInvalidate(buffer);
        CFRelease(buffer);
        [data appendBytes:outBytes length:size];
        free(outBytes);
    }

    return data;

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM