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(); }*/ }
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(); } }