prototipo de filtro funcionando, muy sucio.

This commit is contained in:
snt 2024-05-12 23:23:26 +02:00
parent 8c69da5f9d
commit 7cd4c8fbd8
6 changed files with 276 additions and 98 deletions

View file

@ -29,24 +29,21 @@ v 0.2.0 Antígona (26/05/2024)
- Play all medias found in one folder. - Play all medias found in one folder.
- Play all medias in one folder consecutevily. - Play all medias in one folder consecutevily.
- Play all medias in one folder randomly. - Play all medias in one folder randomly.
+ Multi audio devices output.
v 0.1.3 Leúcade (19/04/2024) v 0.1.3 Leúcade (19/04/2024)
+ Ubuntu 22.04 jammy. + Ubuntu 22.04 jammy.
+ Qt 5.15.3. + Qt 5.15.3.
+ Pitch. + Pitch.
+ Loop. + Loop.
v 0.1.2 Mayordomo (12/08/2015) v 0.1.2 Mayordomo (12/08/2015)
+ GUI config.
- GUI config. + Variable layers.
- Several bugs tested in real world. + SFML as audio engine.
- Variable layers.
- SFML as audio engine.
v 0.1.1 Pascual (24/09/2014) v 0.1.1 Pascual (24/09/2014)
+ First Version: 4 layers playing .ogg. + First Version: 4 layers playing .ogg.
+ Needs Open Lighting Arquitecture => 0.9.0. + Needs Open Lighting Arquitecture => 0.9.0.
+ Pure Data as audio engine. + Pure Data as audio engine.
+ Qt4

View file

@ -25,7 +25,6 @@ v 0.2.2
- Octopus Sound Card support (6 outputs - 8 inputs). - Octopus Sound Card support (6 outputs - 8 inputs).
v 0.2.1 v 0.2.1
- Multi devices output.
- mute/panic on layer. - mute/panic on layer.
- Master Bus Layer: - Master Bus Layer:
- each layer will have one "Gain" prefader that acts in source, "Vol" in v 1.3. - each layer will have one "Gain" prefader that acts in source, "Vol" in v 1.3.
@ -46,6 +45,7 @@ v 0.2.1
- ¿Exit Point? is it needed? - ¿Exit Point? is it needed?
- Hardening: check return errors, try/catch exceptions, i'm too happy.... - Hardening: check return errors, try/catch exceptions, i'm too happy....
- Tests: errors on wrong conf file. - Tests: errors on wrong conf file.
- Ui/Ux: seek cursor playback
v0.2.0: v0.2.0:
- Vumeter or indicator about audio output in layer and master, add to sliderGroup. - Vumeter or indicator about audio output in layer and master, add to sliderGroup.

View file

@ -43,11 +43,16 @@ libreMediaServerAudio::libreMediaServerAudio()
Q_CHECK_PTR(m_ola); Q_CHECK_PTR(m_ola);
m_ola->blockSignals(true); m_ola->blockSignals(true);
m_ola->registerUniverse(); m_ola->registerUniverse();
m_mae.startEngine(); if (!m_mae.startEngine()) {
cout << "Can not start Audio Engine!" << endl;
this->~libreMediaServerAudio();
}
uint *audioDevList = m_settings->getAudioDeviceId(); uint *audioDevList = m_settings->getAudioDeviceId();
for (uint i = 0; i < m_settings->getAudioDeviceQty(); i++) if (!m_mae.startDevice(audioDevList, m_settings->getAudioDeviceQty())) {
m_mae.startDevice(audioDevList[i], i); cout << "Can not start Audio Device!" << audioDevList << endl;
qDebug("Core init Complete. Start reading DMX."); this->~libreMediaServerAudio();
}
cout << "Core init Complete. Start reading DMX." << endl;
m_ola->blockSignals(false); m_ola->blockSignals(false);
#ifdef NOGUI #ifdef NOGUI
m_ola->start(QThread::TimeCriticalPriority ); m_ola->start(QThread::TimeCriticalPriority );
@ -58,6 +63,9 @@ libreMediaServerAudio::~libreMediaServerAudio()
{ {
m_ola->stop(); m_ola->stop();
m_mae.stopEngine(); m_mae.stopEngine();
sleep(1);
cout << "bye!" << endl;
exit(0);
} }
void libreMediaServerAudio::loadMedia(int layer, int folder, int file) void libreMediaServerAudio::loadMedia(int layer, int folder, int file)

View file

@ -20,6 +20,10 @@
#ifndef LIBREMEDIASERVERAUDIO_H #ifndef LIBREMEDIASERVERAUDIO_H
#define LIBREMEDIASERVERAUDIO_H #define LIBREMEDIASERVERAUDIO_H
#include <bits/stdc++.h>
using namespace std;
#include "medialibrary.h" #include "medialibrary.h"
#include "miniaudioengine.h" #include "miniaudioengine.h"
#include "olathread.h" #include "olathread.h"

