audio-ess/ewolsa/music.cpp

214 lines
5.6 KiB
C++
Raw Permalink Normal View History

2014-03-18 11:13:00 +01:00
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD 3 clauses (see license file)
*/
#include <etk/types.h>
#include <ewolsa/music.h>
#include <ewolsa/debug.h>
2014-03-20 10:24:13 +01:00
#include <ewolsa/LoadedFile.h>
2014-03-18 11:13:00 +01:00
#include <math.h>
2014-03-20 10:24:13 +01:00
#include <mutex>
2014-03-18 11:13:00 +01:00
2014-03-20 10:24:13 +01:00
static std::mutex localMutex;
2014-03-18 11:13:00 +01:00
static bool musicMute = false;
static float musicVolume = 0;
static int32_t musicVolumeApply = 1<<16;
static int32_t musicFadingTime = 0;
2014-03-20 10:24:13 +01:00
static int32_t musicPositionReading = 0;
static std::vector<ewolsa::LoadedFile*> musicListRead;
static int32_t musicCurrentRead = -1;
static int32_t musicNextRead = -1;
2014-03-18 11:13:00 +01:00
void ewolsa::music::init(void) {
ewolsa::music::volumeSet(0);
ewolsa::music::muteSet(false);
2014-03-20 10:24:13 +01:00
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();
2014-03-18 11:13:00 +01:00
}
void ewolsa::music::unInit(void) {
ewolsa::music::volumeSet(-1000);
ewolsa::music::muteSet(true);
2014-03-20 10:24:13 +01:00
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();
2014-03-18 11:13:00 +01:00
}
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");
}
2014-03-20 10:24:13 +01:00
void ewolsa::music::preLoad(const std::string& _file) {
// 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) {
/*
2014-03-20 10:24:13 +01:00
if (tmp->m_data == NULL) {
EWOLSA_ERROR("Music has no data ... : " << _file);
delete(tmp);
return;
}*/
2014-03-20 10:24:13 +01:00
std::unique_lock<std::mutex> lck(localMutex);
musicListRead.push_back(tmp);
} else {
EWOLSA_ERROR("can not preload audio Music");
}
2014-03-18 11:13:00 +01:00
}
2014-03-20 10:24:13 +01:00
bool ewolsa::music::play(const std::string& _file) {
preLoad(_file);
// in all case we stop the current playing music ...
stop();
int32_t idMusic = -1;
// check if music already existed ...
for (size_t iii=0; iii<musicListRead.size(); ++iii) {
if (musicListRead[iii] == NULL) {
continue;
}
if (musicListRead[iii]->getName() == _file) {
idMusic = iii;
break;
}
}
if (idMusic == -1) {
return false;
}
std::unique_lock<std::mutex> lck(localMutex);
musicNextRead = idMusic;
EWOLSA_INFO("Playing track " << musicCurrentRead << " request next : " << idMusic);
return true;
2014-03-18 11:13:00 +01:00
}
bool ewolsa::music::stop(void) {
2014-03-20 10:24:13 +01:00
if (musicCurrentRead == -1) {
EWOLSA_INFO("No current audio is playing");
return false;
}
std::unique_lock<std::mutex> lck(localMutex);
musicNextRead = -1;
return true;
2014-03-18 11:13:00 +01:00
}
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) );
2014-03-20 10:24:13 +01:00
std::unique_lock<std::mutex> lck(localMutex);
2014-03-18 11:13:00 +01:00
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) {
2014-03-20 10:24:13 +01:00
EWOLSA_VERBOSE("Music !!! " << musicCurrentRead << " ... " << musicNextRead << " pos: " << musicPositionReading);
std::unique_lock<std::mutex> lck(localMutex);
if (musicCurrentRead != musicNextRead) {
EWOLSA_DEBUG("change track " << musicCurrentRead << " ==> " << musicNextRead);
// TODO : create fading ....
musicCurrentRead = musicNextRead;
musicPositionReading = 0;
2014-03-18 11:13:00 +01:00
}
2014-03-20 10:24:13 +01:00
if (musicCurrentRead < 0) {
// nothing to play ...
return;
}
if ( musicCurrentRead >= musicListRead.size()
|| musicListRead[musicCurrentRead] == NULL) {
musicCurrentRead = -1;
musicPositionReading = 0;
EWOLSA_ERROR("request read an unexisting audio track ... : " << musicCurrentRead << "/" << musicListRead.size());
return;
}
if (musicListRead[musicCurrentRead]->m_data == NULL) {
return;
}
2014-03-20 10:24:13 +01:00
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;
}
2014-03-18 11:13:00 +01:00
}