Antigona Release #1
5 changed files with 195 additions and 57 deletions
|
@ -10,6 +10,19 @@
|
|||
#define ENTRY_POINT_COARSE 5
|
||||
#define ENTRY_POINT_FINE 4
|
||||
#define PITCH 7
|
||||
#define LAYER_CHANNELS 9
|
||||
#define VOL1 9
|
||||
#define VOL2 10
|
||||
#define LOW_FREQ 11
|
||||
#define LOW_Q 12
|
||||
#define MIDLOW_FREQ 13
|
||||
#define MIDLOW_Q 14
|
||||
#define MIDLOW_GAIN 15
|
||||
#define MIDHIGH_FREQ 16
|
||||
#define MIDHIGH_Q 17
|
||||
#define MIDHIGH_GAIN 18
|
||||
#define HIGH_FREQ 19
|
||||
#define HIGH_Q 20
|
||||
|
||||
#define LAYER_CHANNELS 21
|
||||
|
||||
#endif // DMXPERSONALITY_H
|
||||
|
|
|
@ -26,10 +26,11 @@ libreMediaServerAudio::libreMediaServerAudio()
|
|||
m_settings = Settings::getInstance();
|
||||
m_settings->readFile();
|
||||
m_ui = m_settings->getShowUi();
|
||||
m_layersQty = m_settings->getLayersNumber();
|
||||
m_dmxSettings = m_settings->getDmxSettings();
|
||||
m_mediaLibrary = new MediaLibrary;
|
||||
m_mediaLibrary->initMediaLibrary();
|
||||
for (int i = 0; i < MAX_LAYERS; i++) {
|
||||
for (uint i = 0; i < m_layersQty; i++) {
|
||||
m_currentMedia[i] = "";
|
||||
m_currentStatus[i] = Status::Iddle;
|
||||
#ifdef NOGUI
|
||||
|
@ -39,24 +40,24 @@ libreMediaServerAudio::libreMediaServerAudio()
|
|||
m_updateUi[i][3] = -1;
|
||||
#endif
|
||||
}
|
||||
m_ola = new olaThread(this, m_settings->getLayersNumber());
|
||||
Q_CHECK_PTR(m_ola);
|
||||
m_ola->blockSignals(true);
|
||||
m_ola->registerUniverse();
|
||||
if (!m_mae.startEngine()) {
|
||||
if (!m_mae.startEngine(m_layersQty)) {
|
||||
cout << "Can not start Audio Engine!" << endl;
|
||||
this->~libreMediaServerAudio();
|
||||
exit(-1);
|
||||
}
|
||||
uint *audioDevList = m_settings->getAudioDeviceId();
|
||||
if (!m_mae.startDevice(audioDevList, m_settings->getAudioDeviceQty())) {
|
||||
cout << "Can not start Audio Device!" << audioDevList << endl;
|
||||
this->~libreMediaServerAudio();
|
||||
exit(-1);
|
||||
}
|
||||
cout << "Core init Complete. Start reading DMX." << endl;
|
||||
m_ola->blockSignals(false);
|
||||
m_ola = new olaThread(this, m_layersQty);
|
||||
Q_CHECK_PTR(m_ola);
|
||||
m_ola->blockSignals(true);
|
||||
m_ola->registerUniverse();
|
||||
#ifdef NOGUI
|
||||
m_ola->start(QThread::TimeCriticalPriority );
|
||||
#endif
|
||||
m_ola->blockSignals(false);
|
||||
cout << "Core init Complete." << endl;
|
||||
}
|
||||
|
||||
libreMediaServerAudio::~libreMediaServerAudio()
|
||||
|
@ -74,7 +75,8 @@ void libreMediaServerAudio::loadMedia(int layer, int folder, int file)
|
|||
if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
|
||||
return;
|
||||
if (QFile::exists(mediaFile)){
|
||||
m_mae.loadMedia(layer, mediaFile.toLatin1().data(), m_dmxSettings.at(layer).audioDevice);
|
||||
m_mae.loadMedia(layer, mediaFile.toLatin1().data(),\
|
||||
m_dmxSettings.at(layer).audioDevice);
|
||||
m_currentMedia[layer] = mediaFile;
|
||||
#ifndef NOGUI
|
||||
if (m_ui)
|
||||
|
@ -138,6 +140,9 @@ void libreMediaServerAudio::dmxInput(int layer, int channel, int value)
|
|||
m_played.append(m_ola->getValue(layer, DMX_FILE));
|
||||
}
|
||||
#endif
|
||||
} else if (channel >= LOW_FREQ) {
|
||||
m_mae.filterParamChanged(layer, m_dmxSettings.at(layer).audioDevice, channel, value);
|
||||
|
||||
}
|
||||
}
|
||||
#ifndef NOGUI
|
||||
|
|
|
@ -57,6 +57,7 @@ private:
|
|||
QList<dmxSetting> m_dmxSettings;
|
||||
bool m_ui;
|
||||
QList<int> m_played;
|
||||
uint m_layersQty;
|
||||
#ifndef NOGUI
|
||||
QTimer *m_refreshUi;
|
||||
libreMediaServerAudioUi *m_lmsUi;
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include "miniaudioengine.h"
|
||||
#define LPF_BIAS 0.9f
|
||||
#define LPF_CUTOFF_FACTOR 80
|
||||
#define HPF_CUTOFF_FACTOR 1
|
||||
#define LPF_ORDER 8
|
||||
#include "dmxPersonality.h"
|
||||
|
||||
MiniAudioEngine::MiniAudioEngine()
|
||||
{
|
||||
for (int i =0; i < MAX_LAYERS; i++) {
|
||||
m_mediaLoaded[i] = false;
|
||||
m_currentLayerValues[i].status = Status::Iddle;
|
||||
m_currentLayerValues[i].pan = 128;
|
||||
m_currentLayerValues[i].pitch = 128;
|
||||
m_currentLayerValues[i].vol = 0;
|
||||
m_currentLayerValues[i].cursor = 0;
|
||||
}
|
||||
}
|
||||
#define LPF_BIAS 0.9f
|
||||
#define FILTER_ORDER 2
|
||||
#define LPF_CUTOFF_FACTOR 2
|
||||
#define HPF_CUTOFF_FACTOR 20
|
||||
|
||||
MiniAudioEngine::MiniAudioEngine() {}
|
||||
|
||||
void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
{
|
||||
(void)pInput;
|
||||
(void)pDevice;
|
||||
ma_result result;
|
||||
result = ma_engine_read_pcm_frames((ma_engine*)pDevice->pUserData, pOutput, frameCount, NULL);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "1";
|
||||
cout << "Error " << result << ": error audio callback.";
|
||||
}
|
||||
}
|
||||
|
||||
void MiniAudioEngine::stopEngine()
|
||||
{
|
||||
for (uint i = 0; i < m_layersQty; i++) {
|
||||
ma_sound_uninit(&m_currentSound[i]);
|
||||
}
|
||||
for (uint i = 0; i < m_devicesSelected; i++) {
|
||||
for (uint j = 0; j < m_layersQty; j++) {
|
||||
ma_hpf_node_uninit(&m_filterBank[i][j].hpf, NULL);
|
||||
ma_lpf_node_uninit(&m_filterBank[i][j].lpf, NULL);
|
||||
ma_peak_node_uninit(&m_filterBank[i][j].mLow, NULL);
|
||||
ma_peak_node_uninit(&m_filterBank[i][j].mHigh, NULL);
|
||||
}
|
||||
ma_engine_uninit(&m_engine[i]);
|
||||
ma_device_uninit(&m_device[i]);
|
||||
}
|
||||
|
@ -37,10 +37,19 @@ void MiniAudioEngine::stopEngine()
|
|||
ma_resource_manager_uninit(&m_resourceManager);
|
||||
}
|
||||
|
||||
bool MiniAudioEngine::startEngine()
|
||||
bool MiniAudioEngine::startEngine(uint layers)
|
||||
{
|
||||
ma_result result;
|
||||
|
||||
m_layersQty = layers;
|
||||
for (uint i =0; i < m_layersQty; i++) {
|
||||
m_mediaLoaded[i] = false;
|
||||
m_currentLayerValues[i].status = Status::Iddle;
|
||||
m_currentLayerValues[i].pan = 128;
|
||||
m_currentLayerValues[i].pitch = 128;
|
||||
m_currentLayerValues[i].vol = 0;
|
||||
m_currentLayerValues[i].cursor = 0;
|
||||
}
|
||||
result = this->startContext();
|
||||
if (result != MA_SUCCESS) return false;
|
||||
result = this->getAllAudioDevices();
|
||||
|
@ -48,41 +57,74 @@ bool MiniAudioEngine::startEngine()
|
|||
return true;
|
||||
}
|
||||
|
||||
ma_result MiniAudioEngine::setNodeGraph(int id) {
|
||||
// lpf -> hpf -> mLow -> mHigh -> engine
|
||||
ma_result MiniAudioEngine::createFilterBank(int id, uint layer)
|
||||
{
|
||||
ma_result result;
|
||||
|
||||
ma_lpf_node_config lpfNodeConfig = ma_lpf_node_config_init(CHANNELS, SAMPLE_RATE, SAMPLE_RATE / LPF_CUTOFF_FACTOR, LPF_ORDER);
|
||||
ma_node_graph *ng = ma_engine_get_node_graph(&m_engine[id]);
|
||||
result = ma_lpf_node_init(ng, &lpfNodeConfig, NULL, &m_filterBank[id].lpfNode);
|
||||
ma_node *endpoint = ma_engine_get_endpoint(&m_engine[id]);
|
||||
filterBank *fb = &m_filterBank[id][layer];
|
||||
|
||||
ma_lpf_node_config lpfConfig = ma_lpf_node_config_init(CHANNELS, SAMPLE_RATE, SAMPLE_RATE / LPF_CUTOFF_FACTOR, FILTER_ORDER);
|
||||
fb->lpfConfig = ma_lpf_config_init(FORMAT, CHANNELS, SAMPLE_RATE, SAMPLE_RATE / LPF_CUTOFF_FACTOR, FILTER_ORDER);
|
||||
result = ma_lpf_node_init(ng, &lpfConfig, NULL, &fb->lpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to initialize low pass filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
ma_node *endpoint = ma_engine_get_endpoint(&m_engine[id]);
|
||||
// ToDo: ampliar dimensión a m_filterBank con las capas
|
||||
ma_hpf_node_config hpfNodeConfig = ma_hpf_node_config_init(CHANNELS, SAMPLE_RATE, SAMPLE_RATE / HPF_CUTOFF_FACTOR, LPF_ORDER);
|
||||
result = ma_hpf_node_init(ng, &hpfNodeConfig, NULL, &m_filterBank[id].hpfNode);
|
||||
ma_hpf_node_config hpfConfig = ma_hpf_node_config_init(CHANNELS, SAMPLE_RATE, HPF_CUTOFF_FACTOR, FILTER_ORDER);
|
||||
fb->hpfConfig = ma_hpf_config_init(FORMAT, CHANNELS, SAMPLE_RATE, HPF_CUTOFF_FACTOR, FILTER_ORDER);
|
||||
result = ma_hpf_node_init(ng, &hpfConfig, NULL, &fb->hpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to initialize high pass filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
result = ma_node_attach_output_bus(&m_filterBank[id].lpfNode, 0, &m_filterBank[id].hpfNode, 0);
|
||||
ma_peak_node_config mLowConfig = ma_peak_node_config_init(CHANNELS, SAMPLE_RATE, 1.0, 5.0, 300); // double gainDB, double q, double frequency);
|
||||
fb->mLowConfig = ma_peak2_config_init(FORMAT, CHANNELS, SAMPLE_RATE, 100.0, 50.0, 1000);
|
||||
result = ma_peak_node_init(ng, &mLowConfig, NULL, &fb->mLow);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to initialize peak low filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
ma_peak_node_config mHighConfig = ma_peak_node_config_init(CHANNELS, SAMPLE_RATE, 0.0, 0.0, 1000); // double gainDB, double q, double frequency);
|
||||
fb->mHighConfig = ma_peak2_config_init(FORMAT, CHANNELS, SAMPLE_RATE, 0.0, 0.0, 220);
|
||||
result = ma_peak_node_init(ng, &mHighConfig, NULL, &fb->mHigh);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to initialize peak high filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
result = ma_node_attach_output_bus(&fb->lpf, 0, &fb->hpf, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to attach low pass filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
// ToDo: add peak filters
|
||||
result = ma_node_attach_output_bus(&m_filterBank[id].hpfNode, 0, endpoint, 0);
|
||||
result = ma_node_attach_output_bus(&fb->hpf, 0, &fb->mLow, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to attach low pass filter node." << endl;
|
||||
cout << "ERROR " << result << ": Failed to attach Mid Low pass filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
result = ma_node_set_state(&m_filterBank[id].lpfNode, ma_node_state::ma_node_state_started);
|
||||
result = ma_node_attach_output_bus(&fb->mLow, 0, &fb->mHigh, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set state to filter node." << endl;
|
||||
cout << "ERROR " << result << ": Failed to attach high peaks filter node." << endl;
|
||||
return result;
|
||||
}*/
|
||||
}
|
||||
result = ma_node_attach_output_bus(&fb->mHigh, 0, endpoint, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to attach high peaks filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ma_result MiniAudioEngine::setNodeGraph(int id) {
|
||||
ma_result result = MA_SUCCESS;
|
||||
uint i = 0;
|
||||
|
||||
while (result == MA_SUCCESS && i < m_layersQty) {
|
||||
result = this->createFilterBank(id, i);
|
||||
i++;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
@ -174,8 +216,11 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file, uint audioDevice)
|
|||
ma_result result;
|
||||
|
||||
// ToDo: ver si s puede attach dos dispositivos a la vez. si no:
|
||||
// enchufar a un splitter al sonido y attach cada uno de los lados.
|
||||
// iniciar un sonido por cada capa
|
||||
// - enchufar a un splitter al sonido y attach cada uno de los lados.
|
||||
// - iniciar un sonido por cada capa, copiar la capa en otro dispositivo
|
||||
// - splitter al final de filterBank, esas señales se mezclan en un nodo mudo
|
||||
// y se escribe la mezcla en un buffer. Mezclar el buffer en disco con el
|
||||
// del otro device en el audio callback .
|
||||
if (m_mediaLoaded[layer] == true)
|
||||
{
|
||||
ma_sound_uninit(&m_currentSound[layer]);
|
||||
|
@ -188,14 +233,11 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file, uint audioDevice)
|
|||
cout << "Error " << result << ": Failed to load file " << file << endl;
|
||||
return result;
|
||||
}
|
||||
result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &m_filterBank[audioDevice].lpfNode, 0);
|
||||
result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &m_filterBank[audioDevice][layer].lpf, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "Error " << result << ": Failed to attach output bus " << audioDevice << endl;
|
||||
//return result;
|
||||
}
|
||||
// ToDo: ampliar dimensión a m_filterBank con las capas
|
||||
// attach las capas en los dispositivos
|
||||
// master cada capa? al principio o final del filtro?
|
||||
m_mediaLoaded[layer] = true;
|
||||
this->refreshValues(layer);
|
||||
m_currentLayerValues[layer].media = file;
|
||||
|
@ -357,3 +399,71 @@ void MiniAudioEngine::refreshValues(int layer)
|
|||
this->pitchChanged(layer, m_currentLayerValues[layer].pitch);
|
||||
this->playbackChanged(layer, m_currentLayerValues[layer].status);
|
||||
}
|
||||
|
||||
ma_result MiniAudioEngine::filterParamChanged(int layer, int audioDevice, int channel, int value)
|
||||
{
|
||||
ma_result result = MA_SUCCESS;
|
||||
|
||||
filterBank *fb = &m_filterBank[audioDevice][layer];
|
||||
|
||||
if (channel == LOW_FREQ) {
|
||||
fb->hpfConfig.cutoffFrequency = (value * 2) + 20;
|
||||
result = ma_hpf_node_reinit(&fb->hpfConfig, &fb->hpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set frecuency Low filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
} else if (channel == HIGH_FREQ) {
|
||||
fb->lpfConfig.cutoffFrequency = 22000 - (value * 80);
|
||||
result = ma_lpf_node_reinit(&fb->lpfConfig, &fb->lpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set frecuency High filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
} else if (channel == MIDLOW_FREQ) {
|
||||
fb->mLowConfig.frequency = 60 + (value * 4);
|
||||
result = ma_peak_node_reinit(&fb->mLowConfig, &fb->mLow);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set frecuency Mid Low pass filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
cout << "frec " << fb->mLowConfig.frequency << endl;
|
||||
} else if (channel == MIDLOW_Q) {
|
||||
fb->mLowConfig.q = (double)( value / 32.0f) + 0.50;
|
||||
result = ma_peak_node_reinit(&fb->mLowConfig, &fb->mLow);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set Q Mid Low filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
cout << "Q " << fb->mLowConfig.q << endl;
|
||||
} else if (channel == MIDLOW_GAIN) {
|
||||
fb->mLowConfig.gainDB = (double)(value / 8.0f) - 16.0f;
|
||||
result = ma_peak_node_reinit(&fb->mLowConfig, &fb->mLow);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set gain Mid Low filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
} else if (channel == MIDHIGH_FREQ) {
|
||||
fb->mHighConfig.frequency = 400 + (value * 32);
|
||||
result = ma_peak_node_reinit(&fb->mHighConfig, &fb->mHigh);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set frecuency Mid High filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
} else if (channel == MIDHIGH_Q) {
|
||||
fb->mHighConfig.q = (double)( value / 32.0f) + 0.50;
|
||||
result = ma_peak_node_reinit(&fb->mHighConfig, &fb->mHigh);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set Q Mid High filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
} else if (channel == MIDHIGH_GAIN) {
|
||||
fb->mHighConfig.gainDB = (double)(value / 8.0f) - 16.0f;
|
||||
result = ma_peak_node_reinit(&fb->mHighConfig, &fb->mHigh);
|
||||
if (result != MA_SUCCESS) {
|
||||
cout << "ERROR " << result << ": Failed to set gain Mid High filter node." << endl;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
|
@ -19,12 +19,18 @@ using namespace std;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
ma_hpf_node hpfNode;
|
||||
ma_lpf_node lpfNode;
|
||||
ma_peak_node midLowNode;
|
||||
ma_peak_node midHighNode;
|
||||
ma_hpf_node hpf;
|
||||
ma_hpf_config hpfConfig;
|
||||
ma_lpf_node lpf;
|
||||
ma_lpf_config lpfConfig;
|
||||
ma_peak_node mLow;
|
||||
ma_peak_config mLowConfig;
|
||||
ma_peak_node mHigh;
|
||||
ma_notch_node notch;
|
||||
ma_peak_config mHighConfig;
|
||||
} filterBank;
|
||||
|
||||
|
||||
class MiniAudioEngine
|
||||
{
|
||||
friend class libreMediaServerAudio;
|
||||
|
@ -32,7 +38,7 @@ class MiniAudioEngine
|
|||
public:
|
||||
MiniAudioEngine();
|
||||
void stopEngine();
|
||||
bool startEngine();
|
||||
bool startEngine(uint layersQty);
|
||||
bool startDevice(uint *id, uint nb);
|
||||
static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
|
||||
|
||||
|
@ -50,6 +56,7 @@ protected:
|
|||
inline float getVol(int layer) {
|
||||
return ma_sound_get_volume(&m_currentSound[layer]); }
|
||||
inline bool getAtEnd(int layer) { return m_currentSound[layer].atEnd; }
|
||||
ma_result filterParamChanged(int layer, int audioDevice, int channel, int value);
|
||||
|
||||
private:
|
||||
ma_resource_manager_config m_resourceManagerConfig;
|
||||
|
@ -62,14 +69,16 @@ private:
|
|||
ma_sound m_currentSound[MAX_LAYERS];
|
||||
ma_bool8 m_mediaLoaded[MAX_LAYERS];
|
||||
layerData m_currentLayerValues[MAX_LAYERS];
|
||||
filterBank m_filterBank[MAX_LAYERS];
|
||||
filterBank m_filterBank[MAX_AUDIODEVICES][MAX_LAYERS];
|
||||
ma_engine m_engine[MAX_AUDIODEVICES];
|
||||
uint m_layersQty;
|
||||
|
||||
ma_result getAllAudioDevices();
|
||||
ma_result startContext();
|
||||
void refreshValues(int layer);
|
||||
ma_result seekToCursor(int layer, int cursor);
|
||||
ma_result setNodeGraph(int id);
|
||||
ma_result createFilterBank(int id, uint layer);
|
||||
};
|
||||
|
||||
#endif // MINIAUDIOENGINE_H
|
||||
|
|
Loading…
Add table
Reference in a new issue