View file

@ -1,5 +1,15 @@
#include "miniaudioengine.h" #include "miniaudioengine.h"
#include <iostream> //enum macro #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_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() MiniAudioEngine::MiniAudioEngine()
{ {
for (int i =0; i < MAX_LAYERS; i++) { for (int i =0; i < MAX_LAYERS; i++) {
@ -12,19 +22,37 @@ MiniAudioEngine::MiniAudioEngine()
} }
} }
void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) void MiniAudioEngine::audioDataCallback1(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{ {
(void)pInput; (void)pInput;
//Do master audio processing before sending to device. (void)pDevice;
ma_engine_read_pcm_frames((ma_engine*)pDevice->pUserData, pOutput, frameCount, NULL); ma_result result;
result = ma_engine_read_pcm_frames((ma_engine*)pDevice->pUserData, pOutput, frameCount, NULL);
if (result != MA_SUCCESS) {
cout << "1";
}
}
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() void MiniAudioEngine::stopEngine()
{ {
ma_engine_uninit(&engine[0]); for (uint i = 0; i < m_devicesSelected; i++) {
ma_device_uninit(&device[0]); ma_engine_uninit(&m_engine[i]);
ma_context_uninit(&context); ma_device_uninit(&m_device[i]);
ma_resource_manager_uninit(&resourceManager); }
ma_context_uninit(&m_context);
ma_resource_manager_uninit(&m_resourceManager);
} }
bool MiniAudioEngine::startEngine() bool MiniAudioEngine::startEngine()
@ -32,66 +60,144 @@ bool MiniAudioEngine::startEngine()
ma_result result; ma_result result;
result = this->startContext(); result = this->startContext();
if (result != MA_SUCCESS) return result; if (result != MA_SUCCESS) return false;
result = this->getAllAudioDevices(); result = this->getAllAudioDevices();
return result; if (result != MA_SUCCESS) return false;
return true;
} }
ma_result MiniAudioEngine::startDevice(uint systemId, uint internalId) ma_result MiniAudioEngine::setNodeGraph(int id) {
{
ma_result result; 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]);
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);
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);
if (result != MA_SUCCESS) {
cout << "ERROR " << result << ": Failed to set volume low pass filter node." << endl;
return result;
}
ma_node_set_state(&g_lpfNode[id], ma_node_state::ma_node_state_started);
return (result);
}
bool MiniAudioEngine::startDevice(uint *systemId, uint nb)
{
ma_result result = MA_SUCCESS;
ma_device_config deviceConfig; ma_device_config deviceConfig;
ma_engine_config engineConfig; ma_engine_config engineConfig;
if (systemId >= playbackDeviceCount) m_devicesSelected = nb;
systemId = playbackDeviceCount - 1; for (uint internalId = 0; internalId < nb; internalId++) {
deviceConfig = ma_device_config_init(ma_device_type_playback); deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.pDeviceID = &pPlaybackDeviceInfos[systemId].id; deviceConfig.playback.pDeviceID = &m_pPlaybackDeviceInfos[systemId[internalId]].id;
deviceConfig.playback.format = resourceManager.config.decodedFormat; deviceConfig.playback.format = m_resourceManager.config.decodedFormat;
deviceConfig.playback.channels = 0; deviceConfig.playback.channels = 0;
deviceConfig.sampleRate = resourceManager.config.decodedSampleRate; deviceConfig.sampleRate = m_resourceManager.config.decodedSampleRate;
deviceConfig.dataCallback = audioDataCallback; if (internalId == 0)
deviceConfig.pUserData = &engine[internalId]; deviceConfig.dataCallback = audioDataCallback1;
result = ma_device_init(&context, &deviceConfig, &device[internalId]); else
if (result != MA_SUCCESS) { deviceConfig.dataCallback = audioDataCallback2;
qCritical("Failed to initialize audio device %s.", pPlaybackDeviceInfos[systemId].name); deviceConfig.pUserData = &m_engine[internalId];
return result; result = ma_device_init(&m_context, &deviceConfig, &m_device[internalId]);
if (result != MA_SUCCESS) {
cout << "Error " << result << ": Failed to initialize audio device " << m_pPlaybackDeviceInfos[*systemId].name << endl;
return false;
}
engineConfig = ma_engine_config_init();
engineConfig.pDevice = &m_device[internalId];
engineConfig.pResourceManager = &m_resourceManager;
engineConfig.noAutoStart = MA_TRUE;
result = ma_engine_init(&engineConfig, &m_engine[internalId]);
if (result != MA_SUCCESS) {
cout << "Error " << result << ": Failed to initialize audio engine" << endl;
return false;
}
result = this->setNodeGraph(internalId);
if (result != MA_SUCCESS) {
cout << "Error " << result << ": Failed to set node graph " << systemId[internalId] << endl;
return false;
}
result = ma_engine_start(&m_engine[internalId]);
if (result != MA_SUCCESS) {
cout << "Error " << result << ": Failed to start audio engine" << systemId[internalId] << endl;
return false;
}
cout << "Initialized Audio Device. internalId: " << internalId << " systemId: " << systemId[internalId] << " " << m_pPlaybackDeviceInfos[systemId[internalId]].name << endl;
} }
engineConfig = ma_engine_config_init(); return true;
engineConfig.pDevice = &device[internalId];
engineConfig.pResourceManager = &resourceManager;
engineConfig.noAutoStart = MA_TRUE;
result = ma_engine_init(NULL, &engine[internalId]);
if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio engine.");
return result;
}
result = ma_engine_start(&engine[internalId]);
if (result != MA_SUCCESS) {
qCritical("Failed to start audio engine %i.", systemId);
return result;
}
qInfo("Initialized audio device internal: %ui system: %d %s", internalId, systemId, pPlaybackDeviceInfos[systemId].name);
return result;
} }
ma_result MiniAudioEngine::startContext() ma_result MiniAudioEngine::startContext()
{ {
ma_result result; ma_result result;
resourceManagerConfig = ma_resource_manager_config_init(); m_resourceManagerConfig = ma_resource_manager_config_init();
resourceManagerConfig.decodedFormat = ma_format_f32; /* ma_format_f32 should almost always be used as that's what the engine (and most everything else) uses for mixing. */ m_resourceManagerConfig.decodedFormat = FORMAT;
resourceManagerConfig.decodedChannels = 0; m_resourceManagerConfig.decodedChannels = CHANNELS;
resourceManagerConfig.decodedSampleRate = ma_standard_sample_rate_44100; m_resourceManagerConfig.decodedSampleRate = SAMPLE_RATE;
resourceManagerConfig.jobThreadCount = 4; m_resourceManagerConfig.jobThreadCount = 4;
result = ma_resource_manager_init(&resourceManagerConfig, &resourceManager); result = ma_resource_manager_init(&m_resourceManagerConfig, &m_resourceManager);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio resource manager."); cout << "Error " << result << ": Failed to initialize audio resource manager." << endl;
return result; return result;
} }
result = ma_context_init(NULL, 0, NULL, &context); result = ma_context_init(NULL, 0, NULL, &m_context);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio context."); cout << "Error " << result << ": Failed to initialize audio context." << endl;
} }
return result; return result;
} }
@ -101,15 +207,15 @@ ma_result MiniAudioEngine::getAllAudioDevices()
{ {
ma_result result; ma_result result;
result = ma_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, NULL, NULL); result = ma_context_get_devices(&m_context, &m_pPlaybackDeviceInfos, &m_playbackDeviceCount, NULL, NULL);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qWarning("Failed to enumerate playback devices.\n"); cout << "Error" << result << ": Failed to enumerate playback devices." << endl;
ma_context_uninit(&context); ma_context_uninit(&m_context);
return result; return result;
} }
printf("Audio devices available:\n"); cout << "Audio devices available:" << endl;
for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < playbackDeviceCount; iAvailableDevice += 1) { for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < m_playbackDeviceCount; iAvailableDevice += 1) {
qInfo("%d: : %s", iAvailableDevice, pPlaybackDeviceInfos[iAvailableDevice].name); cout << iAvailableDevice << " : " << m_pPlaybackDeviceInfos[iAvailableDevice].name << endl;
} }
return result; return result;
} }
@ -123,19 +229,49 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file, uint audioDevice)
ma_sound_uninit(&m_currentSound[layer]); ma_sound_uninit(&m_currentSound[layer]);
m_mediaLoaded[layer] = false; m_mediaLoaded[layer] = false;
} }
result = ma_sound_init_from_file(&engine[audioDevice], file, \ /*
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_NO_SPATIALIZATION \
| MA_SOUND_FLAG_DECODE \ // | MA_SOUND_FLAG_DECODE // | MA_SOUND_FLAG_STREAM // | MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT
| MA_SOUND_FLAG_STREAM \
/*| MA_SOUND_FLAG_NO_PITCH \*/
, NULL, NULL, &m_currentSound[layer]); , NULL, NULL, &m_currentSound[layer]);
if (result != MA_SUCCESS) if (result != MA_SUCCESS) {
qWarning("Failed to load file %s", file); cout << "Error " << result << ": Failed to load file " << file << endl;
else { return result;
m_mediaLoaded[layer] = true;
this->refreshValues(layer);
m_currentLayerValues[layer].media = file;
} }
result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &g_lpfNode[audioDevice], 0);
if (result != MA_SUCCESS) {
cout << "Error " << result << ": Failed to attach output bus " << audioDevice << endl;
//return result;
}
m_mediaLoaded[layer] = true;
this->refreshValues(layer);
m_currentLayerValues[layer].media = file;
return result; return result;
} }
@ -163,7 +299,7 @@ float MiniAudioEngine::getCursor(int layer)
result = ma_sound_get_cursor_in_seconds(&m_currentSound[layer], &ret); result = ma_sound_get_cursor_in_seconds(&m_currentSound[layer], &ret);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
{ {
qWarning("%i can not get cursor error %i", layer, result); cout << "Error" << result << ": Can not get cursor " << layer << endl;
ret = MA_ERROR; ret = MA_ERROR;
} }
return ret; return ret;
@ -177,11 +313,17 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
if (m_mediaLoaded[layer] == false) if (m_mediaLoaded[layer] == false)
return MA_DOES_NOT_EXIST; return MA_DOES_NOT_EXIST;
ma_result result = ma_sound_get_data_format(&m_currentSound[layer], &format, &channels, &sampleRate, NULL, 0); ma_result result = ma_sound_get_data_format(&m_currentSound[layer], \
if (result != MA_SUCCESS) &format, &channels, &sampleRate, NULL, 0);
qWarning("%i failed to get data format %i\n", layer, result); if (result != MA_SUCCESS) {
else cout << "Error" << result << ": Failed to get data format " << layer;
qInfo() << "Layer:" << layer << m_currentLayerValues[layer].media << "samples/sec:" << sampleRate << "format:" << format << "channels:" << channels; cout << endl;
} else {
cout << "Layer: " << layer;
cout << m_currentLayerValues[layer].media.toLatin1().data();
cout << " samples/sec:" << sampleRate << " format:" << format;
cout << " channels:" << channels << endl;
}
return result; return result;
} }

