的创建者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数据兼容列表?
一个