00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "AudioFile.hxx" 00023 #include "Assert.hxx" 00024 #include "PCMCodec.hxx" 00025 #if USE_OGGVORBIS == 1 00026 # include "OggVorbisCodec.hxx" 00027 #endif 00028 00029 #if USE_MAD == 1 00030 # include "MpegCodec.hxx" 00031 #endif 00032 00033 namespace CLAM 00034 { 00035 AudioFile::AudioFile() 00036 : mCodec( EAudioFileCodec::eUnknown ) 00037 , mActiveCodec( NULL ) 00038 { 00039 } 00040 00041 AudioFile::AudioFile( const AudioFile& obj ) 00042 { 00043 mLocation = obj.mLocation; 00044 mActiveCodec = obj.mActiveCodec; 00045 mCodec = obj.mCodec; 00046 mHeaderData = obj.mHeaderData; 00047 mTextDescriptors = obj.mTextDescriptors; 00048 } 00049 00050 const AudioFile& AudioFile::operator=( const AudioFile& obj ) 00051 { 00052 mLocation = obj.mLocation; 00053 mActiveCodec = obj.mActiveCodec; 00054 mCodec = obj.mCodec; 00055 mHeaderData = obj.mHeaderData; 00056 mTextDescriptors = obj.mTextDescriptors; 00057 return *this; 00058 } 00059 00060 AudioFile::~AudioFile() 00061 { 00062 } 00063 00064 void AudioFile::ResolveCodec() 00065 { 00066 mActiveCodec = NULL; 00067 00068 const std::string &location = mLocation; 00069 if ( !AudioCodecs::Codec::FileExists( location ) ) 00070 { 00071 mCodec = EAudioFileCodec::eUnknown; 00072 return; 00073 } 00074 00075 if ( AudioCodecs::PCMCodec::Instantiate().IsReadable( location ) ) 00076 { 00077 mCodec = EAudioFileCodec::ePCM; 00078 mActiveCodec = &AudioCodecs::PCMCodec::Instantiate(); 00079 } 00080 #if USE_OGGVORBIS == 1 00081 else if ( AudioCodecs::OggVorbisCodec::Instantiate().IsReadable( location ) ) 00082 { 00083 mCodec = EAudioFileCodec::eOggVorbis; 00084 mActiveCodec = &AudioCodecs::OggVorbisCodec::Instantiate(); 00085 } 00086 #endif 00087 #if USE_MAD == 1 00088 else if ( AudioCodecs::MpegCodec::Instantiate().IsReadable( location ) ) 00089 { 00090 mCodec = EAudioFileCodec::eMpeg; 00091 mActiveCodec = &AudioCodecs::MpegCodec::Instantiate(); 00092 } 00093 #endif 00094 else 00095 mCodec = EAudioFileCodec::eUnknown; 00096 } 00097 00098 bool AudioFile::SetHeader( const AudioFileHeader& newHeader ) 00099 { 00100 mHeaderData.AddAll(); 00101 mHeaderData.UpdateData(); 00102 00103 if ( !newHeader.HasSampleRate() ) 00104 return false; 00105 else 00106 mHeaderData.SetSampleRate( newHeader.GetSampleRate() ); 00107 00108 if ( !newHeader.HasChannels() ) 00109 mHeaderData.SetChannels( 1 ); 00110 else 00111 mHeaderData.SetChannels( newHeader.GetChannels() ); 00112 00113 if ( !newHeader.HasFormat() ) 00114 return false; 00115 00116 if ( newHeader.HasEncoding() ) 00117 mHeaderData.SetEncoding( newHeader.GetEncoding() ); 00118 00119 00120 if ( newHeader.GetFormat() < EAudioFileFormat::eVorbisMk1 ) 00121 { 00122 mCodec = EAudioFileCodec::ePCM; 00123 mActiveCodec = &AudioCodecs::PCMCodec::Instantiate(); 00124 } 00125 else if ( newHeader.GetFormat() == EAudioFileFormat::eVorbisMk1 ) 00126 { 00127 mCodec = EAudioFileCodec::eOggVorbis; 00128 #if USE_OGGVORBIS==1 00129 mActiveCodec= &AudioCodecs::OggVorbisCodec::Instantiate(); 00130 #endif 00131 } 00132 else 00133 CLAM_ASSERT( false, "The Enum contained and invalid value!" ); 00134 00135 mHeaderData.SetFormat( newHeader.GetFormat() ); 00136 00137 if ( !newHeader.HasEndianess() ) 00138 mHeaderData.SetEndianess( EAudioFileEndianess::eDefault ); 00139 else 00140 mHeaderData.SetEndianess( newHeader.GetEndianess() ); 00141 00142 return true; 00143 } 00144 00145 EAudioFileCodec AudioFile::GetCodec() const 00146 { 00147 return mCodec; 00148 } 00149 00150 bool AudioFile::IsValid() const 00151 { 00152 return mActiveCodec == NULL; 00153 } 00154 00155 bool AudioFile::IsReadable() const 00156 { 00157 return mActiveCodec && mActiveCodec->IsReadable(mLocation); 00158 } 00159 00160 bool AudioFile::IsWritable() const 00161 { 00162 return mActiveCodec && mActiveCodec->IsWritable(mLocation, mHeaderData ); 00163 } 00164 00165 AudioCodecs::Stream* AudioFile::GetStream() 00166 { 00167 if ( !mActiveCodec ) return 0; 00168 return mActiveCodec->GetStreamFor( *this ); 00169 } 00170 00171 void AudioFile::ActivateCodec() 00172 { 00173 if (!mActiveCodec) return; 00174 mActiveCodec->RetrieveHeaderData( mLocation, mHeaderData ); 00175 mActiveCodec->RetrieveTextDescriptors( mLocation, mTextDescriptors ); 00176 } 00177 00178 void AudioFile::ResetHeaderData() 00179 { 00180 mHeaderData.RemoveAll(); 00181 mHeaderData.UpdateData(); 00182 } 00183 00184 /* =============================================================== */ 00185 00186 void AudioFileSource::OpenExisting(const std::string &location) 00187 { 00188 mLocation = location; 00189 ResolveCodec(); 00190 ActivateCodec(); 00191 if ( mCodec == EAudioFileCodec::eUnknown ) 00192 ResetHeaderData(); 00193 } 00194 00195 /* =============================================================== */ 00196 00197 bool AudioFileTarget::CreateNew(const std::string &location, 00198 const AudioFileHeader &header) 00199 { 00200 mLocation = location; 00201 return SetHeader(header); 00202 } 00203 00204 } 00205