示例#1
0
static void AQTestBufferCallback(void *					inUserData,
								AudioQueueRef			inAQ,
								AudioQueueBufferRef		inCompleteAQBuffer) 
{
	AQTestInfo * myInfo = (AQTestInfo *)inUserData;
	if (myInfo->mDone) return;
		
	UInt32 numBytes;
	UInt32 nPackets = myInfo->mNumPacketsToRead;

	OSStatus result = AudioFileReadPackets(myInfo->mAudioFile, false, &numBytes, myInfo->mPacketDescs, myInfo->mCurrentPacket, &nPackets, 
								inCompleteAQBuffer->mAudioData);
	if (result) {
		DebugMessageN1 ("Error reading from file: %d\n", (int)result);
		exit(1);
	}
	
	if (nPackets > 0) {
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;		

		AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, (myInfo->mPacketDescs ? nPackets : 0), myInfo->mPacketDescs);
		
		myInfo->mCurrentPacket += nPackets;
	} else {
		result = AudioQueueStop(myInfo->mQueue, false);
		if (result) {
			DebugMessageN1 ("AudioQueueStop(false) failed: %d", (int)result);
			exit(1);
		}
			// reading nPackets == 0 is our EOF condition
		myInfo->mDone = true;
	}
}
static void MyAQOutputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) 
{
	MyPlayer *aqp = (MyPlayer*)inUserData;
	if (aqp->isDone) return;
	
	// read audio data from file into supplied buffer
	UInt32 numBytes;
	UInt32 nPackets = aqp->numPacketsToRead;	
	CheckError(AudioFileReadPackets(aqp->playbackFile,
									false,
									&numBytes,
									aqp->packetDescs,
									aqp->packetPosition,
									&nPackets,
									inCompleteAQBuffer->mAudioData),
			   "AudioFileReadPackets failed");
	
	// enqueue buffer into the Audio Queue
	// if nPackets == 0 it means we are EOF (all data has been read from file)
	if (nPackets > 0)
	{
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;		
		AudioQueueEnqueueBuffer(inAQ,
								inCompleteAQBuffer,
								(aqp->packetDescs ? nPackets : 0),
								aqp->packetDescs);
		aqp->packetPosition += nPackets;
	}
	else
	{
		CheckError(AudioQueueStop(inAQ, false), "AudioQueueStop failed");
		aqp->isDone = true;
	}
}
示例#3
0
文件: player.c 项目: Yoonster/dhun
static void HandleOutputBuffer (void                *aqData,
                                AudioQueueRef       inAQ,
                                AudioQueueBufferRef inBuffer) {
  AQPlayerState *pAqData = (AQPlayerState *) aqData;

  if (pAqData->mIsRunning == 0) return;
  UInt32 numBytesReadFromFile;
  UInt32 numPackets = pAqData->mNumPacketsToRead;

  AudioFileReadPackets (pAqData->mAudioFile,
                        false,
                        &numBytesReadFromFile,
                        pAqData->mPacketDescs,
                        pAqData->mCurrentPacket,
                        &numPackets,
                        inBuffer->mAudioData);
  if (numPackets > 0) {
    inBuffer->mAudioDataByteSize = numBytesReadFromFile;
    AudioQueueEnqueueBuffer (pAqData->mQueue,
                             inBuffer,
                             (pAqData->mPacketDescs ? numPackets : 0),
                             pAqData->mPacketDescs);
    pAqData->mCurrentPacket += numPackets;
  } else {
    AudioQueueStop (pAqData->mQueue,
                    false);
    //printf("Play Stopped!\n");
    pAqData->mIsRunning = false;
  }
}
void AudioQueueStreamOut::AQBufferCallback(void *					inUserData,
                                            AudioQueueRef			inAQ,
                                            AudioQueueBufferRef		inCompleteAQBuffer)
{
	AudioQueueStreamOut * pThis = (AudioQueueStreamOut *)inUserData;
	if (pThis->mInfo.mDone) return;
    if(pThis->mInfo.m_SeekToPacket != -1)
    {
        pThis->mInfo.mCurrentPacket = pThis->mInfo.m_SeekToPacket;
        pThis->mInfo.m_SeekToPacket = -1; 
    }        
	UInt32 numBytes;
	UInt32 nPackets = pThis->mInfo.mNumPacketsToRead;

	if ((AudioFileReadPackets(pThis->mInfo.mAudioFile, false, &numBytes, pThis->mInfo.mPacketDescs, pThis->mInfo.mCurrentPacket, &nPackets, 
								inCompleteAQBuffer->mAudioData) == 0)
                                
		
	 && (nPackets > 0)) {
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;		
        AudioQueueParameterEvent event;
        event.mID = kAudioQueueParam_Volume;
        event.mValue = pThis->m_Volume; 
		AudioQueueEnqueueBufferWithParameters(inAQ, inCompleteAQBuffer, (pThis->mInfo.mPacketDescs ? nPackets : 0), pThis->mInfo.mPacketDescs,0,0,1, &event,NULL,NULL);
		
		pThis->mInfo.mCurrentPacket += nPackets;
	} 
    else 
    {
		AudioQueueStop(pThis->mInfo.mQueue, false);
			// reading nPackets == 0 is our EOF condition
		pThis->mInfo.mDone = true;
	}
}
示例#5
0
void	HLAudioFile::ReadAudioFrames(SInt64 inOffset, UInt32& ioNumberFrames, void* outData, bool inCache)
{
	ThrowIf(mAudioFileID == 0, CAException(fnOpnErr), "HLAudioFile::ReadAudioFrames: file isn't prepared");
	
	UInt32 theNumberBytesRead = 0;
	OSStatus theError = AudioFileReadPackets(mAudioFileID, inCache, &theNumberBytesRead, NULL, inOffset, &ioNumberFrames, outData);
	ThrowIfError(theError, CAException(theError), "HLAudioFile::ReadAudioFrames: couldn't read the data");
}
static void AQTestBufferCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) 
{
	AQTestInfo * myInfo = (AQTestInfo *)inUserData;
	if (myInfo->mDone) return;
		
	UInt32 numBytes;
	UInt32 nPackets = myInfo->mNumPacketsToRead;
	OSStatus result = AudioFileReadPackets(myInfo->mAudioFile,      // The audio file from which packets of audio data are to be read.
                                           false,                   // Set to true to cache the data. Otherwise, set to false.
                                           &numBytes,               // On output, a pointer to the number of bytes actually returned.
                                           myInfo->mPacketDescs,    // A pointer to an array of packet descriptions that have been allocated.
                                           myInfo->mCurrentPacket,  // The packet index of the first packet you want to be returned.
                                           &nPackets,               // On input, a pointer to the number of packets to read. On output, the number of packets actually read.
                                           inCompleteAQBuffer->mAudioData); // A pointer to user-allocated memory.
	if (result) {
		DebugMessageN1 ("Error reading from file: %d\n", (int)result);
		exit(1);
	}
    
    // we have some data
	if (nPackets > 0) {
		inCompleteAQBuffer->mAudioDataByteSize = numBytes;
        
		result = AudioQueueEnqueueBuffer(inAQ,                                  // The audio queue that owns the audio queue buffer.
                                         inCompleteAQBuffer,                    // The audio queue buffer to add to the buffer queue.
                                         (myInfo->mPacketDescs ? nPackets : 0), // The number of packets of audio data in the inBuffer parameter. See Docs.
                                         myInfo->mPacketDescs);                 // An array of packet descriptions. Or NULL. See Docs.
		if (result) {
			DebugMessageN1 ("Error enqueuing buffer: %d\n", (int)result);
			exit(1);
		}
        
		myInfo->mCurrentPacket += nPackets;
        
	} else {
        // **** This ensures that we flush the queue when done -- ensures you get all the data out ****
		
        if (!myInfo->mFlushed) {
			result = AudioQueueFlush(myInfo->mQueue);
			
            if (result) {
				DebugMessageN1("AudioQueueFlush failed: %d", (int)result);
				exit(1);
			}
            
			myInfo->mFlushed = true;
		}
		
		result = AudioQueueStop(myInfo->mQueue, false);
		if (result) {
			DebugMessageN1("AudioQueueStop(false) failed: %d", (int)result);
			exit(1);
		}
        
		// reading nPackets == 0 is our EOF condition
		myInfo->mDone = true;
	}
}
示例#7
0
void LoaderSourceFile::dataInputCallback( Loader* aLoader, uint32_t *ioNumberDataPackets, BufferList *ioData, AudioStreamPacketDescription * packetDescriptions )
{
	LoaderSourceFile * theLoader = dynamic_cast<LoaderSourceFile *>( aLoader );
	SourceFile * theSource = theLoader->mSource;
	
	OSStatus err = AudioFileReadPackets( theSource->mFileRef.get(), false, (UInt32 *)&(ioData->mBuffers[0].mDataByteSize), packetDescriptions, theLoader->mPacketOffset, (UInt32 *)ioNumberDataPackets, ioData->mBuffers[0].mData );
	if( err ) {
		//throw ??
	}
	theLoader->mPacketOffset += *ioNumberDataPackets;
}
示例#8
0
void AudioFile::load()
{
	OSStatus err = noErr;
	
	uint32_t bytesReturned = 0;
	uint32_t packets = mPacketCount;
	
	mData = malloc( mByteCount );
	memset( mData, 0, mByteCount );
	
	err = AudioFileReadPackets( mNativeFileRef, false, (UInt32 *)&bytesReturned, NULL, 0, (UInt32 *)&packets, mData );
	if( err ) {
		std::cout << "Error loading audio data" << std::endl;
	}
}
void AudioFile::read(Float32 *data, UInt64 *cursor, UInt32 *numFrames)
{
  AudioFramePacketTranslation t;
  UInt32 size = sizeof(AudioFramePacketTranslation);
  t.mFrame = *cursor;
  AudioFileGetProperty(mAudioFileID, kAudioFilePropertyFrameToPacket, &size, &t);
  *mCursor = t.mPacket;
  
  AudioFramePacketTranslation t2;
  t2.mFrame = *numFrames;
  AudioFileGetProperty(mAudioFileID, kAudioFilePropertyFrameToPacket, &size, &t2);
  UInt32 numPacketsToRead = t2.mPacket ? t2.mPacket : 1;
  
  AudioBytePacketTranslation t3;
  t3.mPacket = numPacketsToRead;
  size = sizeof(AudioBytePacketTranslation);
  AudioFileGetProperty(mAudioFileID, kAudioFilePropertyPacketToByte, &size, &t3);
  
  if (mConverterBuffer) free(mConverterBuffer);
  mConverterBuffer = (char*)malloc(t3.mByte);
  mNumPacketsToRead = numPacketsToRead;
  
  UInt32 outNumBytes;
  checkError(AudioFileReadPackets(mAudioFileID, false, &outNumBytes, mPacketDescs, *mCursor, &numPacketsToRead, mConverterBuffer), "AudioFileReadPackets");
  mConvertByteSize = outNumBytes;
  
  UInt32 numFramesToConvert = t.mFrameOffsetInPacket + *numFrames;
  bool interleaved = true;
  interleaved = !(mClientFormat.mFormatFlags & kAudioFormatFlagIsNonInterleaved);
  AudioBufferList* tmpbuf = AudioSourceNode::createAudioBufferList(2, interleaved, numFramesToConvert, sizeof(Float32));
  checkError(AudioConverterFillComplexBuffer(mAudioConverterRef, encoderProc, this, &numFramesToConvert, tmpbuf, NULL),
             "AudioConverterFillComplexBuffer");
  
  if (interleaved) {
    Float32* sample = (Float32*)tmpbuf->mBuffers[0].mData;
    memcpy(data, &sample[t.mFrameOffsetInPacket], numFramesToConvert * sizeof(Float32) * mClientFormat.mChannelsPerFrame);
  }
  
  AudioSourceNode::deleteAudioBufferList(tmpbuf);
  
  if (numFramesToConvert == 0) {
    AudioConverterReset(mAudioConverterRef);
  }
  
  *numFrames = numFramesToConvert;
}
示例#10
0
static void HandleOutputBuffer (
                                void                *aqData,
                                AudioQueueRef       inAQ,
                                AudioQueueBufferRef inBuffer
                                ) {
    
    //    std::cout << "cb" << std::endl;
    
    OSStatus status;
    
    AQPlayerState *pAqData = (AQPlayerState *) aqData;        // 1
    if (pAqData->mIsRunning == 0) return;                     // 2
    UInt32 numBytesReadFromFile;                              // 3
    UInt32 numPackets = pAqData->mNumPacketsToRead;           // 4
    status = AudioFileReadPackets (
                                   pAqData->mAudioFile,
                                   false,
                                   &numBytesReadFromFile,
                                   pAqData->mPacketDescs,
                                   pAqData->mCurrentPacket,
                                   &numPackets,
                                   inBuffer->mAudioData
                                   );
    //    checkStatus(status);
    if (numPackets > 0) {                                     // 5
        inBuffer->mAudioDataByteSize = numBytesReadFromFile;  // 6
        status = AudioQueueEnqueueBuffer (
                                          pAqData->mQueue,
                                          inBuffer,
                                          (pAqData->mPacketDescs ? numPackets : 0),
                                          pAqData->mPacketDescs
                                          );
        //        checkStatus(status);
        pAqData->mCurrentPacket += numPackets;                // 7
    } else {
        status = AudioQueueStop (
                                 pAqData->mQueue,
                                 false
                                 );
        //        checkStatus(status);
        pAqData->mIsRunning = false;
    }
}
示例#11
0
void AudioFile::getData( void ** aBuffer, uint32_t * size, AudioStreamPacketDescription * outPacketDescriptions, uint32_t startPacket, uint32_t packetCount, bool looping )
{
	
	if( startPacket < mPacketCount ) {
		if( ( startPacket + packetCount ) > mPacketCount ) {
			packetCount = mPacketCount - startPacket;
		}
	} else {
		packetCount = 0;
	}
	
	UInt32 bytesToCopy = packetCount * mMaxPacketSize;
	
	if( packetCount ) {
		*aBuffer = (void *) calloc( 1, bytesToCopy );
		AudioFileReadPackets( mNativeFileRef, false, &bytesToCopy, outPacketDescriptions, (SInt64)startPacket, (UInt32 *)&packetCount, *aBuffer );
		*size = bytesToCopy;
	} else {
		*size = 0;
		aBuffer = NULL;
	}
}
示例#12
0
    UInt32 music_obj<audio_queue_driver>::read_packets(AudioQueueBufferRef buffer)
    {
        UInt32 num_bytes, num_packets;
        num_packets = num_packets_to_read_;
        
        AudioFileReadPackets(audio_file_, false, &num_bytes, packet_descriptions_, packet_index_, &num_packets, buffer->mAudioData);
        if (num_packets > 0)
        {
            buffer->mAudioDataByteSize = num_bytes;
            AudioQueueEnqueueBuffer(queue_, buffer, (packet_descriptions_ ? num_packets : 0), packet_descriptions_);
            packet_index_ += num_packets;
            
            if(stop_packet_index_ != 0 && packet_index_ >= stop_packet_index_) {
                if(loop_)
                    packet_index_ = start_packet_index_;
                else
                    return 0;
            }
        }

        return num_packets;
    }
