00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MpegAudioStream.hxx"
00023 #include "AudioFile.hxx"
00024 #include "Assert.hxx"
00025 #include <iostream>
00026
00027 namespace CLAM
00028 {
00029
00030 namespace AudioCodecs
00031 {
00032
00033 const TSize MpegAudioStream::mMaxDecodedBlockSize = 8192;
00034
00035 MpegAudioStream::MpegAudioStream()
00036 : mpHandle( NULL )
00037 {
00038 }
00039
00040 MpegAudioStream::MpegAudioStream( const AudioFile& file )
00041 : mpHandle( NULL )
00042 {
00043 SetFOI( file );
00044 }
00045
00046 MpegAudioStream::~MpegAudioStream()
00047 {
00048
00049 if ( mpHandle )
00050 {
00051 if ( fclose(mpHandle) )
00052 {
00053 std::string msgString = "Could not close ";
00054 msgString += mName;
00055
00056 CLAM_ASSERT( false, msgString.c_str() );
00057 }
00058 }
00059
00060 }
00061
00062 void MpegAudioStream::SetFOI( const AudioFile& file )
00063 {
00064 AudioFileToNative( file );
00065 }
00066
00067 void MpegAudioStream::AudioFileToNative( const AudioFile& file )
00068 {
00069 mName = file.GetLocation();
00070 mEncodedSampleRate = (int)file.GetHeader().GetSampleRate();
00071 mEncodedChannels = (int)file.GetHeader().GetChannels();
00072
00073 mDecodeBuffer.resize( mEncodedChannels );
00074 }
00075
00076 void MpegAudioStream::PrepareReading()
00077 {
00078 mpHandle = fopen( mName.c_str(), "rb");
00079
00080 if ( !mpHandle )
00081 {
00082 std::string msgString = "Could not open ";
00083 msgString += mName;
00084 msgString += " for reading!";
00085
00086 CLAM_ASSERT( false, msgString.c_str() );
00087
00088 }
00089
00090 mBitstream.Init( mpHandle );
00091
00092 SetChannels( mEncodedChannels );
00093 MarkAllChannelsAsConsumed();
00094
00095 mSamplesDecoded = 0;
00096 mSamplesTransferred = 0;
00097 }
00098
00099 void MpegAudioStream::PrepareWriting()
00100 {
00101 CLAM_ASSERT( false, "CLAM does not encode Mpeg Audio!!!");
00102 }
00103
00104 void MpegAudioStream::PrepareReadWrite()
00105 {
00106 CLAM_ASSERT( false, "CLAM does not encode Mpeg Audio!!!");
00107 }
00108
00109 void MpegAudioStream::Dispose()
00110 {
00111 mBitstream.Finish();
00112 }
00113
00114 void MpegAudioStream::DiskToMemoryTransfer()
00115 {
00116 unsigned samplesToRead = mInterleavedData.Size()/mEncodedChannels;
00117
00118 while( mDecodeBuffer[0].size() < samplesToRead
00119 && mBitstream.NextFrame() )
00120 {
00121 mBitstream.SynthesizeCurrent();
00122
00123 CLAM_ASSERT( mEncodedChannels == MAD_NCHANNELS( &mBitstream.CurrentFrame().header ),
00124 "This frame hasn't mEncodedChannels channels!" );
00125
00126 CLAM_ASSERT( mEncodedChannels == mBitstream.CurrentSynthesis().pcm.channels,
00127 "Synthesis result does not have the expected number of channels" );
00128
00129 TSize samplesDecodedThisTime = mBitstream.CurrentSynthesis().pcm.length;
00130
00131 for( int i = 0; i < mEncodedChannels; i++ )
00132 {
00133 mad_fixed_t* channelData = mBitstream.CurrentSynthesis().pcm.samples[i];
00134
00135 mDecodeBuffer[i].insert( mDecodeBuffer[i].end(),
00136 channelData,
00137 channelData + samplesDecodedThisTime );
00138 }
00139
00140 mSamplesDecoded += mBitstream.CurrentSynthesis().pcm.length;
00141
00142 }
00143
00144 mFramesLastRead = mDecodeBuffer[0].size();
00145
00146 if ( !mDecodeBuffer[0].empty() )
00147 {
00148
00149 for ( int i = 0; i < mEncodedChannels; i++ )
00150 if ( mDecodeBuffer[i].size() < samplesToRead )
00151 {
00152 mDecodeBuffer[i].insert( mDecodeBuffer[i].end(),
00153 samplesToRead - mDecodeBuffer[i].size(),
00154 mad_fixed_t(0) );
00155
00156 }
00157
00158 ConsumeDecodedSamples();
00159 }
00160
00161 mEOFReached = mBitstream.EOS() && mDecodeBuffer[0].empty();
00162 }
00163
00164 void MpegAudioStream::ConsumeDecodedSamples()
00165 {
00166 TSize samplesToRead = mInterleavedData.Size()/mEncodedChannels;
00167
00168 for ( int i = 0; i < mEncodedChannels; i++ )
00169 {
00170 TIndex currOffset = 0;
00171
00172 for ( std::deque<mad_fixed_t>::iterator j = mDecodeBuffer[i].begin();
00173 currOffset < mInterleavedData.Size();
00174 j++, currOffset+=mEncodedChannels )
00175 {
00176 double sampleValue = mad_f_todouble(*j);
00177
00178
00179
00180
00181 if ( sampleValue > 1.0 )
00182 sampleValue = 1.0;
00183 else if ( sampleValue < -1.0 )
00184 sampleValue = -1.0;
00185
00186
00187 mInterleavedData[ currOffset + i ] = TData(sampleValue);
00188 }
00189
00190 mDecodeBuffer[i].erase( mDecodeBuffer[i].begin(),
00191 mDecodeBuffer[i].begin() + samplesToRead );
00192 }
00193
00194 mSamplesTransferred += samplesToRead;
00195
00196
00197 }
00198
00199 void MpegAudioStream::MemoryToDiskTransfer()
00200 {
00201 CLAM_ASSERT( false, "CLAM does not encode Mpeg Audio!!!");
00202 }
00203 }
00204
00205 }
00206