View file

@ -9,7 +9,32 @@
#define MINIAUDIO_IMPLEMENTATION #define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h" #include "miniaudio.h"
#include "defines.h" // MAX_LAYERS #include "defines.h" // MAX_LAYERS
#include <QDebug> // prints messages #include <bits/stdc++.h>
using namespace std;
/* Data Format */
#define FORMAT ma_format_f32 /* Must always be f32. */
#define CHANNELS 2
#define SAMPLE_RATE 48000
typedef struct
{
ma_node_base node;
ma_loshelf2 loShelfNode;
ma_peak2 midLowNode;
ma_peak2 midHighNode;
ma_hishelf2 hiShelfNode;
ma_splitter_node outputNode;
} filterBank;
typedef struct
{
ma_node_base input;
ma_data_source_node node;
ma_decoder decoder;
filterBank filters;
} soundNode;
class MiniAudioEngine class MiniAudioEngine
{ {
@ -19,8 +44,13 @@ public:
MiniAudioEngine(); MiniAudioEngine();
void stopEngine(); void stopEngine();
bool startEngine(); bool startEngine();
ma_result startDevice(uint id, uint internalId); bool startDevice(uint *id, uint nb);
static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); 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];
protected: protected:
ma_result loadMedia(int layer, char *media, uint audioDevice); ma_result loadMedia(int layer, char *media, uint audioDevice);
@ -38,22 +68,19 @@ protected:
inline bool getAtEnd(int layer) { return m_currentSound[layer].atEnd; } inline bool getAtEnd(int layer) { return m_currentSound[layer].atEnd; }
private: private:
ma_resource_manager_config resourceManagerConfig; ma_resource_manager_config m_resourceManagerConfig;
ma_resource_manager resourceManager; ma_resource_manager m_resourceManager;
ma_device_info* pPlaybackDeviceInfos; ma_context m_context;
ma_uint32 playbackDeviceCount; ma_device_info* m_pPlaybackDeviceInfos;
ma_uint32 iChosenDevice; ma_uint32 m_playbackDeviceCount;
ma_engine engine[MAX_AUDIODEVICES]; ma_uint32 m_devicesSelected;
ma_device device[MAX_AUDIODEVICES];
ma_context context;
ma_sound m_currentSound[MAX_LAYERS];
ma_bool8 m_mediaLoaded[MAX_LAYERS];
layerData m_currentLayerValues[MAX_LAYERS]; layerData m_currentLayerValues[MAX_LAYERS];
ma_result getAllAudioDevices(); ma_result getAllAudioDevices();
ma_result startContext(); ma_result startContext();
void refreshValues(int layer); void refreshValues(int layer);
ma_result seekToCursor(int layer, int cursor); ma_result seekToCursor(int layer, int cursor);
ma_result setNodeGraph(int id);
}; };
#endif // MINIAUDIOENGINE_H #endif // MINIAUDIOENGINE_H