Как играть NSData (байты) с аудио-очередью? - PullRequest
1 голос
/ 16 ноября 2011

как воспроизвести [NSData bytes] с помощью Audio Queue Services, например на SpeeHere, байты являются токенами из AudioFile, но у меня загружается звук из Интернета, мне нужно воспроизвести его с помощью Queue Services.Iv пытался параметры, как это:

      memset(&mDataFormat, 0, sizeof(mDataFormat));
audioData = [[NSData alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"1" ofType:@"mp3"]];
    UInt32 size = sizeof(mDataFormat.mSampleRate);
    XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size,&mDataFormat.mSampleRate), "couldn't get hardware sample rate");
    size = sizeof(mDataFormat.mChannelsPerFrame);
    XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels,&size,&mDataFormat.mChannelsPerFrame), "couldn't get input channel count");
    mDataFormat.mFormatID = kAudioFormatLinearPCM;
    if (mDataFormat.mFormatID == kAudioFormatLinearPCM)
    {
        mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
        mDataFormat.mBitsPerChannel = 8;
        mDataFormat.mBytesPerPacket = mDataFormat.mBytesPerFrame = (mDataFormat.mBitsPerChannel / 8) * mDataFormat.mChannelsPerFrame;
        mDataFormat.mFramesPerPacket = 1;
    }



AudioQueueNewOutput(&mDataFormat, AQPlayer::AQBufferCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue);
UInt32 maxPacketSize;
UInt32 _size = sizeof(maxPacketSize);
AudioFileGetProperty(mAudioFile, kAudioFilePropertyPacketSizeUpperBound, &_size, &maxPacketSize);
UInt32 bufferByteSize = (UInt32)[audioData length];
CalculateBytesForTime (mDataFormat, maxPacketSize, kBufferDurationSeconds, &bufferByteSize, &mNumPacketsToRead);
AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, 1.0);

обратный вызов работает, но, к сожалению, не может установить байты в буфере:

if (nPackets > 0) 
{
    inCompleteAQBuffer->mAudioDataByteSize = numBytes;      
    inCompleteAQBuffer->mPacketDescriptionCount = nPackets; 

  for (int i = 0; i < inCompleteAQBuffer->mAudioDataByteSize; i++)
   {
        char * cash = (void *)[THIS->audioData bytes];

       // inCompleteAQBuffer->mUserData[i] = cash[i];

   }

    //inCompleteAQBuffer->mUserData = data;

где inCompleteAQBuffer тип AudioQueueBufferRef, пожалуйстапомощь ...

1 Ответ

1 голос
/ 17 ноября 2011

Вам необходимо знать формат аудио, содержащегося в NSData. Заголовок? Несжатый / необработанный PCM? Сколько бит? Endian-Несс? Сколько каналов? Требуется частота дискретизации (или отфильтрованная частота интерполяции)?

Если данные сжаты, вам нужно будет распаковать их в необработанное аудио или настроить Audio Queue для воспроизведения соответствующего сжатого формата, если это так поддерживается.

Как только вы знаете формат для несжатого аудио, вы можете привести указатель на ваши байты NSData к соответствующему массиву или массиву структур типа C (unsigned char, short int, пара коротких int и т. Д.). Затем скопируйте запрошенное количество выборок из массива в буфер обратного вызова. Ваш обратный вызов также должен отслеживать, какая часть этого массива уже использовалась в предыдущем обратном вызове (например, индекс массива) между обратными вызовами.

...