2011-11-16 24 views
1

如何播放[NSData字節]與音頻隊列服務,從speakHere示例字節是來自AudioFile的令牌,但我有從互聯網上下載的聲音,我需要與隊列服務播放它。 Iv've試圖像這樣的參數:如何播放音頻隊列的NSData(字節)?

 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

您需要知道包含在NSData中的音頻格式。頁眉?未壓縮/原始PCM?多少位?字節序?多少個頻道?採樣率(或濾波插值率)要求?

如果數據被壓縮,您需要將其解壓縮爲原始音頻,或者配置音頻隊列以播放適當的壓縮格式(如果支持的話)。

一旦您知道格式,對於未壓縮的音頻,您可以將指向您的NSData字節的指針轉換爲適當的數組或結構C數組(無符號字符,短整型,一對短整型等)。然後將請求數量的樣本從數組中複製到回調緩衝區。你的回調也必須跟蹤這個數組的哪個部分已經用在回調之間的前一個回調(例如數組索引)中。

+0

感謝您的評論... 我已經知道關於數據的所有信息,因爲我用這種方式記錄它,問題是我無法將字節傳遞給回調,我有一個不知何故的錯誤贏得我試圖從NSData範圍複製字節到空閒緩衝區中: like: for(int i = 0; i Florik

+1

究竟是什麼樣的錯誤? – hotpaw2

+0

錯誤:語義問題:指向不完整類型'void'的下標 – Florik