Пример #1
0
SourceFileWav::SourceFileWav( DataSourceRef dataSourceRef )
	: Source(), mDataSource( dataSourceRef )
{
	mDataType = DATA_UNKNOWN;
	mSampleRate = 0;
	mChannelCount = 0;
	mBitsPerSample = 0;
	mBlockAlign = 0;
	mIsPcm = FALSE;
	mIsBigEndian = FALSE;
	mIsInterleaved = FALSE;
	
	IStreamRef stream = mDataSource->createStream();

	uint32_t fileSize = 0;
	
	uint32_t chunkName = 0;
	uint32_t chunkSize = 0;
	
	uint32_t riffType = 0;
	
	stream->readData( &chunkName, 4 );
	if( chunkName == gRiffMarker ) {
		mIsBigEndian = false;
	} else if( chunkName == gRifxMarker ) {
		mIsBigEndian = true;
	} else {
		throw IoExceptionFailedLoad();
	}
	
	readStreamWithEndianess( stream, &fileSize, mIsBigEndian );
	fileSize = fileSize + 4 + sizeof( int );
	
	stream->readData( &riffType, 4 );
	if( riffType != gWaveMarker ) {
		throw IoExceptionFailedLoad();
	}
	
	
	uint32_t chunkEnd = 0;
	uint32_t chunks = 0;
	static const uint8_t hasFormat = 1;
	static const uint8_t hasData = 1 << 1;
	
	while( stream->tell() < fileSize) {
		stream->readData( &chunkName, 4 );
		readStreamWithEndianess( stream, &chunkSize, mIsBigEndian );
		chunkEnd = stream->tell() + chunkSize;
		
		if( chunkName == gFmtMarker ) {
			readFormatChunk( stream );
			chunks |= hasFormat;
		} else if( chunkName == gDataMarker ) {
			mDataLength = chunkSize;
			mDataStart = stream->tell();
			chunks |= hasData;
		}
		stream->seekAbsolute( chunkEnd );
	}
	
	if( chunks != ( hasFormat | hasData ) ) {
		throw IoExceptionFailedLoad();
	}

	mSampleCount = mDataLength / mBlockAlign;
	
	//Pull all of the data
	//mData = (int16_t *)calloc( 1, mDataLength );
	//stream->seekSet( mDataStart );
	//stream->readData( mData, mDataLength );


}
LoaderSourceFileWindowsMedia::LoaderSourceFileWindowsMedia( SourceFileWindowsMedia * source, Target * target ) 
	: Loader(), mSource( source ), mSampleOffset( 0 ), mSrcSampleRate( 0 ), mSrcChannelCount( 0 ), mSrcBitsPerSample( 0 )
{
	::HRESULT hr;

	//setup readers
	IWMSyncReader * IWMReaderP = NULL;
	hr = ::WMCreateSyncReader(0, 0, &IWMReaderP );
	if( FAILED( hr ) ) {
		throw IoExceptionFailedLoad();
	}
	mReader = msw::makeComShared<IWMSyncReader>( IWMReaderP );

	IWMHeaderInfo * IWMHeaderInfoP = NULL;
	hr = mReader->QueryInterface( IID_IWMHeaderInfo, (void**)&IWMHeaderInfoP );
	if( FAILED(hr) ) {
		throw IoExceptionFailedLoad();
	}
	mHeaderInfo = msw::makeComShared<IWMHeaderInfo>( IWMHeaderInfoP );

	//turn data into stream
	::IStream * iStreamP = NULL;
	hr = ::CreateStreamOnHGlobal( mSource->mMemHandle.get(), FALSE, &iStreamP );
	if(FAILED(hr)) {
		throw IoExceptionFailedLoad();
	}
	std::shared_ptr<::IStream> pStream = msw::makeComShared<::IStream>( iStreamP );
	
	hr = mReader->OpenStream( pStream.get() );
	if( FAILED(hr) ) {
		throw IoExceptionFailedLoad();
	}

	DWORD nOutputFormatCount;
	hr = mReader->GetOutputFormatCount(0, &nOutputFormatCount);
	if( FAILED(hr) ) {
		throw IoExceptionFailedLoad();
	}
	
	DWORD nFormatSize = 0; 
	BYTE* pBuf = 0;
	IWMOutputMediaProps* pProps = 0;
	for( uint32_t j = 0; j < nOutputFormatCount; j++ ) {
		hr = mReader->GetOutputFormat( 0, j, &pProps  );
		if(FAILED(hr)) {
			continue;
		}

		//get required size of the media type structure
		DWORD nNewSize = 0;
		hr = pProps->GetMediaType( NULL, & nNewSize );
		if( FAILED(hr) ) {
			continue;
		}

		if(nNewSize > nFormatSize)
		{
			if( pBuf ) {
				delete [] pBuf;
				pBuf = 0;
			}

			nFormatSize = nNewSize;
			pBuf = new BYTE[nFormatSize];
		}

		WM_MEDIA_TYPE* pType = (WM_MEDIA_TYPE*) pBuf;
		size_t acrunk = sizeof( WM_MEDIA_TYPE );
		hr = pProps->GetMediaType( pType, &nFormatSize );
		if(FAILED(hr))
			continue;
		
		if( IsEqualIID( WMFORMAT_WaveFormatEx, pType->formattype ) )
		{
			//casting format buffer as WAVEFORMATEX
			//when formattype == WMFORMAT_WaveFormatEx, pbFormat will be
			//WAVEFORMATEX or WAVEFORMATEXTENSIBLE, both of which can be cast
			//safely as WAVEFORMATEX
			mOutputFormat = *((WAVEFORMATEX *)pType->pbFormat);

			if( ( mOutputFormat.wFormatTag == ( ( target->isFloat() ) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM ) ) &&
				( mOutputFormat.nChannels == target->getChannelCount() ) &&
				( mOutputFormat.wBitsPerSample == target->getBitsPerSample() ) &&
				( mOutputFormat.nSamplesPerSec == target->getSampleRate() ) &&
				( mOutputFormat.nBlockAlign == target->getBlockAlign() )
			) {
				mSrcSampleRate = mOutputFormat.nSamplesPerSec;
				mSrcChannelCount = mOutputFormat.nChannels;
				mSrcBitsPerSample = mOutputFormat.wBitsPerSample;
				mSrcBlockAlign = mOutputFormat.nBlockAlign;
				break;
			}
		}
		if( pProps ) {
			pProps->Release();
			pProps = 0;
		}


	}
	if( pBuf ) {
		delete [] pBuf;
		pBuf = 0;
	}

	hr = mReader->SetOutputProps( 0, pProps );
	if( FAILED( hr ) ) {
		throw IoExceptionFailedLoad();
	}

	if( pProps ) {
		pProps->Release();
		pProps = 0;
	}

	WORD wStreamNum = 0;
	WMT_ATTR_DATATYPE Type;
	QWORD dwDuration = 0;
	WORD wLength = 8;
	hr = mHeaderInfo->GetAttributeByName( &wStreamNum, g_wszWMDuration, &Type, (BYTE*)&dwDuration, &wLength );
	if( FAILED( hr ) ) {
		throw IoExceptionFailedLoad();
	}

	//divide by 10 million to get seconds
	double fTime = double( dwDuration ) / 10000000.0f;

	mStreamSize = (uint32_t)( fTime * mOutputFormat.nAvgBytesPerSec * 1.5 );
	
	DWORD tempMaxBufferSize = 0;
	mMaxBufferSize = 0;
	hr = mReader->GetMaxOutputSampleSize( 0, &tempMaxBufferSize );
	mMaxBufferSize = tempMaxBufferSize;
	if( FAILED( hr ) ) {
		throw IoExceptionFailedLoad();
	}

	//set data to not be compressed
	/*hr = mReader->SetReadStreamSamples( 0, FALSE );
	if( FAILED( hr ) ) {
		throw IoExceptionFailedLoad();
	}*/
}
Пример #3
0
SourceFile::SourceFile( DataSourceRef dataSourceRef )
	: Source()
{
	OSStatus err = noErr;
	AudioFileID aFileRef;
	if( dataSourceRef->isFilePath() ) {
		::CFStringRef pathString = cocoa::createCfString( dataSourceRef->getFilePath() );
		::CFURLRef urlRef = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, pathString, kCFURLPOSIXPathStyle, false );
		err = AudioFileOpenURL( urlRef, kAudioFileReadPermission/*fsRdPerm*/, 0, &aFileRef );
		::CFRelease( pathString );
		::CFRelease( urlRef );
		if( err ) {
#if defined(CINDER_MAC)
			//TODO: find iphone equivalent of fnfErr
			if( err == fnfErr ) {
				throw IoExceptionSourceNotFound();
			}
#endif
			throw IoExceptionFailedLoad();
		}
	} else if( dataSourceRef->isUrl() ) {
		::CFURLRef urlRef = cocoa::createCfUrl( dataSourceRef->getUrl() );
		err = AudioFileOpenURL( urlRef, kAudioFileReadPermission/*fsRdPerm*/, 0, &aFileRef );
		::CFRelease( urlRef );
		if( err ) {
			throw IoExceptionFailedLoad();
		}
	}
	mFileRef = shared_ptr<OpaqueAudioFileID>( aFileRef, AudioFileClose );
	
	
	//load header info
	AudioStreamBasicDescription nativeFormatDescription;
	UInt32 size = sizeof( AudioStreamBasicDescription );
	err = AudioFileGetProperty( aFileRef, kAudioFilePropertyDataFormat, &size, &nativeFormatDescription );
	if( err ) {
		throw IoExceptionFailedLoad();
	}
	
	loadFromCaAudioStreamBasicDescription( this, &nativeFormatDescription );
	
	size = sizeof( uint64_t );
	err = AudioFileGetProperty( aFileRef, kAudioFilePropertyAudioDataPacketCount, &size, &mPacketCount );
	if( err ) {
		throw IoExceptionFailedLoad();
	}
	
	size = sizeof( uint64_t );
	err = AudioFileGetProperty( aFileRef, kAudioFilePropertyAudioDataByteCount, &size, &mByteCount );
	if( err ) {
		throw IoExceptionFailedLoad();
	}
	
	size = sizeof( uint32_t );
	err = AudioFileGetProperty( aFileRef, kAudioFilePropertyMaximumPacketSize, &size, &mMaxPacketSize );
	if( err ) {
		throw IoExceptionFailedLoad();
	}
	
	size = sizeof( double );
	err = AudioFileGetProperty( aFileRef, kAudioFilePropertyEstimatedDuration, &size, &mDuration );
	if( err ) {
		throw IoExceptionFailedLoad();
	}
}