void	AudioFileReaderThread::DoConnect ()
{
	if (!mIsEngaged)
	{
		mFinishedReadingData = false;

		mNumTimesAskedSinceFinished = -1;
		mLockUnsuccessful = false;
		
		UInt32 dataChunkSize = 0;

		mCurrentPacketCountInBuffer = mChunkSizeInPackets;
#if LOG_DATA_FLOW
		fprintf(stdout, "***** DoConnect - AFReadPackets from  (pkts/offset) %ld/%qd\n", mCurrentPacketCountInBuffer, mReadPacketPosition);
#endif
		OSStatus result = AudioFileReadPackets ( mAudioFileID, 
												false, 
												&dataChunkSize,
                                                mPacketDescriptions,
                                                mReadPacketPosition, 
												&mCurrentPacketCountInBuffer, 
												mFileBuffer);
			THROW_RESULT("AudioFileReadPackets")
        
        mCurrentByteCountInBuffer = dataChunkSize;
		mReadPacketPosition = mCurrentPacketCountInBuffer;

		mWriteToFirstBuffer = false;
		mReadFromFirstBuffer = true;

		sReaderThread.AddReader();
		
		mIsEngaged = true;
	}
	else
		throw static_cast<OSStatus>(-1); //thread has already been started
}
示例#14
0
文件: play.c 项目: jonahb/play
void AudioQueueOutput( void *userData, AudioQueueRef queue, AudioQueueBufferRef buffer )
{
    OSStatus result;

    State *state = (State *)userData;

    buffer->mAudioDataByteSize = state->audioBufferSize;
    buffer->mPacketDescriptionCount = PACKETS_PER_BUFFER;

    result = AudioFileReadPackets(
        state->audioFile,
        false,  
        &buffer->mAudioDataByteSize,
        buffer->mPacketDescriptions,
        state->nextPacketIndex,
        &buffer->mPacketDescriptionCount,
        buffer->mAudioData
    );

    if (result) {
        fprintf(stderr, "Error reading packets from file: %d\n", result);
    }

    state->nextPacketIndex += buffer->mPacketDescriptionCount;

    AudioQueueEnqueueBuffer(
        queue,
        buffer,
        0,
        NULL
    );

    if (buffer->mPacketDescriptionCount < PACKETS_PER_BUFFER) {
        AudioQueueStop(queue, false);
    }
}
// Input data proc callback
static OSStatus EncoderDataProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)
{
	AudioFileIOPtr afio = (AudioFileIOPtr)inUserData;
    OSStatus error;
	
    // figure out how much to read
	UInt32 maxPackets = afio->srcBufferSize / afio->srcSizePerPacket;
	if (*ioNumberDataPackets > maxPackets) *ioNumberDataPackets = maxPackets;

    // read from the file
	UInt32 outNumBytes;
	error = AudioFileReadPackets(afio->srcFileID, false, &outNumBytes, afio->packetDescriptions, afio->srcFilePos, ioNumberDataPackets, afio->srcBuffer);
	if (eofErr == error) error = noErr;
	if (error) { printf ("Input Proc Read error: %ld (%4.4s)\n", error, (char*)&error); return error; }
	
    //printf("Input Proc: Read %lu packets, at position %lld size %lu\n", *ioNumberDataPackets, afio->srcFilePos, outNumBytes);
	
    // advance input file packet position
	afio->srcFilePos += *ioNumberDataPackets;

    // put the data pointer into the buffer list
	ioData->mBuffers[0].mData = afio->srcBuffer;
	ioData->mBuffers[0].mDataByteSize = outNumBytes;
	ioData->mBuffers[0].mNumberChannels = afio->srcFormat.mChannelsPerFrame;

    // don't forget the packet descriptions if required
	if (outDataPacketDescription) {
		if (afio->packetDescriptions) {
			*outDataPacketDescription = afio->packetDescriptions;
		} else {
			*outDataPacketDescription = NULL;
        }
	}
    
    return error;
}
示例#16
0
// _______________________________________________________________________________________
//
OSStatus CAAudioFile::ReadInputProc(	AudioConverterRef				inAudioConverter,
										UInt32*							ioNumberDataPackets,
										AudioBufferList*				ioData,
										AudioStreamPacketDescription**	outDataPacketDescription,
										void*							inUserData)
{
	CAAudioFile *This = static_cast<CAAudioFile *>(inUserData);

#if 0
	SInt64 remainingPacketsInFile = This->mNumberPackets - This->mPacketMark;
	if (remainingPacketsInFile <= 0) {
		*ioNumberDataPackets = 0;
		ioData->mBuffers[0].mDataByteSize = 0;
		if (outDataPacketDescription)
			*outDataPacketDescription = This->mPacketDescs;
#if VERBOSE_IO
		printf("CAAudioFile::ReadInputProc: EOF\n");
#endif
		return noErr;	// not eofErr; EOF is signified by 0 packets/0 bytes
	}
#endif

	// determine how much to read
	AudioBufferList *readBuffer;
	UInt32 readPackets;
	if (inAudioConverter != NULL) {
		// getting called from converter, need to use our I/O buffer
		readBuffer = &This->mIOBufferList;
		readPackets = This->mIOBufferSizePackets;
	} else {
		// getting called directly from ReadPackets, use supplied buffer
		if (This->mFileMaxPacketSize == 0)
			return kExtAudioFileError_MaxPacketSizeUnknown;
		readBuffer = ioData;
		readPackets = std::min(*ioNumberDataPackets, readBuffer->mBuffers[0].mDataByteSize / This->mFileMaxPacketSize);
			// don't attempt to read more packets than will fit in the buffer
	}
	// don't try to read past EOF
//	if (readPackets > remainingPacketsInFile)
//		readPackets = remainingPacketsInFile;
	// don't read more packets than necessary to produce the requested amount of converted data
	if (readPackets > This->mMaxPacketsToRead) {
#if VERBOSE_IO
		printf("CAAudioFile::ReadInputProc: limiting read to %ld packets (from %ld)\n", This->mMaxPacketsToRead, readPackets);
#endif
		readPackets = This->mMaxPacketsToRead;
	}

	// read
	UInt32 bytesRead;
	OSStatus err;

	StartTiming(This, read);
	StartTiming(This, readinconv);
	err = AudioFileReadPackets(This->mAudioFile, This->mUseCache, &bytesRead, This->mPacketDescs, This->mPacketMark, &readPackets, readBuffer->mBuffers[0].mData);
#if CAAUDIOFILE_PROFILE
	if (This->mInConverter) ElapsedTime(This, readinconv, This->mTicksInReadInConverter);
#endif
	ElapsedTime(This, read, This->mTicksInIO);

	if (err) {
		DebugMessageN1("Error %ld from AudioFileReadPackets!!!\n", err);
		return err;
	}

#if VERBOSE_IO
	printf("CAAudioFile::ReadInputProc: read %ld packets (%qd-%qd), %ld bytes, err %ld\n", readPackets, This->mPacketMark, This->mPacketMark + readPackets, bytesRead, err);
#if VERBOSE_IO >= 2
	if (This->mPacketDescs) {
		for (UInt32 i = 0; i < readPackets; ++i) {
			printf("  read packet %qd : offset %qd, length %ld\n", This->mPacketMark + i, This->mPacketDescs[i].mStartOffset, This->mPacketDescs[i].mDataByteSize);
		}
	}
	printf("  read buffer:"); CAShowAudioBufferList(readBuffer, 0, 4);
#endif
#endif
	if (readPackets == 0) {
		*ioNumberDataPackets = 0;
		ioData->mBuffers[0].mDataByteSize = 0;
		return noErr;
	}

	if (outDataPacketDescription)
		*outDataPacketDescription = This->mPacketDescs;
	ioData->mBuffers[0].mDataByteSize = bytesRead;
	ioData->mBuffers[0].mData = readBuffer->mBuffers[0].mData;

	This->mPacketMark += readPackets;
	if (This->mClientDataFormat.mFramesPerPacket != 1) {	// for PCM client formats we update in Read
		// but for non-PCM client format (weird case) we must update here/now
		if (This->mFileDataFormat.mFramesPerPacket > 0)
			This->mFrameMark += readPackets * This->mFileDataFormat.mFramesPerPacket;
		else {
			for (UInt32 i = 0; i < readPackets; ++i)
				This->mFrameMark += This->mPacketDescs[i].mVariableFramesInPacket;
		}
	}
	*ioNumberDataPackets = readPackets;
	return noErr;
}
示例#17
0
    void music_obj<audio_queue_driver>::calculate_seek(float start, float end)
    {
        bool want_start = start != 0.0f;
        bool want_end   = end != 0.0f;
   
        total_time_ = 0.0f;
        
        // variable bitrate requires calculations per packet
        if (data_format_.mBytesPerPacket == 0 || data_format_.mFramesPerPacket == 0) 
        {		
            UInt32 num_packets = num_packets_to_read_;
            UInt32 num_bytes;
            
            void* dummy_data = malloc(max_packet_size_*num_packets);
            
            // read all file
            while(true) 
            {
                AudioFileReadPackets(audio_file_, false, &num_bytes, packet_descriptions_, packet_index_, &num_packets, dummy_data);
                
                if (num_packets > 0) 
                {
                    for(int i=0; i<num_packets; ++i) {
                        
                        if(packet_descriptions_[i].mVariableFramesInPacket == 0) 
                        {
                            total_time_ += data_format_.mFramesPerPacket / data_format_.mSampleRate;
                        } 
                        else 
                        {
                            total_time_ += packet_descriptions_[i].mVariableFramesInPacket / data_format_.mSampleRate;
                        }
                        
                        if(want_start && total_time_ >= start)
                        {
                            start_packet_index_ = packet_index_;
                            want_start = false;
                        }
                        
                        if(want_end && total_time_ >= end)
                        {
                            stop_packet_index_ = packet_index_;
                            want_end = false;
                        }
                        
                        packet_index_ += 1;
                    }
                } 
                else 
                { 
                    break; // done
                }
            }
            
            free(dummy_data);            
        } 
        else 
        {
            UInt32 size = sizeof(UInt64);
            UInt64 total_packets;
            
            OSStatus err = AudioFileGetProperty(audio_file_, kAudioFilePropertyAudioDataPacketCount, &size, &total_packets);
            if(err != noErr)
            {
                throw sys_exception("audio_queue: Can't get total packet count from CBR audio file. " 
                        + boost::lexical_cast<std::string>(err));
            }

            float packet_time =  data_format_.mFramesPerPacket / data_format_.mSampleRate;
 
            if(want_start)
            {
                start_packet_index_ = start/packet_time;
            }
            
            if(want_end)
            {
                stop_packet_index_ = end/packet_time;
            }
            
            total_time_ = total_packets*packet_time;
        }
        
        LOG("Total length of track: %f", total_time_);
    }
