diff --git a/ewolsa/LoadedFile.cpp b/ewolsa/LoadedFile.cpp index 9f7e772..b7d5914 100644 --- a/ewolsa/LoadedFile.cpp +++ b/ewolsa/LoadedFile.cpp @@ -11,17 +11,27 @@ #include #include #include +#include -ewolsa::LoadedFile::LoadedFile(const std::string& _file, int8_t _nbChanRequested) : - m_file(_file), +ewolsa::LoadedFile::LoadedFile(const std::string& _fileName, int8_t _nbChanRequested) : + m_file(_fileName), m_nbSamples(0), m_requestedTime(1), m_data(NULL){ - m_data = ewolsa::loadAudioFile(_file, _nbChanRequested, m_nbSamples); + std::string tmpName = std::tolower(_fileName); + // select the corect Loader : + if (end_with(tmpName, ".wav") == true) { + m_data = ewolsa::wav::loadAudioFile(_fileName, _nbChanRequested, m_nbSamples); + } else if (end_with(tmpName, ".ogg") == true) { + m_data = ewolsa::ogg::loadAudioFile(_fileName, _nbChanRequested, m_nbSamples); + } else { + EWOLSA_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .wav / .ogg"); + return; + } if (m_data == NULL) { // write an error ... - EWOLSA_ERROR("Can not open file : " << _file); + EWOLSA_ERROR("Can not open file : " << _fileName); } } diff --git a/ewolsa/LoadedFile.h b/ewolsa/LoadedFile.h index a0e30e9..5834de1 100644 --- a/ewolsa/LoadedFile.h +++ b/ewolsa/LoadedFile.h @@ -15,7 +15,7 @@ namespace ewolsa { class LoadedFile { public : - LoadedFile(const std::string& _file, int8_t _nbChanRequested=1); + LoadedFile(const std::string& _fileName, int8_t _nbChanRequested=1); ~LoadedFile(void); std::string m_file; int32_t m_nbSamples; diff --git a/ewolsa/decOgg.cpp b/ewolsa/decOgg.cpp new file mode 100644 index 0000000..3831669 --- /dev/null +++ b/ewolsa/decOgg.cpp @@ -0,0 +1,144 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + +#include +#include +#include +#include +#include +#include + + +static size_t LocalReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) { + etk::FSNode* file = static_cast(datasource); + return file->fileRead(ptr, size, nmemb); +} + +static int localSeekFunc(void *datasource, ogg_int64_t offset, int whence) { + etk::FSNode* file = static_cast(datasource); + enum etk::seekNode mode = etk::FSN_SEEK_START; + if (whence == SEEK_SET) { + mode = etk::FSN_SEEK_START; + } else if (whence == SEEK_END) { + mode = etk::FSN_SEEK_END; + } else if (whence == SEEK_CUR) { + mode = etk::FSN_SEEK_CURRENT; + } + if (file->fileSeek(offset, mode) == true) { + return 0; + } else { + return -1; + } +} + +static int localCloseFunc(void *datasource) { + etk::FSNode* file = static_cast(datasource); + file->fileClose(); +} + +static long localTellFunc(void *datasource) { + etk::FSNode* file = static_cast(datasource); + return file->fileTell(); +} + +int16_t* ewolsa::ogg::loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut) { + _nbSampleOut = 0; + OggVorbis_File vf; + int32_t eof=0; + int32_t current_section; + ov_callbacks tmpCallback = { + LocalReadFunc, + localSeekFunc, + localCloseFunc, + localTellFunc + }; + etk::FSNode fileAccess(_filename); + // Start loading the XML : + EWOLSA_DEBUG("open file (OGG) \"" << fileAccess << "\""); + if (false == fileAccess.exist()) { + EWOLSA_ERROR("File Does not exist : \"" << fileAccess << "\""); + return NULL; + } + int32_t fileSize = fileAccess.fileSize(); + if (0 == fileSize) { + EWOLSA_ERROR("This file is empty : \"" << fileAccess << "\""); + return NULL; + } + if (false == fileAccess.fileOpenRead()) { + EWOLSA_ERROR("Can not open the file : \"" << fileAccess << "\""); + return NULL; + } + if (ov_open_callbacks(&fileAccess, &vf, NULL, 0, tmpCallback) < 0) { + EWOLSA_ERROR("Input does not appear to be an Ogg bitstream."); + return NULL; + } + vorbis_info *vi=ov_info(&vf,-1); + _nbSampleOut = ov_pcm_total(&vf,-1) / vi->channels; + { + char **ptr=ov_comment(&vf,-1)->user_comments; + while(*ptr){ + EWOLSA_DEBUG("comment : " << *ptr); + ++ptr; + } + EWOLSA_DEBUG("Bitstream is " << vi->channels << " channel, " << vi->rate << "Hz"); + EWOLSA_DEBUG("Decoded length: " << _nbSampleOut << " samples"); + EWOLSA_DEBUG("Encoded by: " << ov_comment(&vf,-1)->vendor); + EWOLSA_DEBUG("time: " << ((float)_nbSampleOut/(float)vi->rate)/60.0); + } + int16_t* outputData = new int16_t[_nbSampleOut*_nbChan*sizeof(int16_t)]; + if (NULL == outputData) { + EWOLSA_ERROR("Allocation ERROR try to allocate " << (int32_t)(_nbSampleOut*_nbChan*sizeof(int16_t) ) << "bytes"); + return NULL; + } + int32_t pos = 0; + char pcmout[4096]; + while(!eof){ + long ret=ov_read(&vf, pcmout, sizeof(pcmout), ¤t_section); + if (ret == 0) { + /* EOF */ + eof=1; + } else if (ret < 0) { + if(ret==OV_EBADLINK){ + EWOLSA_ERROR("Corrupt bitstream section! Exiting."); + // TODO : Remove pointer data ... + return NULL; + } + } else { + int16_t* pointerIn = (int16_t*)pcmout; + int16_t* pointerOut = outputData+pos; + if (_nbChan == vi->channels) { + memcpy(pointerOut, pointerIn, ret); + pos += ret/2; + } else { + if ( _nbChan == 1 + && vi->channels == 2) { + for (int32_t iii=0; iiichannels == 1) { + for (int32_t iii=0; iiichannels << " channels in " << _nbChan << " channels"); + } + } + // fwrite(pcmout,1,ret,stdout); + //EWOLSA_DEBUG("get data : " << ret << " Bytes"); + } + } + /* cleanup */ + ov_clear(&vf); + EWOLSA_CRITICAL("Done."); + return outputData; +} + diff --git a/ewolsa/decOgg.h b/ewolsa/decOgg.h new file mode 100644 index 0000000..cd074b0 --- /dev/null +++ b/ewolsa/decOgg.h @@ -0,0 +1,20 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + +#ifndef __EWOLSA_DEC_OGG_H__ +#define __EWOLSA_DEC_OGG_H__ + +#include + +namespace ewolsa { + namespace ogg { + int16_t* loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut); + } +}; + +#endif diff --git a/ewolsa/decWav.cpp b/ewolsa/decWav.cpp index ac925de..5998274 100644 --- a/ewolsa/decWav.cpp +++ b/ewolsa/decWav.cpp @@ -59,7 +59,7 @@ typedef struct { #define COMPR_G721 (64) #define COMPR_MPEG (80) -int16_t* ewolsa::loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut) { +int16_t* ewolsa::wav::loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut) { _nbSampleOut = 0; waveHeader myHeader; memset(&myHeader, 0, sizeof(waveHeader)); diff --git a/ewolsa/decWav.h b/ewolsa/decWav.h index e9ca292..0e360a0 100644 --- a/ewolsa/decWav.h +++ b/ewolsa/decWav.h @@ -12,7 +12,9 @@ #include namespace ewolsa { - int16_t* loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut); + namespace wav { + int16_t* loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut); + } }; #endif diff --git a/lutin_ewolsa.py b/lutin_ewolsa.py index 26977b5..d5a13b5 100644 --- a/lutin_ewolsa.py +++ b/lutin_ewolsa.py @@ -13,6 +13,7 @@ def create(target): myModule.add_src_file([ 'ewolsa/debug.cpp', 'ewolsa/decWav.cpp', + 'ewolsa/decOgg.cpp', 'ewolsa/effects.cpp', 'ewolsa/ewolsa.cpp', 'ewolsa/music.cpp', @@ -20,7 +21,7 @@ def create(target): ]) # name of the dependency - myModule.add_module_depend(['ewol', 'airtaudio']) + myModule.add_module_depend(['ewol', 'airtaudio', 'ogg']) myModule.add_export_path(tools.get_current_path(__file__))