/**
* \file audio_decoder.cpp
* \brief IAudioDecoder
* \date 2012-04-11 09:34GMT
* \author Jan Boon (Kaetemi)
* IAudioDecoder
*/
// NeL - MMORPG Framework
// Copyright (C) 2008-2020 Jan BOON (Kaetemi)
//
// This source file has been modified by the following contributors:
// Copyright (C) 2016-2020 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#include "stdsound.h"
#include
// STL includes
// NeL includes
#include
#include
// Project includes
#include
#include
#ifdef FFMPEG_ENABLED
#include
#endif
using namespace std;
using namespace NLMISC;
namespace NLSOUND {
IAudioDecoder::IAudioDecoder() : _InternalStream(NULL)
{
}
IAudioDecoder::~IAudioDecoder()
{
if (_InternalStream) { delete _InternalStream; _InternalStream = NULL; }
}
IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &filepath, bool async, bool loop)
{
std::string type = CFile::getExtension(filepath);
CIFile *ifile = new CIFile();
ifile->setCacheFileOnOpen(!async);
ifile->allowBNPCacheFileOnOpen(!async);
ifile->open(filepath);
IAudioDecoder *mb = createAudioDecoder(type, ifile, loop);
if (mb) mb->_InternalStream = ifile;
else delete ifile;
return mb;
}
IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC::IStream *stream, bool loop)
{
if (!stream)
{
nlwarning("Stream is NULL");
return NULL;
}
#ifdef FFMPEG_ENABLED
try {
CAudioDecoderFfmpeg *decoder = new CAudioDecoderFfmpeg(stream, loop);
return static_cast(decoder);
}
catch(const Exception &e)
{
nlwarning("Exception %s during ffmpeg setup", e.what());
return NULL;
}
#else
std::string type_lower = toLowerAscii(type);
if (type_lower == "ogg")
{
return new CAudioDecoderVorbis(stream, loop);
}
#if !defined(NL_OS_WINDOWS) || (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
else if (type_lower == "mp3")
{
return new CAudioDecoderMP3(stream, loop);
}
#endif
else
{
nlwarning("Music file type unknown: '%s'", type_lower.c_str());
return NULL;
}
#endif
}
bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length)
{
if (filepath.empty() || !CFile::fileExists(filepath))
{
nlwarning("Music file '%s' does not exist!", filepath.c_str());
return false;
}
#ifdef FFMPEG_ENABLED
CIFile ifile;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(filepath))
return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length);
#else
std::string type = CFile::getExtension(filepath);
std::string type_lower = NLMISC::toLowerAscii(type);
if (type_lower == "ogg")
{
CIFile ifile;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(filepath))
return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str());
}
#if !defined(NL_OS_WINDOWS) || (NL_COMP_VC_VERSION > 90) /* VS2008 does not have stdint.h */
else if (type_lower == "mp3")
{
CIFile ifile;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(filepath))
return CAudioDecoderMP3::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str());
}
#endif
else
{
nlwarning("Music file type unknown: '%s'", type_lower.c_str());
}
#endif
artist.clear(); title.clear();
return false;
}
/// Get audio/container extensions that are currently supported by the nel sound library.
void IAudioDecoder::getMusicExtensions(std::vector &extensions)
{
// only add ogg format if not already in extensions list
if (std::find(extensions.begin(), extensions.end(), "ogg") == extensions.end())
{
extensions.push_back("ogg");
}
if (std::find(extensions.begin(), extensions.end(), "mp3") == extensions.end())
{
extensions.push_back("mp3");
}
#ifdef FFMPEG_ENABLED
extensions.push_back("mp3");
extensions.push_back("flac");
extensions.push_back("aac");
#endif
// extensions.push_back("wav"); // TODO: Easy.
}
/// Return if a music extension is supported by the nel sound library.
bool IAudioDecoder::isMusicExtensionSupported(const std::string &extension)
{
#ifdef FFMPEG_ENABLED
return (extension == "ogg" || extension == "mp3" || extension == "flac" || extension == "aac");
#else
return (extension == "ogg");
#endif
}
} /* namespace NLSOUND */
/* end of file */