diff --git a/src/miniaudioengine.cpp b/src/miniaudioengine.cpp index a0445c9..6e9c1c9 100644 --- a/src/miniaudioengine.cpp +++ b/src/miniaudioengine.cpp @@ -1,15 +1,9 @@ #include "miniaudioengine.h" -#define LPF_BIAS 0.9f /* Higher values means more bias towards the low pass filter (the low pass filter will be more audible). Lower values means more bias towards the echo. Must be between 0 and 1. */ -#define LPF_CUTOFF_FACTOR 80 /* High values = more filter. */ +#define LPF_BIAS 0.9f +#define LPF_CUTOFF_FACTOR 80 +#define HPF_CUTOFF_FACTOR 1 #define LPF_ORDER 8 -//static filterBank m_filterBank[MAX_LAYERS]; -//static ma_node_graph m_nodeGraph[MAX_LAYERS]; -//static soundNode m_soundNode[MAX_LAYERS]; - -static ma_lpf_node g_lpfNode[MAX_AUDIODEVICES]; -static ma_engine m_engine[MAX_AUDIODEVICES]; - MiniAudioEngine::MiniAudioEngine() { for (int i =0; i < MAX_LAYERS; i++) { @@ -22,7 +16,7 @@ MiniAudioEngine::MiniAudioEngine() } } -void MiniAudioEngine::audioDataCallback1(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) +void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) { (void)pInput; (void)pDevice; @@ -33,18 +27,6 @@ void MiniAudioEngine::audioDataCallback1(ma_device* pDevice, void* pOutput, cons } } -void MiniAudioEngine::audioDataCallback2(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 << "2"; - } -} - void MiniAudioEngine::stopEngine() { for (uint i = 0; i < m_devicesSelected; i++) { @@ -69,68 +51,38 @@ bool MiniAudioEngine::startEngine() ma_result MiniAudioEngine::setNodeGraph(int id) { ma_result result; - //ma_node_graph_config nodeGraphConfig = ma_node_graph_config_init(CHANNELS); - //result = ma_node_graph_init(&nodeGraphConfig, NULL, &m_nodeGraph[id]); - //if (result != MA_SUCCESS) { - // cout << "ERROR " << result << ": Failed to initialize node graph."; - // return MA_ERROR; - //} -/* - ma_loshelf2_config losConfig = ma_loshelf2_config_init(FORMAT, CHANNELS, SAMPLE_RATE, 1, 0.5, 83.3); // double gainDB, double shelfSlope, double frequency) - result = ma_loshelf2_init(&losConfig, NULL, &m_filterBank[id].loShelfNode); - if (result != MA_SUCCESS) { - cout << "Error " << result << ": Can not init loShelf node." << endl; - return result; - } - ma_engine m; - ma_node_graph *ng = (ma_node_graph *)(&m_engine[id]); - ma_node *node = ma_node_graph_get_endpoint(ng); - node = ma_engine_get_endpoint(&m_engine[id]); - ma_node_base nodeBase = ng->endpoint; - result = ma_node_attach_output_bus(&m_filterBank[id].loShelfNode, 0, &nodeBase, 0); - //result = ma_node_attach_output_bus(&m_filterBank[id].loShelfNode, 0, ma_engine_get_endpoint(engine), 0); - if (result != MA_SUCCESS) { - cout << "Error " << result << ": Can not attach filter to graph endpoint." << endl; - return result; - }*/ -/* - ma_splitter_node_config splitterConfig = ma_splitter_node_config_init(ma_engine_get_channels(&engine[0])); - result = ma_splitter_node_init(ng, &splitterConfig, NULL, &m_filterBank[layer].outputNode); - if (result != MA_SUCCESS) { - cout << "Can not init splitter node." << endl; - return result; - } - result = ma_node_attach_output_bus(&m_filterBank[layer].loShelfNode, 0, &m_filterBank[layer].outputNode, 0); - if (result != MA_SUCCESS) { - cout << "Can not attach loShelf to output." << endl; - return result; - } - result = ma_node_attach_output_bus(&m_filterBank[layer].outputNode, 0, ma_node_graph_get_endpoint(ng), 0); - if (result != MA_SUCCESS) { - cout << "Can not attach splitter to graph endpoint." << endl; - return result; - } - }*/ - /* Low Pass Filter. */ 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, &g_lpfNode[id]); + result = ma_lpf_node_init(ng, &lpfNodeConfig, NULL, &m_filterBank[id].lpfNode); 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]); - result = ma_node_attach_output_bus(&g_lpfNode[id], 0, endpoint, 0); + // 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); + 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); if (result != MA_SUCCESS) { cout << "ERROR " << result << ": Failed to attach low pass filter node." << endl; return result; } - result = ma_node_set_output_bus_volume(&g_lpfNode[id], 0, LPF_BIAS); + // ToDo: add peak filters + result = ma_node_attach_output_bus(&m_filterBank[id].hpfNode, 0, endpoint, 0); if (result != MA_SUCCESS) { - cout << "ERROR " << result << ": Failed to set volume low pass filter node." << endl; + cout << "ERROR " << result << ": Failed to attach low pass filter node." << endl; return result; } - ma_node_set_state(&g_lpfNode[id], ma_node_state::ma_node_state_started); +/* + result = ma_node_set_state(&m_filterBank[id].lpfNode, ma_node_state::ma_node_state_started); + if (result != MA_SUCCESS) { + cout << "ERROR " << result << ": Failed to set state to filter node." << endl; + return result; + }*/ return (result); } @@ -147,10 +99,7 @@ bool MiniAudioEngine::startDevice(uint *systemId, uint nb) deviceConfig.playback.format = m_resourceManager.config.decodedFormat; deviceConfig.playback.channels = 0; deviceConfig.sampleRate = m_resourceManager.config.decodedSampleRate; - if (internalId == 0) - deviceConfig.dataCallback = audioDataCallback1; - else - deviceConfig.dataCallback = audioDataCallback2; + deviceConfig.dataCallback = audioDataCallback; deviceConfig.pUserData = &m_engine[internalId]; result = ma_device_init(&m_context, &deviceConfig, &m_device[internalId]); if (result != MA_SUCCESS) { @@ -209,7 +158,7 @@ ma_result MiniAudioEngine::getAllAudioDevices() result = ma_context_get_devices(&m_context, &m_pPlaybackDeviceInfos, &m_playbackDeviceCount, NULL, NULL); if (result != MA_SUCCESS) { - cout << "Error" << result << ": Failed to enumerate playback devices." << endl; + cout << "Error " << result << ": Failed to enumerate playback devices." << endl; ma_context_uninit(&m_context); return result; } @@ -224,51 +173,29 @@ 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 if (m_mediaLoaded[layer] == true) { ma_sound_uninit(&m_currentSound[layer]); m_mediaLoaded[layer] = false; } -/* - ma_sound_config soundConfig = ma_sound_config_init(); - soundConfig = ma_sound_config_init(); - soundConfig.pFilePath = file; - soundConfig.pInitialAttachment = &m_filterBank[layer].loShelfNode; - soundConfig.initialAttachmentInputBusIndex = 0; - soundConfig.channelsIn = 0; - soundConfig.channelsOut = CHANNELS; - //soundConfig.monoExpansionMode; - soundConfig.flags = MA_SOUND_FLAG_NO_SPATIALIZATION; - // | MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT; - //| MA_SOUND_FLAG_STREAM | MA_SOUND_FLAG_NO_PITCH - soundConfig.volumeSmoothTimeInPCMFrames = 480; - //soundConfig.initialSeekPointInPCMFrames; - //soundConfig.rangeBegInPCMFrames; - //soundConfig.rangeEndInPCMFrames; - //soundConfig.loopPointBegInPCMFrames; - //soundConfig.loopPointEndInPCMFrames; - //soundConfig.isLooping; - //soundConfig.endCallback; - //soundConfig.pEndCallbackUserData; - - result = ma_sound_init_ex(&m_engine[audioDevice], &soundConfig, &m_currentSound[layer]); - if (result != MA_SUCCESS) { - cout << "Error" << result << ": Failed to load file " << file << endl; - return result; - }*/ result = ma_sound_init_from_file(&m_engine[audioDevice], file, \ MA_SOUND_FLAG_NO_SPATIALIZATION \ - // | MA_SOUND_FLAG_DECODE // | MA_SOUND_FLAG_STREAM // | MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT , NULL, NULL, &m_currentSound[layer]); if (result != MA_SUCCESS) { cout << "Error " << result << ": Failed to load file " << file << endl; return result; } - result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &g_lpfNode[audioDevice], 0); + result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &m_filterBank[audioDevice].lpfNode, 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; @@ -316,10 +243,10 @@ ma_result MiniAudioEngine::printFormatInfo(int layer) ma_result result = ma_sound_get_data_format(&m_currentSound[layer], \ &format, &channels, &sampleRate, NULL, 0); if (result != MA_SUCCESS) { - cout << "Error" << result << ": Failed to get data format " << layer; + cout << "Error " << result << ": Failed to get data format " << layer; cout << endl; } else { - cout << "Layer: " << layer; + cout << "Layer:" << layer << " "; cout << m_currentLayerValues[layer].media.toLatin1().data(); cout << " samples/sec:" << sampleRate << " format:" << format; cout << " channels:" << channels << endl; diff --git a/src/miniaudioengine.h b/src/miniaudioengine.h index 4f24ce7..fec6c07 100644 --- a/src/miniaudioengine.h +++ b/src/miniaudioengine.h @@ -19,23 +19,12 @@ using namespace std; typedef struct { - ma_node_base node; - ma_loshelf2 loShelfNode; - ma_peak2 midLowNode; - ma_peak2 midHighNode; - ma_hishelf2 hiShelfNode; - ma_splitter_node outputNode; + ma_hpf_node hpfNode; + ma_lpf_node lpfNode; + ma_peak_node midLowNode; + ma_peak_node midHighNode; } filterBank; -typedef struct -{ - ma_node_base input; - ma_data_source_node node; - ma_decoder decoder; - filterBank filters; -} soundNode; - - class MiniAudioEngine { friend class libreMediaServerAudio; @@ -45,12 +34,7 @@ public: void stopEngine(); bool startEngine(); bool startDevice(uint *id, uint nb); - static void audioDataCallback1(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); - static void audioDataCallback2(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); - - ma_device m_device[MAX_AUDIODEVICES]; - ma_sound m_currentSound[MAX_LAYERS]; - ma_bool8 m_mediaLoaded[MAX_LAYERS]; + static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); protected: ma_result loadMedia(int layer, char *media, uint audioDevice); @@ -74,7 +58,12 @@ private: ma_device_info* m_pPlaybackDeviceInfos; ma_uint32 m_playbackDeviceCount; ma_uint32 m_devicesSelected; + ma_device m_device[MAX_AUDIODEVICES]; + ma_sound m_currentSound[MAX_LAYERS]; + ma_bool8 m_mediaLoaded[MAX_LAYERS]; layerData m_currentLayerValues[MAX_LAYERS]; + filterBank m_filterBank[MAX_LAYERS]; + ma_engine m_engine[MAX_AUDIODEVICES]; ma_result getAllAudioDevices(); ma_result startContext();