-->

如何阅读VBR音频novacaine(相对于PCM)(how to read VBR audio i

2019-08-02 07:20发布

的创建者novacaine提供其中的音频数据被从AA文件中读取并供给到环形缓冲器的示例代码。 当虽然创建的文件阅读器,输出被强制为PCM:

- (id)initWithAudioFileURL:(NSURL *)urlToAudioFile samplingRate:(float)thisSamplingRate numChannels:(UInt32)thisNumChannels
{

...

    // We're going to impose a format upon the input file
    // Single-channel float does the trick.
    _outputFormat.mSampleRate = self.samplingRate;
    _outputFormat.mFormatID = kAudioFormatLinearPCM;
    _outputFormat.mFormatFlags = kAudioFormatFlagIsFloat;
    _outputFormat.mBytesPerPacket = 4*self.numChannels;
    _outputFormat.mFramesPerPacket = 1;
    _outputFormat.mBytesPerFrame = 4*self.numChannels;
    _outputFormat.mChannelsPerFrame = self.numChannels;
    _outputFormat.mBitsPerChannel = 32;

}

我试图通过允许其作出贡献novacaine项目

  • 从iPod库(只能通过AVAssetReader进行访问,而不是音频文件服务库)阅读
  • 读写VBR数据包,而不是PCM。

原来这就是我上面貌似同等功能(见注:部分)

- (id)initWithAudioAssetURL:(NSURL *)urlToAsset samplingRate:(float)thisSamplingRate numChannels:(UInt32)thisNumChannels
{
    self = [super init];
    if (self)
    {

        // Zero-out our timer, so we know we're not using our callback yet
        self.callbackTimer = nil;

        // Open a reference to the audio Asset Track and setup the reader
        self.assetURL = urlToAsset;
        AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:self.assetURL options:nil];
        NSError * error = nil;
        AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:songAsset error:&error];
        AVAssetTrack* track = [songAsset.tracks objectAtIndex:0];

        //NOTE: we use the track's native settings here, as opposed to forcing it to be PCM
        //like the example above
        _readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track
                                                                  outputSettings:NULL];

        _nativeTrackASBD = [self getTrackNativeSettings:track];

        [reader addOutput:_readerOutput];
        [reader startReading];


        // Set a few defaults and presets
        self.samplingRate = thisSamplingRate;
        self.numChannels = thisNumChannels;
        self.latency = .011609977; // 512 samples / ( 44100 samples / sec ) default

        // Arbitrary buffer sizes that don't matter so much as long as they're "big enough"
        self.outputBufferSize = 100000; //buffer sample sizes vary around 60-70k, we keep it @ 100k to be safe
        self.numSamplesReadPerPacket = 8192;
        self.desiredPrebufferedSamples = self.numSamplesReadPerPacket*2;

        //NOTE: these buffers are float, where as the above audio code is in SInt16
        self.outputBuffer = (float *)calloc(2*self.samplingRate, sizeof(float));
        self.holdingBuffer = (float *)calloc(2*self.samplingRate, sizeof(float));


        // Allocate a ring buffer (this is what's going to buffer our audio)
        ringBuffer = new RingBuffer(self.outputBufferSize, self.numChannels);


        // Fill up the buffers, so we're ready to play immediately
        [self bufferNewAudioFromAsset];

    }
    return self;
}

看代码,似乎一切都在浮动(音频缓冲,输出格式等)制成..有一个原因? (请记住,iOS的音频规范格式是SInt16, 浮动)。例如看到奴佛卡因:: renderCallback功能:

else if ( sm.numBytesPerSample == 2 ) // then we need to convert SInt16 -> Float (and also scale)
{
    float scale = (float)INT16_MAX;
    vDSP_vsmul(sm.outData, 1, &scale, sm.outData, 1, inNumberFrames*sm.numOutputChannels);

    for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {  

        int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;

        for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
            vDSP_vfix16(sm.outData+iChannel, sm.numOutputChannels, (SInt16 *)ioData->mBuffers[iBuffer].mData+iChannel, thisNumChannels, inNumberFrames);
        }
    }

}

是什么的东西,我得改变,使这个图书馆阅读和写作VBR数据兼容列表?

一个

文章来源: how to read VBR audio in novacaine (as opposed to PCM)