void 	FileReaderThread::ReadNextChunk ()
{
	OSStatus 						result;
	UInt32							dataChunkSize;
	UInt32							dataChunkSizeInPackets;
    AudioStreamPacketDescription	*packetDescriptions = NULL;
	FileThreadVariables* 			theItem = 0;

	for (;;) 
	{
		{ // this is a scoped based lock
			CAGuard::Locker fileReadLock (mGuard);
			
			if (mThreadShouldDie) return;
			
			while (mFileData.empty()) {
				fileReadLock.Wait();
			}
			
			// kill thread
			if (mThreadShouldDie) return;

			theItem = mFileData[0];
			mFileData.erase (mFileData.begin());
		}
	

		packetDescriptions = theItem->mPacketDescriptions;
        if (!theItem->mWriteToFirstBuffer)
            packetDescriptions += theItem->mChunkSizeInPackets;
        
        if ((theItem->mPacketCount - theItem->mReadPacketPosition) < theItem->mChunkSizeInPackets)
		{
        	dataChunkSizeInPackets = theItem->mPacketCount - theItem->mReadPacketPosition;
            if (!theItem->IsLooping()) {
                theItem->mFinishedReadingData = true;
            }
		}
        else
			dataChunkSizeInPackets = theItem->mChunkSizeInPackets;

        // this is the exit condition for the thread
		if (dataChunkSizeInPackets == 0 && !theItem->IsLooping()) {
			theItem->mFinishedReadingData = true;
			continue;
		}

        // construct pointer
        char* writePtr = const_cast<char*>(theItem->GetFileBuffer() + 
                            (theItem->mWriteToFirstBuffer ? 0 : theItem->mChunkSizeInPackets * theItem->mMaxPacketSize));
	
#if LOG_DATA_FLOW
		fprintf(stdout, "***** ReadNextChunk(1) - AFReadPackets (pkts/offset) = %ld/%qd\n", dataChunkSizeInPackets, theItem->mReadPacketPosition);
#endif
        result = AudioFileReadPackets (theItem->GetFileID(), 
                                        false,
                                        &dataChunkSize,
                                        packetDescriptions,
                                        theItem->mReadPacketPosition, 
                                        &dataChunkSizeInPackets, 
                                        writePtr);
		if (result) {
			theItem->GetParent().DoNotification(result);
			continue;
		}

		theItem->mCurrentPacketCountInBuffer = dataChunkSizeInPackets;
		theItem->mCurrentByteCountInBuffer = dataChunkSize;

		if (dataChunkSizeInPackets != theItem->mChunkSizeInPackets)
		{
			writePtr += dataChunkSize;
            packetDescriptions += dataChunkSizeInPackets;

			if (theItem->IsLooping())
			{

                packetDescriptions = theItem->mPacketDescriptions + dataChunkSizeInPackets;
				dataChunkSizeInPackets = theItem->mChunkSizeInPackets - dataChunkSizeInPackets;
				theItem->mReadPacketPosition = 0;
            
#if LOG_DATA_FLOW
                fprintf(stdout, "***** ReadNextChunk(2) - AFReadPackets (pkts/offset) = %ld/%qd\n", dataChunkSizeInPackets, theItem->mReadPacketPosition);
#endif
                result = AudioFileReadPackets (theItem->GetFileID(), 
                                                false,
                                                &dataChunkSize,
                                                packetDescriptions,
                                                theItem->mReadPacketPosition, 
                                                &dataChunkSizeInPackets, 
                                                writePtr);
                if (result) {
                    theItem->GetParent().DoNotification(result);
                    continue;
                }
                theItem->mCurrentPacketCountInBuffer += dataChunkSizeInPackets;
                theItem->mCurrentByteCountInBuffer += dataChunkSize;
			} 
            else 
            {
                // can't exit yet.. we still have to pass the partial buffer back
                memset (writePtr, 0, ((theItem->mChunkSizeInPackets - dataChunkSizeInPackets) * theItem->mMaxPacketSize));
			}
		}
		
        theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer;	// switch buffers
		
		theItem->mReadPacketPosition += dataChunkSizeInPackets;		// increment count
	}
}
示例#19
0
  sfx_obj<audio_queue_driver>::sfx_obj(const boost::shared_ptr<ifdstream>& ifd, bool loop, float pitch, float volume)    
  : ifd_(ifd)
  , volume_(volume)
  {
      OSStatus res = AudioFileOpenWithCallbacks(this, &sfx_obj::af_read_cb, &sfx_obj::af_write_cb,
                                                &sfx_obj::af_get_size_cb, &sfx_obj::af_set_size_cb, 
                                                kAudioFileCAFType, &audio_file_);
      
      if(res)
      {
          throw sys_exception("audio_queue_driver: couldn't open SFX file in liverpool fs. AudioFileOpen returned " 
              + boost::lexical_cast<std::string>(res));
      }
      
      UInt32 size = sizeof(data_format_);
      AudioFileGetProperty(audio_file_, kAudioFilePropertyDataFormat, &size, &data_format_);
      
      if (res != 0) 
      {
          throw sys_exception("audio_queue_driver: couldn't load SFX file from liverpool fs. AudioFileReadBytes returned " 
              + boost::lexical_cast<std::string>(res));
      }
      
      alGenBuffers(NUM_BUFFERS, buffers_);
      alGenSources(1, &source_); 
      
      alSource3f(source_, AL_POSITION, 0.0, 0.0, 0.0);
      alSource3f(source_, AL_VELOCITY, 0.0, 0.0, 0.0);
      alSource3f(source_, AL_DIRECTION, 0.0, 0.0, 0.0);
      
      alSourcef(source_, AL_PITCH, pitch);
      alSourcef(source_, AL_GAIN, volume_);
      
      alSourcei(source_, AL_LOOPING, loop?AL_TRUE:AL_FALSE);	
      alSourcef(source_, AL_ROLLOFF_FACTOR, 0.0);
      alSourcei(source_, AL_SOURCE_RELATIVE, AL_TRUE);        
      
      if (data_format_.mBytesPerPacket == 0 || data_format_.mFramesPerPacket == 0)
      {
          LOG("Variable bitrate SFX");
          size = sizeof(max_packet_size_);
          AudioFileGetProperty(audio_file_, kAudioFilePropertyPacketSizeUpperBound, &size, &max_packet_size_);
          if (max_packet_size_ > BUFFER_SIZE_BYTES)
          {
              max_packet_size_ = BUFFER_SIZE_BYTES;
          }
          
          num_packets_to_read_ = BUFFER_SIZE_BYTES / max_packet_size_;
      }
      else
      {
          LOG("Constant bitrate SFX");
          num_packets_to_read_ = BUFFER_SIZE_BYTES / data_format_.mBytesPerPacket;
      }
      
      UInt32 offset = 0;
      
      std::vector<unsigned char> dat;
      
      for( int i=0; i<NUM_BUFFERS; ++i)
      {
          UInt32 packets = num_packets_to_read_;
          dat.resize(BUFFER_SIZE_BYTES);        
          res = AudioFileReadPackets (audio_file_, false, &size, NULL, offset, &packets, &dat.at(0));            
 
          if(res != noErr)
          {
              throw sys_exception("AudioFileReadPackets returned error: " + boost::lexical_cast<std::string>(res));
          }
          
          if (size == 0) 
          {
              LOG("All buffered into %d buffers total.", i+1);
              break; // done
          }
          
          dat.resize(size);
          LOG("Read %d bytes", size);
      
          LOG("Buffering data.. size is %d", dat.size());
          alBufferData(buffers_[i], AL_FORMAT_STEREO16, &dat.at(0), dat.size(), 44100);              
          alSourcei(source_, AL_BUFFER, buffers_[i]);
          
          offset += packets;
      }
      
      AudioFileClose(audio_file_);
  }
