[DEV] basic version with music
This commit is contained in:
parent
c744b27bb5
commit
5dbdea5425
36
ewolsa/LoadedFile.cpp
Normal file
36
ewolsa/LoadedFile.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license BSD 3 clauses (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <etk/types.h>
|
||||||
|
#include <ewolsa/debug.h>
|
||||||
|
#include <ewolsa/LoadedFile.h>
|
||||||
|
#include <ewolsa/decWav.h>
|
||||||
|
|
||||||
|
|
||||||
|
ewolsa::LoadedFile::LoadedFile(const std::string& _file, int8_t _nbChanRequested) :
|
||||||
|
m_file(_file),
|
||||||
|
m_nbSamples(0),
|
||||||
|
m_requestedTime(1),
|
||||||
|
m_data(NULL){
|
||||||
|
m_data = ewolsa::loadAudioFile(_file, _nbChanRequested, m_nbSamples);
|
||||||
|
if (m_data == NULL) {
|
||||||
|
// write an error ...
|
||||||
|
EWOLSA_ERROR("Can not open file : " << _file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ewolsa::LoadedFile::~LoadedFile(void) {
|
||||||
|
if (m_data != NULL) {
|
||||||
|
delete[] m_data;
|
||||||
|
m_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
32
ewolsa/LoadedFile.h
Normal file
32
ewolsa/LoadedFile.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license BSD 3 clauses (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __EWOLSA_LOADED_FILE_H__
|
||||||
|
#define __EWOLSA_LOADED_FILE_H__
|
||||||
|
|
||||||
|
#include <etk/types.h>
|
||||||
|
|
||||||
|
namespace ewolsa {
|
||||||
|
class LoadedFile {
|
||||||
|
public :
|
||||||
|
LoadedFile(const std::string& _file, int8_t _nbChanRequested=1);
|
||||||
|
~LoadedFile(void);
|
||||||
|
std::string m_file;
|
||||||
|
int32_t m_nbSamples;
|
||||||
|
int32_t m_requestedTime;
|
||||||
|
int16_t* m_data;
|
||||||
|
public:
|
||||||
|
const std::string& getName(void) {
|
||||||
|
return m_file;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -218,7 +218,7 @@ int16_t* ewolsa::loadAudioFile(const std::string& _filename, int8_t _nbChan, int
|
|||||||
//int32_t globalDataSize = myHeader.dataSize;
|
//int32_t globalDataSize = myHeader.dataSize;
|
||||||
int32_t nbSample = (myHeader.dataSize/((myHeader.waveFormat.bitsPerSample/8)*myHeader.waveFormat.channelCount));
|
int32_t nbSample = (myHeader.dataSize/((myHeader.waveFormat.bitsPerSample/8)*myHeader.waveFormat.channelCount));
|
||||||
int32_t outputSize = _nbChan*nbSample;
|
int32_t outputSize = _nbChan*nbSample;
|
||||||
int16_t * outputData = (int16_t*)malloc(outputSize*sizeof(int16_t));
|
int16_t * outputData = new int16_t[outputSize*sizeof(int16_t)];
|
||||||
if (NULL == outputData) {
|
if (NULL == outputData) {
|
||||||
EWOLSA_ERROR("Allocation ERROR try to allocate " << (int32_t)(outputSize*sizeof(int16_t) ) << "bytes");
|
EWOLSA_ERROR("Allocation ERROR try to allocate " << (int32_t)(outputSize*sizeof(int16_t) ) << "bytes");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -281,7 +281,7 @@ int16_t* ewolsa::loadAudioFile(const std::string& _filename, int8_t _nbChan, int
|
|||||||
*tmpOut++ = (int16_t)(((left>>1) + (right>>1))>>16);
|
*tmpOut++ = (int16_t)(((left>>1) + (right>>1))>>16);
|
||||||
} else {
|
} else {
|
||||||
*tmpOut++ = (int16_t)(left>>16);
|
*tmpOut++ = (int16_t)(left>>16);
|
||||||
*tmpOut++ = (int16_t)(left>>16);
|
*tmpOut++ = (int16_t)(right>>16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// close the file:
|
// close the file:
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
#include <ewolsa/effects.h>
|
#include <ewolsa/effects.h>
|
||||||
#include <ewolsa/decWav.h>
|
#include <ewolsa/decWav.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ewolsa/LoadedFile.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
static std::mutex localMutex;
|
||||||
static bool effectsMute = false;
|
static bool effectsMute = false;
|
||||||
static float effectsVolume = 0;
|
static float effectsVolume = 0;
|
||||||
static int32_t effectsVolumeApply = 1<<16;
|
static int32_t effectsVolumeApply = 1<<16;
|
||||||
@ -22,36 +25,20 @@ static int32_t effectsVolumeApply = 1<<16;
|
|||||||
//----------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------
|
||||||
// Effects ...
|
// 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 {
|
class RequestPlay {
|
||||||
private:
|
private:
|
||||||
bool m_freeSlot;
|
bool m_freeSlot;
|
||||||
EffectsLoaded* m_effect; // reference to the effects
|
ewolsa::LoadedFile* m_effect; // reference to the effects
|
||||||
int32_t m_playTime; // position in sample playing in the audio effects
|
int32_t m_playTime; // position in sample playing in the audio effects
|
||||||
public :
|
public :
|
||||||
RequestPlay(EffectsLoaded * _effect) :
|
RequestPlay(ewolsa::LoadedFile * _effect) :
|
||||||
m_freeSlot(false),
|
m_freeSlot(false),
|
||||||
m_effect(_effect),
|
m_effect(_effect),
|
||||||
m_playTime(0) {
|
m_playTime(0) {
|
||||||
|
|
||||||
};
|
};
|
||||||
void reset(EffectsLoaded * _effect) {
|
void reset(ewolsa::LoadedFile * _effect) {
|
||||||
m_effect=_effect;
|
m_effect=_effect;
|
||||||
m_playTime=0;
|
m_playTime=0;
|
||||||
m_freeSlot=false;
|
m_freeSlot=false;
|
||||||
@ -91,7 +78,7 @@ class RequestPlay {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
std::vector<EffectsLoaded*> ListEffects;
|
std::vector<ewolsa::LoadedFile*> ListEffects;
|
||||||
std::vector<RequestPlay*> ListEffectsPlaying;
|
std::vector<RequestPlay*> ListEffectsPlaying;
|
||||||
|
|
||||||
void ewolsa::effects::init(void) {
|
void ewolsa::effects::init(void) {
|
||||||
@ -115,7 +102,7 @@ int32_t ewolsa::effects::add(const std::string& _file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// effect does not exist ... create a new one ...
|
// effect does not exist ... create a new one ...
|
||||||
EffectsLoaded * tmpEffect = new EffectsLoaded(_file);
|
ewolsa::LoadedFile * tmpEffect = new ewolsa::LoadedFile(_file);
|
||||||
if (NULL == tmpEffect) {
|
if (NULL == tmpEffect) {
|
||||||
EWOLSA_ERROR("Error to load the effects : \"" << _file << "\"");
|
EWOLSA_ERROR("Error to load the effects : \"" << _file << "\"");
|
||||||
return -1;
|
return -1;
|
||||||
@ -203,6 +190,7 @@ bool ewolsa::effects::muteGet(void) {
|
|||||||
void ewolsa::effects::muteSet(bool _newMute) {
|
void ewolsa::effects::muteSet(bool _newMute) {
|
||||||
effectsMute = _newMute;
|
effectsMute = _newMute;
|
||||||
EWOLSA_INFO("Set effects Mute at " << _newMute);
|
EWOLSA_INFO("Set effects Mute at " << _newMute);
|
||||||
|
uptateEffectVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
184
ewolsa/music.cpp
184
ewolsa/music.cpp
@ -11,25 +11,53 @@
|
|||||||
|
|
||||||
#include <ewolsa/music.h>
|
#include <ewolsa/music.h>
|
||||||
#include <ewolsa/debug.h>
|
#include <ewolsa/debug.h>
|
||||||
|
#include <ewolsa/LoadedFile.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
static std::mutex localMutex;
|
||||||
|
|
||||||
static bool musicMute = false;
|
static bool musicMute = false;
|
||||||
static float musicVolume = 0;
|
static float musicVolume = 0;
|
||||||
static int32_t musicVolumeApply = 1<<16;
|
static int32_t musicVolumeApply = 1<<16;
|
||||||
static int32_t musicFadingTime = 0;
|
static int32_t musicFadingTime = 0;
|
||||||
|
static int32_t musicPositionReading = 0;
|
||||||
|
static std::vector<ewolsa::LoadedFile*> musicListRead;
|
||||||
|
static int32_t musicCurrentRead = -1;
|
||||||
|
static int32_t musicNextRead = -1;
|
||||||
|
|
||||||
void ewolsa::music::init(void) {
|
void ewolsa::music::init(void) {
|
||||||
ewolsa::music::volumeSet(0);
|
ewolsa::music::volumeSet(0);
|
||||||
ewolsa::music::muteSet(false);
|
ewolsa::music::muteSet(false);
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
|
musicCurrentRead = -1;
|
||||||
|
musicNextRead = -1;
|
||||||
|
musicPositionReading = 0;
|
||||||
|
for (size_t iii=0; iii<musicListRead.size(); ++iii) {
|
||||||
|
if (musicListRead[iii] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
delete musicListRead[iii];
|
||||||
|
musicListRead[iii] = NULL;
|
||||||
|
}
|
||||||
|
musicListRead.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ewolsa::music::unInit(void) {
|
void ewolsa::music::unInit(void) {
|
||||||
ewolsa::music::volumeSet(-1000);
|
ewolsa::music::volumeSet(-1000);
|
||||||
ewolsa::music::muteSet(true);
|
ewolsa::music::muteSet(true);
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
|
musicCurrentRead = -1;
|
||||||
|
musicNextRead = -1;
|
||||||
|
musicPositionReading = 0;
|
||||||
|
for (size_t iii=0; iii<musicListRead.size(); ++iii) {
|
||||||
|
if (musicListRead[iii] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
delete musicListRead[iii];
|
||||||
|
musicListRead[iii] = NULL;
|
||||||
|
}
|
||||||
|
musicListRead.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,61 +68,64 @@ void ewolsa::music::fading(int32_t _timeMs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ewolsa::music::listAdd(std::string _file) {
|
void ewolsa::music::preLoad(const std::string& _file) {
|
||||||
return false;
|
// check if music already existed ...
|
||||||
|
for (size_t iii=0; iii<musicListRead.size(); ++iii) {
|
||||||
|
if (musicListRead[iii] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (musicListRead[iii]->getName() == _file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ewolsa::LoadedFile* tmp = new ewolsa::LoadedFile(_file, 2);
|
||||||
|
if (tmp != NULL) {
|
||||||
|
if (tmp->m_data == NULL) {
|
||||||
|
EWOLSA_ERROR("Music has no data ... : " << _file);
|
||||||
|
delete(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
|
musicListRead.push_back(tmp);
|
||||||
|
} else {
|
||||||
|
EWOLSA_ERROR("can not preload audio Music");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ewolsa::music::listRm(std::string _file) {
|
bool ewolsa::music::play(const std::string& _file) {
|
||||||
return false;
|
preLoad(_file);
|
||||||
}
|
// in all case we stop the current playing music ...
|
||||||
|
stop();
|
||||||
|
int32_t idMusic = -1;
|
||||||
bool ewolsa::music::listClean(void) {
|
// check if music already existed ...
|
||||||
return false;
|
for (size_t iii=0; iii<musicListRead.size(); ++iii) {
|
||||||
}
|
if (musicListRead[iii] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
bool ewolsa::music::listPrevious(void) {
|
if (musicListRead[iii]->getName() == _file) {
|
||||||
return false;
|
idMusic = iii;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool ewolsa::music::listNext(void) {
|
if (idMusic == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
|
musicNextRead = idMusic;
|
||||||
bool ewolsa::music::listFirst(void) {
|
EWOLSA_INFO("Playing track " << musicCurrentRead << " request next : " << idMusic);
|
||||||
return false;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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) {
|
bool ewolsa::music::stop(void) {
|
||||||
return false;
|
if (musicCurrentRead == -1) {
|
||||||
|
EWOLSA_INFO("No current audio is playing");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
|
musicNextRead = -1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -111,6 +142,7 @@ static void uptateMusicVolume(void) {
|
|||||||
// convert in an fixpoint value
|
// convert in an fixpoint value
|
||||||
// V2 = V1*10^(db/20)
|
// V2 = V1*10^(db/20)
|
||||||
double coef = pow(10, (musicVolume/20) );
|
double coef = pow(10, (musicVolume/20) );
|
||||||
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
musicVolumeApply = (int32_t)(coef * (double)(1<<16));
|
musicVolumeApply = (int32_t)(coef * (double)(1<<16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,18 +168,42 @@ void ewolsa::music::muteSet(bool _newMute) {
|
|||||||
|
|
||||||
|
|
||||||
void ewolsa::music::getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) {
|
void ewolsa::music::getData(int16_t * _bufferInterlace, int32_t _nbSample, int32_t _nbChannels) {
|
||||||
/*static int32_t maxValue = 0;
|
EWOLSA_VERBOSE("Music !!! " << musicCurrentRead << " ... " << musicNextRead << " pos: " << musicPositionReading);
|
||||||
static float angle = 0;
|
std::unique_lock<std::mutex> lck(localMutex);
|
||||||
maxValue +=10;
|
if (musicCurrentRead != musicNextRead) {
|
||||||
if (maxValue > 16000) {
|
EWOLSA_DEBUG("change track " << musicCurrentRead << " ==> " << musicNextRead);
|
||||||
maxValue = 0;
|
// TODO : create fading ....
|
||||||
|
musicCurrentRead = musicNextRead;
|
||||||
|
musicPositionReading = 0;
|
||||||
}
|
}
|
||||||
for (int iii = 0; iii<nbSample ; iii++) {
|
if (musicCurrentRead < 0) {
|
||||||
bufferInterlace[iii*2] = (float)maxValue * sin(angle/180.0 * M_PI);
|
// nothing to play ...
|
||||||
bufferInterlace[iii*2+1] = bufferInterlace[iii*2];
|
return;
|
||||||
angle+=0.9;
|
}
|
||||||
if (angle >= 360) {
|
if ( musicCurrentRead >= musicListRead.size()
|
||||||
angle -= 360.0;
|
|| musicListRead[musicCurrentRead] == NULL) {
|
||||||
}
|
musicCurrentRead = -1;
|
||||||
}*/
|
musicPositionReading = 0;
|
||||||
|
EWOLSA_ERROR("request read an unexisting audio track ... : " << musicCurrentRead << "/" << musicListRead.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int32_t processTimeMax = etk_min(_nbSample*_nbChannels, musicListRead[musicCurrentRead]->m_nbSamples - musicPositionReading);
|
||||||
|
processTimeMax = etk_max(0, processTimeMax);
|
||||||
|
int16_t * pointer = _bufferInterlace;
|
||||||
|
int16_t * newData = &musicListRead[musicCurrentRead]->m_data[musicPositionReading];
|
||||||
|
//EWOLSA_DEBUG("AUDIO : Play slot... nb sample : " << processTimeMax << " playTime=" <<m_playTime << " nbCannels=" << nbChannels);
|
||||||
|
for (int32_t iii=0; iii<processTimeMax; iii++) {
|
||||||
|
int32_t tmppp = *pointer + ((((int32_t)*newData)*musicVolumeApply)>>16);
|
||||||
|
*pointer = etk_avg(-32767, tmppp, 32766);
|
||||||
|
//EWOLSA_DEBUG("AUDIO : element : " << *pointer);
|
||||||
|
pointer++;
|
||||||
|
newData++;
|
||||||
|
}
|
||||||
|
musicPositionReading += processTimeMax;
|
||||||
|
// check end of playing ...
|
||||||
|
if (musicListRead[musicCurrentRead]->m_nbSamples <= musicPositionReading) {
|
||||||
|
musicPositionReading = 0;
|
||||||
|
musicCurrentRead = -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,9 @@ namespace ewolsa {
|
|||||||
void init(void);
|
void init(void);
|
||||||
void unInit(void);
|
void unInit(void);
|
||||||
void fading(int32_t _timeMs);
|
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;
|
void preLoad(const std::string& _file);
|
||||||
|
bool play(const std::string& _file);
|
||||||
bool stop(void);
|
bool stop(void);
|
||||||
|
|
||||||
// in db
|
// in db
|
||||||
|
@ -15,7 +15,8 @@ def create(target):
|
|||||||
'ewolsa/decWav.cpp',
|
'ewolsa/decWav.cpp',
|
||||||
'ewolsa/effects.cpp',
|
'ewolsa/effects.cpp',
|
||||||
'ewolsa/ewolsa.cpp',
|
'ewolsa/ewolsa.cpp',
|
||||||
'ewolsa/music.cpp'
|
'ewolsa/music.cpp',
|
||||||
|
'ewolsa/LoadedFile.cpp'
|
||||||
])
|
])
|
||||||
|
|
||||||
# name of the dependency
|
# name of the dependency
|
||||||
|
Loading…
x
Reference in New Issue
Block a user