2 * \file audio_decoder.cpp
4 * \date 2012-04-11 09:34GMT
5 * \author Jan Boon (Kaetemi)
9 // NeL - MMORPG Framework <https://wiki.ryzom.dev/>
10 // Copyright (C) 2008-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
12 // This source file has been modified by the following contributors:
13 // Copyright (C) 2016-2020 Winch Gate Property Limited
15 // This program is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU Affero General Public License as
17 // published by the Free Software Foundation, either version 3 of the
18 // License, or (at your option) any later version.
20 // This program is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU Affero General Public License for more details.
25 // You should have received a copy of the GNU Affero General Public License
26 // along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include <nel/sound/audio_decoder.h>
34 #include <nel/misc/debug.h>
35 #include <nel/misc/path.h>
38 #include <nel/sound/audio_decoder_vorbis.h>
39 #include <nel/sound/audio_decoder_mp3.h>
42 #include <nel/sound/audio_decoder_ffmpeg.h>
46 using namespace NLMISC
;
50 IAudioDecoder::IAudioDecoder() : _InternalStream(NULL
)
55 IAudioDecoder::~IAudioDecoder()
57 if (_InternalStream
) { delete _InternalStream
; _InternalStream
= NULL
; }
60 IAudioDecoder
*IAudioDecoder::createAudioDecoder(const std::string
&filepath
, bool async
, bool loop
)
62 std::string type
= CFile::getExtension(filepath
);
64 CIFile
*ifile
= new CIFile();
65 ifile
->setCacheFileOnOpen(!async
);
66 ifile
->allowBNPCacheFileOnOpen(!async
);
67 ifile
->open(filepath
);
69 IAudioDecoder
*mb
= createAudioDecoder(type
, ifile
, loop
);
71 if (mb
) mb
->_InternalStream
= ifile
;
77 IAudioDecoder
*IAudioDecoder::createAudioDecoder(const std::string
&type
, NLMISC::IStream
*stream
, bool loop
)
81 nlwarning("Stream is NULL");
86 CAudioDecoderFfmpeg
*decoder
= new CAudioDecoderFfmpeg(stream
, loop
);
87 return static_cast<IAudioDecoder
*>(decoder
);
89 catch(const Exception
&e
)
91 nlwarning("Exception %s during ffmpeg setup", e
.what());
95 std::string type_lower
= toLowerAscii(type
);
96 if (type_lower
== "ogg")
98 return new CAudioDecoderVorbis(stream
, loop
);
100 #if !defined(NL_OS_WINDOWS) || (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
101 else if (type_lower
== "mp3")
103 return new CAudioDecoderMP3(stream
, loop
);
108 nlwarning("Music file type unknown: '%s'", type_lower
.c_str());
114 bool IAudioDecoder::getInfo(const std::string
&filepath
, std::string
&artist
, std::string
&title
, float &length
)
116 if (filepath
.empty() || !CFile::fileExists(filepath
))
118 nlwarning("Music file '%s' does not exist!", filepath
.c_str());
122 #ifdef FFMPEG_ENABLED
124 ifile
.setCacheFileOnOpen(false);
125 ifile
.allowBNPCacheFileOnOpen(false);
126 if (ifile
.open(filepath
))
127 return CAudioDecoderFfmpeg::getInfo(&ifile
, artist
, title
, length
);
129 std::string type
= CFile::getExtension(filepath
);
130 std::string type_lower
= NLMISC::toLowerAscii(type
);
132 if (type_lower
== "ogg")
135 ifile
.setCacheFileOnOpen(false);
136 ifile
.allowBNPCacheFileOnOpen(false);
137 if (ifile
.open(filepath
))
138 return CAudioDecoderVorbis::getInfo(&ifile
, artist
, title
, length
);
140 nlwarning("Unable to open: '%s'", filepath
.c_str());
142 #if !defined(NL_OS_WINDOWS) || (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
143 else if (type_lower
== "mp3")
146 ifile
.setCacheFileOnOpen(false);
147 ifile
.allowBNPCacheFileOnOpen(false);
148 if (ifile
.open(filepath
))
149 return CAudioDecoderMP3::getInfo(&ifile
, artist
, title
, length
);
151 nlwarning("Unable to open: '%s'", filepath
.c_str());
156 nlwarning("Music file type unknown: '%s'", type_lower
.c_str());
160 artist
.clear(); title
.clear();
164 /// Get audio/container extensions that are currently supported by the nel sound library.
165 void IAudioDecoder::getMusicExtensions(std::vector
<std::string
> &extensions
)
167 // only add ogg format if not already in extensions list
168 if (std::find(extensions
.begin(), extensions
.end(), "ogg") == extensions
.end())
170 extensions
.push_back("ogg");
172 if (std::find(extensions
.begin(), extensions
.end(), "mp3") == extensions
.end())
174 extensions
.push_back("mp3");
176 #ifdef FFMPEG_ENABLED
177 extensions
.push_back("mp3");
178 extensions
.push_back("flac");
179 extensions
.push_back("aac");
182 // extensions.push_back("wav"); // TODO: Easy.
185 /// Return if a music extension is supported by the nel sound library.
186 bool IAudioDecoder::isMusicExtensionSupported(const std::string
&extension
)
188 #ifdef FFMPEG_ENABLED
189 return (extension
== "ogg" || extension
== "mp3" || extension
== "flac" || extension
== "aac");
191 return (extension
== "ogg");
195 } /* namespace NLSOUND */