OSStatus MyAudioConverterCallback(AudioConverterRef inAudioConverter,
								  UInt32 *ioDataPacketCount,
								  AudioBufferList *ioData,
								  AudioStreamPacketDescription **outDataPacketDescription,
								  void *inUserData)
{
	MyAudioConverterSettings *audioConverterSettings = (MyAudioConverterSettings *)inUserData;
	
	// initialize in case of failure
    ioData->mBuffers[0].mData = NULL;			
    ioData->mBuffers[0].mDataByteSize = 0;
	
    // if there are not enough packets to satisfy request, then read what's left
    if (audioConverterSettings->inputFilePacketIndex + *ioDataPacketCount > audioConverterSettings->inputFilePacketCount)
        *ioDataPacketCount = audioConverterSettings->inputFilePacketCount - audioConverterSettings->inputFilePacketIndex;
	
	if(*ioDataPacketCount == 0)
        return noErr;
    
    if (audioConverterSettings->sourceBuffer != NULL)
    {
        free(audioConverterSettings->sourceBuffer);
        audioConverterSettings->sourceBuffer = NULL;
    }
    
    audioConverterSettings->sourceBuffer = (void *)calloc(1, *ioDataPacketCount * audioConverterSettings->inputFilePacketMaxSize);        
	
    UInt32 outByteCount = 0;
	OSStatus result = AudioFileReadPackets(audioConverterSettings->inputFile, 
										   true, 
										   &outByteCount, 
										   audioConverterSettings->inputFilePacketDescriptions, 
										   audioConverterSettings->inputFilePacketIndex,
										   ioDataPacketCount, 
										   audioConverterSettings->sourceBuffer);
    
	// it's not an error if we just read the remainder of the file
#ifdef MAC_OS_X_VERSION_10_7
    if (result == kAudioFileEndOfFileError && *ioDataPacketCount) result = noErr;
#else
    if (result == eofErr && *ioDataPacketCount) result = noErr;
#endif
    else if (result != noErr) return result;
	
    audioConverterSettings->inputFilePacketIndex += *ioDataPacketCount;
    
	// KEVIN: in "// initialize in case of failure", we assumed there was only 1
	// buffer (since we set it up ourselves in Convert()). so why be careful to
	// iterate over potentially multiple buffers here?
	/*
	 UInt32 bufferIndex;
	 for (bufferIndex = 0; bufferIndex < ioData->mNumberBuffers; bufferIndex++)
	 {
	 ioData->mBuffers[bufferIndex].mData = audioConverterSettings->sourceBuffer;
	 ioData->mBuffers[bufferIndex].mDataByteSize = outByteCount;
	 }
	 */
	// chris' hacky asssume-one-buffer equivalent
	ioData->mBuffers[0].mData = audioConverterSettings->sourceBuffer;
	ioData->mBuffers[0].mDataByteSize = outByteCount;
	
    if (outDataPacketDescription)
        *outDataPacketDescription = audioConverterSettings->inputFilePacketDescriptions;
	
    return result;	
}
示例#21
0
		static void QueueCallback(	void *					inUserData,
									AudioQueueRef			inAQ,
									AudioQueueBufferRef		inCompleteAQBuffer) 
		{
			// dispose of the buffer if no longer in use
			OSStatus result = noErr;
			BackgroundTrackMgr *THIS = (BackgroundTrackMgr*)inUserData;
			if (DisposeBuffer(inAQ, THIS->mBuffersToDispose, inCompleteAQBuffer))
				return;
			
			UInt32 nPackets = 0;
			// loop the current buffer if the following:
			// 1. file was loaded into the buffer previously
			// 2. only one file in the queue
			// 3. we have not been told to stop at playlist completion
			if ((CurFileInfo->mFileDataInQueue) && (THIS->mBGFileInfo.size() == 1) && (!THIS->mStopAtEnd))
				nPackets = THIS->GetNumPacketsToRead(CurFileInfo);

			else
			{
				UInt32 numBytes;
				while (nPackets == 0)
				{
					// if loadAtOnce, get all packets in the file, otherwise ~.5 seconds of data
					nPackets = THIS->GetNumPacketsToRead(CurFileInfo);					
					result = AudioFileReadPackets(CurFileInfo->mAFID, false, &numBytes, THIS->mPacketDescs, THIS->mCurrentPacket, &nPackets, 
											inCompleteAQBuffer->mAudioData);
						AssertNoError("Error reading file data", end);
					
					inCompleteAQBuffer->mAudioDataByteSize = numBytes;	
											
					if (nPackets == 0) // no packets were read, this file has ended.
					{
						if (CurFileInfo->mLoadAtOnce)
							CurFileInfo->mFileDataInQueue = true;
						
						THIS->mCurrentPacket = 0;
						UInt32 theNextFileIndex = (THIS->mCurrentFileIndex < THIS->mBGFileInfo.size()-1) ? THIS->mCurrentFileIndex+1 : 0;
						
						// we have gone through the playlist. if mStopAtEnd, stop the queue here
						if (theNextFileIndex == 0 && THIS->mStopAtEnd)
						{
							result = AudioQueueStop(inAQ, false);
								AssertNoError("Error stopping queue", end);
							return;
						}
						
						SInt8 theQueueState = GetQueueStateForNextBuffer(CurFileInfo, THIS->mBGFileInfo[theNextFileIndex]);
						if (theNextFileIndex != THIS->mCurrentFileIndex)
						{
							// if were are not looping the same file. Close the old one and open the new
							result = AudioFileClose(CurFileInfo->mAFID);
								AssertNoError("Error closing file", end);
							THIS->mCurrentFileIndex = theNextFileIndex;

							result = LoadFileDataInfo(CurFileInfo->mFilePath, CurFileInfo->mAFID, CurFileInfo->mFileFormat, CurFileInfo->mFileDataSize);
								AssertNoError("Error opening file", end);
						}
						
						switch (theQueueState) 
						{							
							// if we need to resize the buffer, set the buffer's audio data size to the new file's size
							// we will also need to get the new file cookie
							case kQueueState_ResizeBuffer:
								inCompleteAQBuffer->mAudioDataByteSize = CurFileInfo->mFileDataSize;							
							// if the data format is the same but we just need a new cookie, attach a new cookie
							case kQueueState_NeedNewCookie:
								result = AttachNewCookie(inAQ, CurFileInfo);
									AssertNoError("Error attaching new file cookie data to queue", end);
								break;
							
							// we can keep the same queue, but not the same buffer(s)
							case kQueueState_NeedNewBuffers:
								THIS->mBuffersToDispose.push_back(inCompleteAQBuffer);
								THIS->SetupBuffers(CurFileInfo);
								break;
							
							// if the data formats are not the same, we need to dispose the current queue and create a new one
							case kQueueState_NeedNewQueue:
								THIS->mMakeNewQueueWhenStopped = true;
								result = AudioQueueStop(inAQ, false);
									AssertNoError("Error stopping queue", end);
								return;
								
							default:
								break;
						}
					}
				}
			}
			
			result = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, (THIS->mPacketDescs ? nPackets : 0), THIS->mPacketDescs);
				AssertNoError("Error enqueuing new buffer", end);
			if (CurFileInfo->mLoadAtOnce)
				CurFileInfo->mFileDataInQueue = true;
				
			THIS->mCurrentPacket += nPackets;
		
		end:
			return;
		}
