コード例 #1
0
void	FileReaderThread::RemoveReader (const FileThreadVariables* inItem)
{
	if (mNumReaders > 0)
	{
		CAGuard::Locker fileReadLock (mGuard);

		for (FileData::iterator iter = mFileData.begin(); iter != mFileData.end(); ++iter)
		{
			if ((*iter) == inItem) {	
				mFileData.erase (iter);
			}
		}
		
		if (--mNumReaders == 0) {
			mThreadShouldDie = true;
			mGuard.Notify();
		}
	}	
}
コード例 #2
0
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
	}
}