简体   繁体   中英

How to play NSData(bytes) with Audio Queue's?

how to play [NSData bytes] with Audio Queue Services, from speakHere example the bytes are token from the AudioFile, but i'm having sound downloaded from internet i need to play it with Queue Services. Iv've tried to the parameters like this:

      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);

the callback is working but unfortunately a cannot set the bytes in the buffer:

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;

where inCompleteAQBuffer is AudioQueueBufferRef type, please help ...

You need to know the format of the audio contained in the NSData. Header? Uncompressed/raw PCM? How many bits? Endian-ness? How many channels? Sample rate (or filtered interpolation rate) required?

If the data is compressed, you will need to uncompress it to raw audio, or configure the Audio Queue to play the appropriate compressed format, if it's so supported.

Once you know the format, for uncompressed audio, you can cast a pointer to your NSData bytes to the proper array or array of structures C type (unsigned char, short int, pair of short ints, etc.). Then copy the requested number of samples from the array to the callback buffer. Your callback will also have to keep track of what part of this array has already been used in a previous callback (eg the array index) between callbacks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM