commit c744b27bb575bce98849cffb3efcc062a2a65ba9 Author: Edouard DUPIN Date: Tue Mar 18 11:13:00 2014 +0100 [DEV] first simple sif audio effect diff --git a/ewolsa/debug.cpp b/ewolsa/debug.cpp new file mode 100644 index 0000000..11a4477 --- /dev/null +++ b/ewolsa/debug.cpp @@ -0,0 +1,12 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + +#include + +const char * ewolSaLibName = "ewol-sa "; + diff --git a/ewolsa/debug.h b/ewolsa/debug.h new file mode 100644 index 0000000..c2ecb46 --- /dev/null +++ b/ewolsa/debug.h @@ -0,0 +1,28 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD v3 (see license file) + */ + +#ifndef __EWOLSA_DEBUG_H__ +#define __EWOLSA_DEBUG_H__ + +#include +#include + +extern const char * ewolSaLibName; + +#define EWOLSA_CRITICAL(data) ETK_CRITICAL(ewolSaLibName, data) +#define EWOLSA_WARNING(data) ETK_WARNING(ewolSaLibName, data) +#define EWOLSA_ERROR(data) ETK_ERROR(ewolSaLibName, data) +#define EWOLSA_INFO(data) ETK_INFO(ewolSaLibName, data) +#define EWOLSA_DEBUG(data) ETK_DEBUG(ewolSaLibName, data) +#define EWOLSA_VERBOSE(data) ETK_VERBOSE(ewolSaLibName, data) +#define EWOLSA_ASSERT(cond,data) ETK_ASSERT(ewolSaLibName, cond, data) +#define EWOLSA_CHECK_INOUT(cond) ETK_CHECK_INOUT(ewolSaLibName, cond) +#define EWOLSA_TODO(cond) ETK_TODO(ewolSaLibName, cond) + +#endif + diff --git a/ewolsa/decWav.cpp b/ewolsa/decWav.cpp new file mode 100644 index 0000000..b010605 --- /dev/null +++ b/ewolsa/decWav.cpp @@ -0,0 +1,293 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + +#include +#include +#include +#include + + +typedef struct { + char riffTag[4]; //!< 00-03 + uint32_t size; //!< 04-07 + char waveTag[4]; //!< 08-0b + char fmtTag[4]; //!< 0c-0f + uint32_t waveFormatSize; //!< 10-13 + struct { + uint16_t type; //!< 00-01 + uint16_t channelCount; //!< 02-03 + uint32_t samplesPerSec; //!< 04-07 + uint32_t bytesPerSec; //!< 08-0b + uint16_t bytesPerFrame; //!< 0c-0d + uint16_t bitsPerSample; //!< 0e-0f + }waveFormat; //!< 14-23 + char dataTag[4]; //!< 24-27 + uint32_t dataSize; //!< 28-2b +}waveHeader; + + +#define CONVERT_UINT32(littleEndien,data) (littleEndien)?(((uint32_t)((uint8_t*)data)[0] | (uint32_t)((uint8_t*)data)[1] << 8 | (uint32_t)((uint8_t*)data)[2] << 16 | (uint32_t)((uint8_t*)data)[3] << 24)): \ + (((uint32_t)((uint8_t*)data)[3] | (uint32_t)((uint8_t*)data)[2] << 8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[0] << 24)) + +#define CONVERT_INT32(littleEndien,data) (littleEndien)?(((int32_t)((uint8_t*)data)[0] | (int32_t)((uint8_t*)data)[1] << 8 | (int32_t)((uint8_t*)data)[2] << 16 | (int32_t)((int8_t*)data)[3] << 24)): \ + (((int32_t)((uint8_t*)data)[3] | (int32_t)((uint8_t*)data)[2] << 8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[0] << 24)) + +#define CONVERT_UINT24(littleEndien,data) (littleEndien)?(((uint32_t)((uint8_t*)data)[0]<<8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[2] << 24)): \ + (((uint32_t)((uint8_t*)data)[2]<<8 | (uint32_t)((uint8_t*)data)[1] << 16 | (uint32_t)((uint8_t*)data)[0] << 24)) + +#define CONVERT_INT24(littleEndien,data) (littleEndien)?(((int32_t)((uint8_t*)data)[0]<<8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[2] << 24)): \ + (((int32_t)((uint8_t*)data)[2]<<8 | (int32_t)((uint8_t*)data)[1] << 16 | (int32_t)((int8_t*)data)[0] << 24)) + +#define CONVERT_UINT16(littleEndien,data) (littleEndien)?(((uint16_t)((uint8_t*)data)[0] | (uint16_t)((uint8_t*)data)[1] << 8)): \ + (((uint16_t)((uint8_t*)data)[1] | (uint16_t)((uint8_t*)data)[0] << 8)) + +#define CONVERT_INT16(littleEndien,data) (littleEndien)?(((int16_t)((uint8_t*)data)[0] | (int16_t)((int8_t*)data)[1] << 8)): \ + (((int16_t)((uint8_t*)data)[1] | (int16_t)((int8_t*)data)[0] << 8)) + +#define COMPR_PCM (1) +#define COMPR_MADPCM (2) +#define COMPR_ALAW (6) +#define COMPR_MULAW (7) +#define COMPR_ADPCM (17) +#define COMPR_YADPCM (20) +#define COMPR_GSM (49) +#define COMPR_G721 (64) +#define COMPR_MPEG (80) + +int16_t* ewolsa::loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut) { + _nbSampleOut = 0; + waveHeader myHeader; + memset(&myHeader, 0, sizeof(waveHeader)); + etk::FSNode fileAccess(_filename); + // Start loading the XML : + EWOLSA_DEBUG("open file (WAV) \"" << 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; + } + // try to find endienness : + if (fileSize < (int64_t)sizeof(waveHeader)) { + EWOLSA_ERROR("File : \"" << fileAccess << "\" == > has not enouth data inside might be minumum of " << (int32_t)(sizeof(waveHeader))); + return NULL; + } + // ---------------------------------------------- + // read the header : + // ---------------------------------------------- + if (fileAccess.fileRead(&myHeader.riffTag, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + bool littleEndien = false; + if( myHeader.riffTag[0] == 'R' + && myHeader.riffTag[1] == 'I' + && myHeader.riffTag[2] == 'F' + && (myHeader.riffTag[3] == 'F' || myHeader.riffTag[3] == 'X') ) { + if (myHeader.riffTag[3] == 'F' ) { + littleEndien = true; + } + } else { + EWOLSA_ERROR("file: \"" << fileAccess << "\" Does not start with \"RIF\" " ); + return NULL; + } + // get the data size : + unsigned char tmpData[32]; + if (fileAccess.fileRead(tmpData, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + myHeader.size = CONVERT_UINT32(littleEndien, tmpData); + + // get the data size : + if (fileAccess.fileRead(&myHeader.waveTag, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + if( myHeader.waveTag[0] != 'W' + || myHeader.waveTag[1] != 'A' + || myHeader.waveTag[2] != 'V' + || myHeader.waveTag[3] != 'E' ) { + EWOLSA_ERROR("file: \"" << fileAccess << "\" This is not a wave file " << myHeader.waveTag[0] << myHeader.waveTag[1] << myHeader.waveTag[2] << myHeader.waveTag[3] ); + return NULL; + } + + // get the data size : + if (fileAccess.fileRead(&myHeader.fmtTag, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + if( myHeader.fmtTag[0] != 'f' + || myHeader.fmtTag[1] != 'm' + || myHeader.fmtTag[2] != 't' + || myHeader.fmtTag[3] != ' ' ) { + EWOLSA_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.fmtTag[0] << myHeader.fmtTag[1] << myHeader.fmtTag[2] << myHeader.fmtTag[3]); + return NULL; + } + // get the data size : + if (fileAccess.fileRead(tmpData, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + myHeader.waveFormatSize = CONVERT_UINT32(littleEndien, tmpData); + + if (myHeader.waveFormatSize != 16) { + EWOLSA_ERROR("file : \"" << fileAccess << "\" == > header error ..."); + return NULL; + } + if (fileAccess.fileRead(tmpData, 1, 16)!=16) { + EWOLSA_ERROR("Can not 16 element in the file : \"" << fileAccess << "\""); + return NULL; + } + unsigned char * tmppp = tmpData; + myHeader.waveFormat.type = CONVERT_UINT16(littleEndien, tmppp); + tmppp += 2; + myHeader.waveFormat.channelCount = CONVERT_UINT16(littleEndien, tmppp); + tmppp += 2; + myHeader.waveFormat.samplesPerSec = CONVERT_UINT32(littleEndien, tmppp); + tmppp += 4; + myHeader.waveFormat.bytesPerSec = CONVERT_UINT32(littleEndien, tmppp); + tmppp += 4; + myHeader.waveFormat.bytesPerFrame = CONVERT_UINT16(littleEndien, tmppp); + tmppp += 2; + myHeader.waveFormat.bitsPerSample = CONVERT_UINT16(littleEndien, tmppp); + EWOLSA_DEBUG("audio properties : "); + EWOLSA_DEBUG(" type : " << myHeader.waveFormat.type); + EWOLSA_DEBUG(" channelCount : " << myHeader.waveFormat.channelCount); + EWOLSA_DEBUG(" samplesPerSec : " << myHeader.waveFormat.samplesPerSec); + EWOLSA_DEBUG(" bytesPerSec : " << myHeader.waveFormat.bytesPerSec); + EWOLSA_DEBUG(" bytesPerFrame : " << myHeader.waveFormat.bytesPerFrame); + EWOLSA_DEBUG(" bitsPerSample : " << myHeader.waveFormat.bitsPerSample); + // get the data size : + if (fileAccess.fileRead(&myHeader.dataTag, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + if( myHeader.dataTag[0] != 'd' + || myHeader.dataTag[1] != 'a' + || myHeader.dataTag[2] != 't' + || myHeader.dataTag[3] != 'a' ) { + EWOLSA_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.dataTag[0] << myHeader.dataTag[1] << myHeader.dataTag[2] << myHeader.dataTag[3]); + return NULL; + } + // get the data size : + if (fileAccess.fileRead(tmpData, 1, 4)!=4) { + EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\""); + return NULL; + } + myHeader.dataSize = CONVERT_UINT32(littleEndien, tmpData); + + // ---------------------------------------------- + // end of the header reading done ... + // ---------------------------------------------- + + //Parse the data and transform it if needed ... + if (COMPR_PCM != myHeader.waveFormat.type) { + EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only PCM compression ..."); + return NULL; + } + if (myHeader.waveFormat.channelCount == 0 || myHeader.waveFormat.channelCount>2) { + EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only mono or stereo ..." << myHeader.waveFormat.channelCount); + return NULL; + } + if ( ! ( myHeader.waveFormat.bitsPerSample == 16 + || myHeader.waveFormat.bitsPerSample == 24 + || myHeader.waveFormat.bitsPerSample == 32 ) ) { + EWOLSA_ERROR("File : \"" << fileAccess << "\" == > not supported bit/sample ..." << myHeader.waveFormat.bitsPerSample); + return NULL; + } + if( ! ( 44100 == myHeader.waveFormat.samplesPerSec + || 48000 == myHeader.waveFormat.samplesPerSec) ) { + EWOLSA_ERROR("File : \"" << fileAccess << "\" == > not supported frequency " << myHeader.waveFormat.samplesPerSec << " != 48000"); + return NULL; + } + EWOLSA_DEBUG(" dataSize : " << myHeader.dataSize); + //int32_t globalDataSize = myHeader.dataSize; + int32_t nbSample = (myHeader.dataSize/((myHeader.waveFormat.bitsPerSample/8)*myHeader.waveFormat.channelCount)); + int32_t outputSize = _nbChan*nbSample; + int16_t * outputData = (int16_t*)malloc(outputSize*sizeof(int16_t)); + if (NULL == outputData) { + EWOLSA_ERROR("Allocation ERROR try to allocate " << (int32_t)(outputSize*sizeof(int16_t) ) << "bytes"); + return NULL; + } + int16_t * tmpOut = outputData; + for( int32_t iii=0; iii>1) + (right>>1))>>16); + } else { + *tmpOut++ = (int16_t)(left>>16); + *tmpOut++ = (int16_t)(left>>16); + } + } + // close the file: + fileAccess.fileClose(); + _nbSampleOut = nbSample; + return outputData; +} + + diff --git a/ewolsa/decWav.h b/ewolsa/decWav.h new file mode 100644 index 0000000..e9ca292 --- /dev/null +++ b/ewolsa/decWav.h @@ -0,0 +1,19 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + +#ifndef __EWOLSA_DEC_WAV_H__ +#define __EWOLSA_DEC_WAV_H__ + +#include + +namespace ewolsa { + int16_t* loadAudioFile(const std::string& _filename, int8_t _nbChan, int32_t& _nbSampleOut); +}; + +#endif + diff --git a/ewolsa/effects.cpp b/ewolsa/effects.cpp new file mode 100644 index 0000000..6c39661 --- /dev/null +++ b/ewolsa/effects.cpp @@ -0,0 +1,217 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#include + +#include +#include +#include +#include + +static bool effectsMute = false; +static float effectsVolume = 0; +static int32_t effectsVolumeApply = 1<<16; + + +//---------------------------------------------------------------------------------------------------------- +// Effects ... +//---------------------------------------------------------------------------------------------------------- +//liste d'effet +class EffectsLoaded { + public : + EffectsLoaded(const std::string& _file) { + m_file = _file; + m_requestedTime = 1; + m_data = ewolsa::loadAudioFile(_file, 1, m_nbSamples); + if (m_data == NULL) { + // write an error ... + } + } + std::string m_file; + int32_t m_nbSamples; + int32_t m_requestedTime; + int16_t* m_data; +}; + +class RequestPlay { + private: + bool m_freeSlot; + EffectsLoaded* m_effect; // reference to the effects + int32_t m_playTime; // position in sample playing in the audio effects + public : + RequestPlay(EffectsLoaded * _effect) : + m_freeSlot(false), + m_effect(_effect), + m_playTime(0) { + + }; + void reset(EffectsLoaded * _effect) { + m_effect=_effect; + m_playTime=0; + m_freeSlot=false; + }; + bool isFree(void) { + return m_freeSlot; + }; + void play(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) { + if (true == m_freeSlot) { + return; + } + if (m_effect->m_data == NULL) { + m_freeSlot = true; + return; + } + int32_t processTimeMax = etk_min(_nbSample, m_effect->m_nbSamples - m_playTime); + processTimeMax = etk_max(0, processTimeMax); + int16_t * pointer = _bufferInterlace; + int16_t * newData = &m_effect->m_data[m_playTime]; + //EWOLSA_DEBUG("AUDIO : Play slot... nb sample : " << processTimeMax << " playTime=" <m_nbSamples <= m_playTime) { + m_freeSlot=true; + } + } +}; + +#include +std::vector ListEffects; +std::vector ListEffectsPlaying; + +void ewolsa::effects::init(void) { + ewolsa::effects::volumeSet(0); + ewolsa::effects::muteSet(false); +} + +void ewolsa::effects::unInit(void) { + ewolsa::effects::volumeSet(-1000); + ewolsa::effects::muteSet(true); +} + +int32_t ewolsa::effects::add(const std::string& _file) { + for (size_t iii=0; iiim_file == _file) { + ListEffects[iii]->m_requestedTime++; + return iii; + } + } + // effect does not exist ... create a new one ... + EffectsLoaded * tmpEffect = new EffectsLoaded(_file); + if (NULL == tmpEffect) { + EWOLSA_ERROR("Error to load the effects : \"" << _file << "\""); + return -1; + } + ListEffects.push_back(tmpEffect); + return ListEffects.size()-1; +} + +void ewolsa::effects::rm(int32_t _effectId) { + // find element ... + if (_effectId <0 || _effectId >= (int64_t)ListEffects.size()) { + EWOLSA_ERROR("Wrong effect ID : " << _effectId << " != [0.." << ListEffects.size()-1 << "] == > can not remove it ..."); + return; + } + if (ListEffects[_effectId] == NULL) { + EWOLSA_ERROR("effect ID : " << _effectId << " == > has already been removed"); + return; + } + // check number of requested + if (ListEffects[_effectId]->m_requestedTime <= 0) { + EWOLSA_ERROR("effect ID : " << _effectId << " == > request more than predicted a removed of an effects"); + return; + } + ListEffects[_effectId]->m_requestedTime--; + // mark to be removed ... TODO : Really removed it when no other element readed it ... + // TODO : ... +} + + +void ewolsa::effects::play(int32_t _effectId, float _xxx, float _yyy) { + if (_effectId <0 || _effectId >= (int64_t)ListEffects.size()) { + EWOLSA_ERROR("Wrong effect ID : " << _effectId << " != [0.." << ListEffects.size()-1 << "] == > can not play it ..."); + return; + } + if (ListEffects[_effectId] == NULL) { + EWOLSA_ERROR("effect ID : " << _effectId << " == > has been removed"); + return; + } + EWOLSA_VERBOSE("effect play : " << _effectId ); + // try to find an empty slot : + for (size_t iii=0; iiiisFree()) { + ListEffectsPlaying[iii]->reset(ListEffects[_effectId]); + return; + } + } + RequestPlay* newPlay = new RequestPlay(ListEffects[_effectId]); + if (NULL == newPlay) { + EWOLSA_CRITICAL("Allocation error of a playing element : " << _effectId); + return; + } + ListEffectsPlaying.push_back(newPlay); +} + + +float ewolsa::effects::volumeGet(void) { + return effectsVolume; +} + + +static void uptateEffectVolume(void) { + if (effectsMute == true) { + effectsVolumeApply = 0; + } else { + // convert in an fixpoint value + // V2 = V1*10^(db/20) + double coef = pow(10, (effectsVolume/20) ); + effectsVolumeApply = (int32_t)(coef * (double)(1<<16)); + } +} + +void ewolsa::effects::volumeSet(float _newVolume) { + effectsVolume = _newVolume; + effectsVolume = etk_avg(-100, effectsVolume, 20); + EWOLSA_INFO("Set music Volume at " << _newVolume << "dB == > " << effectsVolume << "dB"); + uptateEffectVolume(); +} + + +bool ewolsa::effects::muteGet(void) { + return effectsMute; +} + + +void ewolsa::effects::muteSet(bool _newMute) { + effectsMute = _newMute; + EWOLSA_INFO("Set effects Mute at " << _newMute); +} + + + +void ewolsa::effects::getData(int16_t* _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) { + for (size_t iii = 0; iii < ListEffectsPlaying.size(); ++iii) { + if (ListEffectsPlaying[iii]!= NULL) { + ListEffectsPlaying[iii]->play(_bufferInterlace, _nbSample, _nbChannels); + } + } +} + diff --git a/ewolsa/effects.h b/ewolsa/effects.h new file mode 100644 index 0000000..faf6c7c --- /dev/null +++ b/ewolsa/effects.h @@ -0,0 +1,35 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#ifndef __EWOLSA_EFFECTS_H__ +#define __EWOLSA_EFFECTS_H__ + +#include + +namespace ewolsa { + // note effect is loaded in memory (then don't create long effect) and unload only when requested + namespace effects { + void init(void); + void unInit(void); + // note : support file (Mono, 16bit, 48kHz) : .raw or .wav (no encodage) or .ogg (decoded with tremor lib) + int32_t add(const std::string& _file); + void rm(int32_t _effectId); + void play(int32_t _effectId, float _xxx=0, float _yyy=0); + // in db + float volumeGet(void); + void volumeSet(float _newVolume); + bool muteGet(void); + void muteSet(bool _newMute); + void getData(int16_t* _bufferInterlace, int32_t _nbSample, int32_t _nbChannels); + + }; +}; + +#endif + diff --git a/ewolsa/ewolsa.cpp b/ewolsa/ewolsa.cpp new file mode 100644 index 0000000..eca0f1d --- /dev/null +++ b/ewolsa/ewolsa.cpp @@ -0,0 +1,86 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#include + +#include +#include +#include + + + +airtaudio::Interface* g_dac; + +static int airtAudioCallBack(void *_outputBuffer, + void *_inputBuffer, + unsigned int _nBufferFrames, + double _streamTime, + airtaudio::streamStatus _status, + void* _userData) { + if (_outputBuffer == NULL) { + EWOLSA_ERROR("Null output buffer pointer"); + return -1; + } + // Reset output data, in case ... + memset(_outputBuffer, 0, _nBufferFrames*2*sizeof(int16_t)); + // call music + ewolsa::music::getData((int16_t*)_outputBuffer, _nBufferFrames, 2); + // call Effects + ewolsa::effects::getData((int16_t*)_outputBuffer, _nBufferFrames, 2); + return 0; +} + + + +void ewolsa::init(void) { + if (g_dac != NULL) { + EWOLSA_ERROR("multiple init requested ... at the audio system ..."); + return; + } + ewolsa::effects::init(); + ewolsa::music::init(); + g_dac = new airtaudio::Interface(); + if (g_dac == NULL) { + EWOLSA_ERROR("Can not create AirTAudio interface"); + return; + } + g_dac->instanciate(); + if ( g_dac->getDeviceCount() < 1 ) { + EWOLSA_ERROR("No audio devices found!"); + return; + } + airtaudio::StreamParameters parameters; + parameters.deviceId = g_dac->getDefaultOutputDevice(); + parameters.nChannels = 2; + parameters.firstChannel = 0; + unsigned int bufferFrames = 256; + EWOLSA_DEBUG("init Stream ..."); + g_dac->openStream(¶meters, NULL, airtaudio::SINT16, 48000, &bufferFrames, &airtAudioCallBack, NULL); + g_dac->startStream(); +} + + +void ewolsa::unInit(void) { + if (g_dac == NULL) { + EWOLSA_ERROR("multiple un-init requested ... at the audio system ..."); + return; + } + ewolsa::effects::init(); + ewolsa::music::init(); + + // Stop the stream + g_dac->stopStream(); + if ( g_dac->isStreamOpen() ) { + g_dac->closeStream(); + } + delete(g_dac); + g_dac = NULL; +} + + diff --git a/ewolsa/ewolsa.h b/ewolsa/ewolsa.h new file mode 100644 index 0000000..3fa0c85 --- /dev/null +++ b/ewolsa/ewolsa.h @@ -0,0 +1,23 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#ifndef __EWOLSA_H__ +#define __EWOLSA_H__ + +#include +#include +#include + +namespace ewolsa { + void init(void); + void unInit(void); +}; + +#endif + diff --git a/ewolsa/music.cpp b/ewolsa/music.cpp new file mode 100644 index 0000000..8153e54 --- /dev/null +++ b/ewolsa/music.cpp @@ -0,0 +1,153 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#include + +#include +#include +#include + + +static bool musicMute = false; +static float musicVolume = 0; +static int32_t musicVolumeApply = 1<<16; +static int32_t musicFadingTime = 0; + + + + +void ewolsa::music::init(void) { + ewolsa::music::volumeSet(0); + ewolsa::music::muteSet(false); +} + +void ewolsa::music::unInit(void) { + ewolsa::music::volumeSet(-1000); + ewolsa::music::muteSet(true); +} + + +void ewolsa::music::fading(int32_t _timeMs) { + musicFadingTime = _timeMs; + musicFadingTime = etk_avg(-100, musicFadingTime, 20); + EWOLSA_INFO("Set music fading time at " << _timeMs << "ms == > " << musicFadingTime << "ms"); +} + + +bool ewolsa::music::listAdd(std::string _file) { + return false; +} + + +bool ewolsa::music::listRm(std::string _file) { + return false; +} + + +bool ewolsa::music::listClean(void) { + return false; +} + + +bool ewolsa::music::listPrevious(void) { + return false; +} + + +bool ewolsa::music::listNext(void) { + return false; +} + + +bool ewolsa::music::listFirst(void) { + return false; +} + + +bool ewolsa::music::listLast(void) { + return false; +} + + + +bool ewolsa::music::listPlay(void) { + return false; +} + + +bool ewolsa::music::listStop(void) { + return false; +} + + + + +bool ewolsa::music::play(std::string _file) { + return false; +} + + +bool ewolsa::music::stop(void) { + return false; +} + + + +float ewolsa::music::volumeGet(void) { + return musicVolume; +} + + +static void uptateMusicVolume(void) { + if (musicMute == true) { + musicVolumeApply = 0; + } else { + // convert in an fixpoint value + // V2 = V1*10^(db/20) + double coef = pow(10, (musicVolume/20) ); + musicVolumeApply = (int32_t)(coef * (double)(1<<16)); + } +} + +void ewolsa::music::volumeSet(float _newVolume) { + musicVolume = _newVolume; + musicVolume = etk_avg(-1000, musicVolume, 40); + EWOLSA_INFO("Set music Volume at " << _newVolume << "dB == > " << musicVolume << "dB"); + uptateMusicVolume(); +} + + +bool ewolsa::music::muteGet(void) { + return musicMute; +} + + +void ewolsa::music::muteSet(bool _newMute) { + musicMute = _newMute; + EWOLSA_INFO("Set music Mute at " << _newMute); + uptateMusicVolume(); +} + + +void ewolsa::music::getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) { + /*static int32_t maxValue = 0; + static float angle = 0; + maxValue +=10; + if (maxValue > 16000) { + maxValue = 0; + } + for (int iii = 0; iii= 360) { + angle -= 360.0; + } + }*/ +} diff --git a/ewolsa/music.h b/ewolsa/music.h new file mode 100644 index 0000000..9462111 --- /dev/null +++ b/ewolsa/music.h @@ -0,0 +1,45 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license BSD 3 clauses (see license file) + */ + + +#ifndef __EWOLSA_MUSIC_H__ +#define __EWOLSA_MUSIC_H__ + +#include + +namespace ewolsa { + namespace music { + void init(void); + void unInit(void); + void fading(int32_t _timeMs); + // list playing system : is cyclic ... + bool listAdd(std::string _file); + bool listRm(std::string _file); + bool listClean(void); + bool listPrevious(void); + bool listNext(void); + bool listFirst(void); + bool listLast(void); + bool listPlay(void); // List playing + bool listStop(void); // List stopping + + bool play(std::string _file); // play specific file ... pause the list element; + bool stop(void); + + // in db + float volumeGet(void); + void volumeSet(float _newVolume); + bool muteGet(void); + void muteSet(bool _newMute); + void getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels); + + }; +}; + +#endif + diff --git a/lutin_ewolsa.py b/lutin_ewolsa.py new file mode 100644 index 0000000..6ab82e7 --- /dev/null +++ b/lutin_ewolsa.py @@ -0,0 +1,29 @@ +#!/usr/bin/python +import lutinModule as module +import lutinTools as tools +import lutinDebug as debug + +def get_desc(): + return "ewolsa : ewol simple audio interface for 'small game' audio effects" + + +def create(target): + myModule = module.Module(__file__, 'ewolsa', 'LIBRARY') + # System core + myModule.add_src_file([ + 'ewolsa/debug.cpp', + 'ewolsa/decWav.cpp', + 'ewolsa/effects.cpp', + 'ewolsa/ewolsa.cpp', + 'ewolsa/music.cpp' + ]) + + # name of the dependency + myModule.add_module_depend(['ewol', 'airtaudio']) + + myModule.add_export_path(tools.get_current_path(__file__)) + + # add the currrent module at the + return myModule + +