OSStatus DiskInUGenInternal::clearOutputsAndReadData(bool& shouldDelete) throw()
{
	const int outputBlockSize = uGenOutput.getBlockSize();
	const double sampeRateRatio = 1.0;//fileSampleRate * UGen::getReciprocalSampleRate();
	
	const int inputBlockSize = outputBlockSize * sampeRateRatio;
	
	if(inputBlockSize > allocatedBlockSize)
	{
		allocatedBlockSize = inputBlockSize;
		audioData = realloc(audioData, bytesPerFrame * allocatedBlockSize);
		if(!audioData)
		{
			printf("DiskIn: error: could not allocated memory for the new buffer size\n\n");
			AudioFileClose(audioFile_);
			audioFile_ = 0;
		}
	}
	
	for(int channel = 0; channel < numChannels_; channel++)
	{
		float *outputSamples = proxies[channel]->getSampleData();
		memset(outputSamples, 0, outputBlockSize * sizeof(float));
	}	
	
	if(!audioFile_)
	{
		numPackets = 0;
		return -1;
	}
	else
	{
		numPackets = inputBlockSize;
		UInt32 numBytesRead = -1;
		OSStatus result = AudioFileReadPackets(audioFile_, false,
											   &numBytesRead, NULL, 
											   currentPacket, &numPackets, audioData); 
		
		if(result == noErr)
		{  
			currentPacket += numPackets;
			
			if(numPackets < inputBlockSize)
			{
				if(loopFlag_)
				{
					// we hit the end of the file and looping is on, we need to pull 
					// a few samples from the start of the file
					
					const int remainingPackets = inputBlockSize - numPackets;
					
					unsigned char *remainingAudioData = (unsigned char*)audioData;
					remainingAudioData += remainingPackets * bytesPerFrame;
					
					numPackets = remainingPackets;
					result = AudioFileReadPackets(audioFile_, false, 
												  &numBytesRead, NULL, 
												  0, &numPackets, audioData);
					
					if(result == noErr)
					{ 
						currentPacket = remainingPackets;
					}
				}
				else
				{
					if(shouldDeleteValue)
						setIsDone();
					
					shouldDelete = shouldDelete ? true : shouldDeleteValue;
				}
			}
		}
		
		return result;
	}
	
}