Fix "no remove aqua speed" bug when player leaves the water
[ryzomcore.git] / nel / src / sound / audio_decoder.cpp
blob2f6f1508a241c6c2b3b7f645e92e6f957efd775c
1 /**
2 * \file audio_decoder.cpp
3 * \brief IAudioDecoder
4 * \date 2012-04-11 09:34GMT
5 * \author Jan Boon (Kaetemi)
6 * IAudioDecoder
7 */
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/>.
28 #include "stdsound.h"
29 #include <nel/sound/audio_decoder.h>
31 // STL includes
33 // NeL includes
34 #include <nel/misc/debug.h>
35 #include <nel/misc/path.h>
37 // Project includes
38 #include <nel/sound/audio_decoder_vorbis.h>
39 #include <nel/sound/audio_decoder_mp3.h>
41 #ifdef FFMPEG_ENABLED
42 #include <nel/sound/audio_decoder_ffmpeg.h>
43 #endif
45 using namespace std;
46 using namespace NLMISC;
48 namespace NLSOUND {
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;
72 else delete ifile;
74 return mb;
77 IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop)
79 if (!stream)
81 nlwarning("Stream is NULL");
82 return NULL;
84 #ifdef FFMPEG_ENABLED
85 try {
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());
92 return NULL;
94 #else
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);
105 #endif
106 else
108 nlwarning("Music file type unknown: '%s'", type_lower.c_str());
109 return NULL;
111 #endif
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());
119 return false;
122 #ifdef FFMPEG_ENABLED
123 CIFile ifile;
124 ifile.setCacheFileOnOpen(false);
125 ifile.allowBNPCacheFileOnOpen(false);
126 if (ifile.open(filepath))
127 return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length);
128 #else
129 std::string type = CFile::getExtension(filepath);
130 std::string type_lower = NLMISC::toLowerAscii(type);
132 if (type_lower == "ogg")
134 CIFile ifile;
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")
145 CIFile ifile;
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());
153 #endif
154 else
156 nlwarning("Music file type unknown: '%s'", type_lower.c_str());
158 #endif
160 artist.clear(); title.clear();
161 return false;
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");
180 #endif
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");
190 #else
191 return (extension == "ogg");
192 #endif
195 } /* namespace NLSOUND */
197 /* end of file */