[DEV] set output in float processing mode

This commit is contained in:
Edouard DUPIN 2016-09-27 22:32:32 +02:00
parent 0359b59b8e
commit fda145c415
7 changed files with 74 additions and 71 deletions

View File

@ -31,7 +31,7 @@ namespace audio {
int32_t m_nbSamples;
int32_t m_nbChanRequested;
int32_t m_requestedTime;
std::vector<int16_t> m_data;
std::vector<float> m_data;
public:
const std::string& getName() {
return m_file;

View File

@ -46,7 +46,8 @@ static long localTellFunc(void *datasource) {
return file->fileTell();
}
std::vector<int16_t> audio::ess::ogg::loadAudioFile(const std::string& _filename, int8_t _nbChan) {
std::vector<float> audio::ess::ogg::loadAudioFile(const std::string& _filename, int8_t _nbChan) {
std::vector<float> out;
OggVorbis_File vf;
int32_t eof=0;
int32_t current_section;
@ -61,20 +62,20 @@ std::vector<int16_t> audio::ess::ogg::loadAudioFile(const std::string& _filename
//EWOLSA_DEBUG("open file (OGG) \"" << fileAccess << "\"");
if (false == fileAccess->exist()) {
EWOLSA_ERROR("File Does not exist : \"" << *fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
int32_t fileSize = fileAccess->fileSize();
if (0 == fileSize) {
EWOLSA_ERROR("This file is empty : \"" << *fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
if (false == fileAccess->fileOpenRead()) {
EWOLSA_ERROR("Can not open the file : \"" << *fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
if (ov_open_callbacks(&(*fileAccess), &vf, nullptr, 0, tmpCallback) < 0) {
EWOLSA_ERROR("Input does not appear to be an Ogg bitstream.");
return std::vector<int16_t>();
return out;
}
vorbis_info *vi=ov_info(&vf,-1);
int32_t nbSampleOut = ov_pcm_total(&vf,-1) / vi->channels;
@ -91,8 +92,7 @@ std::vector<int16_t> audio::ess::ogg::loadAudioFile(const std::string& _filename
EWOLSA_DEBUG("time: " << ((float)_nbSampleOut/(float)vi->rate)/60.0);
}
*/
std::vector<int16_t> outputData;
outputData.resize(nbSampleOut*_nbChan, 0);
out.resize(nbSampleOut*_nbChan, 0);
int32_t pos = 0;
char pcmout[4096];
while(!eof){
@ -104,26 +104,29 @@ std::vector<int16_t> audio::ess::ogg::loadAudioFile(const std::string& _filename
if(ret==OV_EBADLINK){
//EWOLSA_ERROR("Corrupt bitstream section! Exiting.");
// TODO : Remove pointer data ...
return std::vector<int16_t>();
return out;
}
} else {
int16_t* pointerIn = (int16_t*)pcmout;
int16_t* pointerOut = &outputData[0]+pos;
float* pointerOut = &out[0]+pos;
if (_nbChan == vi->channels) {
memcpy(pointerOut, pointerIn, ret);
// 1/32768 = 0.00003051757f
for (int32_t iii=0; iii<ret/2; ++iii) {
pointerOut[iii] = float(pointerIn[iii]) * 0.00003051757f;
}
pos += ret/2;
} else {
if ( _nbChan == 1
&& vi->channels == 2) {
for (int32_t iii=0; iii<ret/4 ; ++iii) {
pointerOut[iii] = pointerIn[iii*2];
pointerOut[iii] = float(pointerIn[iii*2]) * 0.00003051757f;
}
pos += ret/4;
} else if ( _nbChan == 2
&& vi->channels == 1) {
for (int32_t iii=0; iii<ret/2 ; ++iii) {
pointerOut[iii*2] = pointerIn[iii];
pointerOut[iii*2+1] = pointerIn[iii];
pointerOut[iii*2] = float(pointerIn[iii]) * 0.00003051757f;
pointerOut[iii*2+1] = float(pointerIn[iii]) * 0.00003051757f;
}
pos += ret;
} else {
@ -137,6 +140,6 @@ std::vector<int16_t> audio::ess::ogg::loadAudioFile(const std::string& _filename
// cleanup
ov_clear(&vf);
//EWOLSA_DEBUG("Done.");
return outputData;
return out;
}

View File

@ -10,7 +10,7 @@
namespace audio {
namespace ess {
namespace ogg {
std::vector<int16_t> loadAudioFile(const std::string& _filename, int8_t _nbChan);
std::vector<float> loadAudioFile(const std::string& _filename, int8_t _nbChan);
}
}

View File

@ -57,7 +57,8 @@ typedef struct {
#define COMPR_G721 (64)
#define COMPR_MPEG (80)
std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename, int8_t _nbChan) {
std::vector<float> audio::ess::wav::loadAudioFile(const std::string& _filename, int8_t _nbChan) {
std::vector<float> out;
waveHeader myHeader;
memset(&myHeader, 0, sizeof(waveHeader));
etk::FSNode fileAccess(_filename);
@ -66,28 +67,28 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
if (false == fileAccess.exist()) {
EWOLSA_ERROR("File Does not exist : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
int32_t fileSize = fileAccess.fileSize();
if (0 == fileSize) {
EWOLSA_ERROR("This file is empty : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
if (false == fileAccess.fileOpenRead()) {
EWOLSA_ERROR("Can not open the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
// 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 std::vector<int16_t>();
return out;
}
// ----------------------------------------------
// read the header :
// ----------------------------------------------
if (fileAccess.fileRead(&myHeader.riffTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
bool littleEndien = false;
if( myHeader.riffTag[0] == 'R'
@ -99,55 +100,55 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
}
} else {
EWOLSA_ERROR("file: \"" << fileAccess << "\" Does not start with \"RIF\" " );
return std::vector<int16_t>();
return out;
}
// 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 std::vector<int16_t>();
return out;
}
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 std::vector<int16_t>();
return out;
}
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 std::vector<int16_t>();
return out;
}
// get the data size :
if (fileAccess.fileRead(&myHeader.fmtTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
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 std::vector<int16_t>();
return out;
}
// get the data size :
if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
myHeader.waveFormatSize = CONVERT_UINT32(littleEndien, tmpData);
if (myHeader.waveFormatSize != 16) {
EWOLSA_ERROR("file : \"" << fileAccess << "\" == > header error ...");
return std::vector<int16_t>();
return out;
}
if (fileAccess.fileRead(tmpData, 1, 16)!=16) {
EWOLSA_ERROR("Can not 16 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
unsigned char * tmppp = tmpData;
myHeader.waveFormat.type = CONVERT_UINT16(littleEndien, tmppp);
@ -171,19 +172,19 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
// get the data size :
if (fileAccess.fileRead(&myHeader.dataTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
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 std::vector<int16_t>();
return out;
}
// get the data size :
if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return std::vector<int16_t>();
return out;
}
myHeader.dataSize = CONVERT_UINT32(littleEndien, tmpData);
@ -194,30 +195,29 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
//Parse the data and transform it if needed ...
if (COMPR_PCM != myHeader.waveFormat.type) {
EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only PCM compression ...");
return std::vector<int16_t>();
return out;
}
if (myHeader.waveFormat.channelCount == 0 || myHeader.waveFormat.channelCount>2) {
EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only mono or stereo ..." << myHeader.waveFormat.channelCount);
return std::vector<int16_t>();
return out;
}
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 std::vector<int16_t>();
return out;
}
if( ! ( 44100 == myHeader.waveFormat.samplesPerSec
|| 48000 == myHeader.waveFormat.samplesPerSec) ) {
EWOLSA_ERROR("File : \"" << fileAccess << "\" == > not supported frequency " << myHeader.waveFormat.samplesPerSec << " != 48000");
return std::vector<int16_t>();
return out;
}
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;
std::vector<int16_t> outputData;
outputData.resize(outputSize, 0);
int16_t * tmpOut = &outputData[0];
out.resize(outputSize, 0);
float * tmpOut = &out[0];
for( int32_t iii=0; iii<nbSample; iii++) {
int32_t left;
int32_t right;
@ -226,14 +226,14 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 2)!=2) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = ((int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample))) << 16;
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = (int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample)) << 16;
right = (int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample+2)) << 16;
@ -242,14 +242,14 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 3)!=3) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = CONVERT_INT24(littleEndien, audioSample);
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 6)!=6) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = CONVERT_INT24(littleEndien, audioSample);
right = CONVERT_INT24(littleEndien, audioSample+3);
@ -258,29 +258,30 @@ std::vector<int16_t> audio::ess::wav::loadAudioFile(const std::string& _filename
if (myHeader.waveFormat.channelCount == 1) {
if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = CONVERT_INT32(littleEndien, audioSample);
right = left;
} else {
if (fileAccess.fileRead(audioSample, 1, 8)!=8) {
EWOLSA_ERROR("Read Error at position : " << iii);
return std::vector<int16_t>();
return out;
}
left = CONVERT_INT32(littleEndien, audioSample);
right = CONVERT_INT32(littleEndien, audioSample+4);
}
}
// 1/32768 = 0.00003051757f
if (_nbChan == 1) {
*tmpOut++ = (int16_t)(((left>>1) + (right>>1))>>16);
*tmpOut++ = float(((left>>1) + (right>>1))>>16) * 0.00003051757f;
} else {
*tmpOut++ = (int16_t)(left>>16);
*tmpOut++ = (int16_t)(right>>16);
*tmpOut++ = float(left>>16) * 0.00003051757f;
*tmpOut++ = float(right>>16) * 0.00003051757f;
}
}
// close the file:
fileAccess.fileClose();
return outputData;
return out;
}

View File

@ -10,7 +10,7 @@
namespace audio {
namespace ess {
namespace wav {
std::vector<int16_t> loadAudioFile(const std::string& _filename, int8_t _nbChan);
std::vector<float> loadAudioFile(const std::string& _filename, int8_t _nbChan);
}
}
}

View File

@ -20,7 +20,7 @@ audio::ess::Effects::Effects(const ememory::SharedPtr<audio::river::Manager>& _m
channelMap.push_back(audio::channel_frontCenter);
m_interface = m_manager->createOutput(48000,
channelMap,
audio::format_int16,
audio::format_float,
"speaker");
if (m_interface == nullptr) {
EWOLSA_ERROR("can not allocate output interface ... ");
@ -51,19 +51,18 @@ audio::ess::Effects::~Effects() {
}
static bool playData(const ememory::SharedPtr<audio::ess::LoadedFile>& _file, int32_t& _position, int16_t* _bufferInterlace, int32_t _nbSample) {
static bool playData(const ememory::SharedPtr<audio::ess::LoadedFile>& _file, int32_t& _position, float* _bufferInterlace, int32_t _nbSample) {
if ( _file == nullptr
|| _file->m_data.size() == 0) {
return true;
}
int32_t processTimeMax = std::min(_nbSample, _file->m_nbSamples - _position);
processTimeMax = std::max(0, processTimeMax);
int16_t * pointer = _bufferInterlace;
const int16_t * newData = &_file->m_data[_position];
float * pointer = _bufferInterlace;
const float * newData = &_file->m_data[_position];
//EWOLSA_DEBUG("AUDIO : Play slot... nb sample : " << processTimeMax << " playTime=" <<m_playTime << " nbCannels=" << nbChannels);
for (int32_t iii=0; iii<processTimeMax; iii++) {
int32_t tmppp = int32_t(*_bufferInterlace) + int32_t(*newData);
*_bufferInterlace = std::avg(-32767, tmppp, 32766);
*_bufferInterlace += *newData;
//EWOLSA_DEBUG("AUDIO : element : " << *pointer);
_bufferInterlace++;
newData++;
@ -77,18 +76,18 @@ static bool playData(const ememory::SharedPtr<audio::ess::LoadedFile>& _file, in
}
void audio::ess::Effects::onDataNeeded(void* _data,
const audio::Time& _playTime,
const size_t& _nbChunk,
enum audio::format _format,
uint32_t _sampleRate,
const std::vector<audio::channel>& _map){
if (_format != audio::format_int16) {
EWOLSA_ERROR("call wrong type ... (need int16_t)");
const audio::Time& _playTime,
const size_t& _nbChunk,
enum audio::format _format,
uint32_t _sampleRate,
const std::vector<audio::channel>& _map){
if (_format != audio::format_float) {
EWOLSA_ERROR("call wrong type ... (need float)");
}
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_playing.begin();
while (it != m_playing.end()) {
bool ret = playData((*it).first, (*it).second, static_cast<int16_t*>(_data), _nbChunk);
bool ret = playData((*it).first, (*it).second, static_cast<float*>(_data), _nbChunk);
if (ret == true) {
it = m_playing.erase(it);
} else {

View File

@ -22,7 +22,7 @@ audio::ess::Music::Music(const ememory::SharedPtr<audio::river::Manager>& _manag
channelMap.push_back(audio::channel_frontRight);
m_interface = m_manager->createOutput(48000,
channelMap,
audio::format_int16,
audio::format_float,
"speaker");
if (m_interface == nullptr) {
EWOLSA_ERROR("can not allocate output interface ... ");
@ -60,8 +60,8 @@ void audio::ess::Music::onDataNeeded(void* _data,
enum audio::format _format,
uint32_t _sampleRate,
const std::vector<audio::channel>& _map){
if (_format != audio::format_int16) {
EWOLSA_ERROR("call wrong type ... (need int16_t)");
if (_format != audio::format_float) {
EWOLSA_ERROR("call wrong type ... (need float)");
}
std::unique_lock<std::mutex> lock(m_mutex);
if (m_current != m_next) {
@ -78,8 +78,8 @@ void audio::ess::Music::onDataNeeded(void* _data,
}
int32_t processTimeMax = std::min(int32_t(_nbChunk*_map.size()), int32_t(m_current->m_nbSamples - m_position));
processTimeMax = std::max(0, processTimeMax);
int16_t * pointer = static_cast<int16_t*>(_data);
int16_t * newData = &m_current->m_data[m_position];
float * pointer = static_cast<float*>(_data);
float * newData = &m_current->m_data[m_position];
EWOLSA_VERBOSE("AUDIO : Play slot... nb sample : " << processTimeMax << " map=" << _map << " _nbChunk=" << _nbChunk);
for (int32_t iii=0; iii<processTimeMax; iii++) {
*pointer++ = *newData++;