funcionando multidispositivo, cada capa se patchea a un dispositivo de

audio.
This commit is contained in:
snt 2024-05-10 21:04:26 +02:00
parent 103a33820e
commit 8c69da5f9d
7 changed files with 38 additions and 37 deletions

View file

@ -1,8 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<lmsAudio ui="1" layersNumber="4" path="../media/sound" > <lmsAudio ui="1" layersNumber="4" path="../media/sound" >
<audioDevice devicesNumber="2" id0="3" id1="4" /> <audioDevice devicesNumber="2" id0="3" id1="4"/>
<layer id="0" dmx="1" universe="1" /> <layer id="0" dmx="1" universe="1" audioDevice="0" />
<layer id="1" dmx="17" universe="1" /> <layer id="1" dmx="17" universe="1" audioDevice="0" />
<layer id="2" dmx="33" universe="1" /> <layer id="2" dmx="33" universe="1" audioDevice="1" />
<layer id="3" dmx="49" universe="1" /> <layer id="3" dmx="49" universe="1" audioDevice="1"/>
</lmsAudio> </lmsAudio>

View file

@ -14,6 +14,7 @@ struct dmxSetting {
int address; int address;
unsigned int universe; unsigned int universe;
int layer; int layer;
int audioDevice;
}; };
enum Status enum Status

View file

@ -26,6 +26,7 @@ libreMediaServerAudio::libreMediaServerAudio()
m_settings = Settings::getInstance(); m_settings = Settings::getInstance();
m_settings->readFile(); m_settings->readFile();
m_ui = m_settings->getShowUi(); m_ui = m_settings->getShowUi();
m_dmxSettings = m_settings->getDmxSettings();
m_mediaLibrary = new MediaLibrary; m_mediaLibrary = new MediaLibrary;
m_mediaLibrary->initMediaLibrary(); m_mediaLibrary->initMediaLibrary();
for (int i = 0; i < MAX_LAYERS; i++) { for (int i = 0; i < MAX_LAYERS; i++) {
@ -42,7 +43,10 @@ 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(m_settings->getAudioDeviceId()); m_mae.startEngine();
uint *audioDevList = m_settings->getAudioDeviceId();
for (uint i = 0; i < m_settings->getAudioDeviceQty(); i++)
m_mae.startDevice(audioDevList[i], i);
qDebug("Core init Complete. Start reading DMX."); qDebug("Core init Complete. Start reading DMX.");
m_ola->blockSignals(false); m_ola->blockSignals(false);
#ifdef NOGUI #ifdef NOGUI
@ -62,7 +66,7 @@ void libreMediaServerAudio::loadMedia(int layer, int folder, int file)
if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0) if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
return; return;
if (QFile::exists(mediaFile)){ if (QFile::exists(mediaFile)){
m_mae.loadMedia(layer, mediaFile.toLatin1().data()); m_mae.loadMedia(layer, mediaFile.toLatin1().data(), m_dmxSettings.at(layer).audioDevice);
m_currentMedia[layer] = mediaFile; m_currentMedia[layer] = mediaFile;
#ifndef NOGUI #ifndef NOGUI
if (m_ui) if (m_ui)
@ -247,7 +251,7 @@ void libreMediaServerAudio::uiLoadMedia(int layer, QString mediaFile)
if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0) if (strcmp(mediaFile.toLatin1().constData(), m_currentMedia[layer].toLatin1().constData()) == 0)
return; return;
result = m_mae.loadMedia(layer, mediaFile.toLatin1().data()); result = m_mae.loadMedia(layer, mediaFile.toLatin1().data(), m_dmxSettings[layer].audioDevice);
if (result == MA_SUCCESS) { if (result == MA_SUCCESS) {
m_currentMedia[layer] = mediaFile; m_currentMedia[layer] = mediaFile;
m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer)); m_lmsUi->m_aw->mediaLoaded(layer, mediaFile, m_mae.getDuration(layer));

View file

@ -21,60 +21,57 @@ void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const
void MiniAudioEngine::stopEngine() void MiniAudioEngine::stopEngine()
{ {
ma_engine_uninit(&engine); ma_engine_uninit(&engine[0]);
ma_device_uninit(&device); ma_device_uninit(&device[0]);
ma_context_uninit(&context); ma_context_uninit(&context);
ma_resource_manager_uninit(&resourceManager); ma_resource_manager_uninit(&resourceManager);
} }
bool MiniAudioEngine::startEngine(uint n) 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 result;
result = this->getAllAudioDevices(); result = this->getAllAudioDevices();
if (result != MA_SUCCESS) return result;
result = this->startDevice(n);
return result; return result;
} }
ma_result MiniAudioEngine::startDevice(uint id) ma_result MiniAudioEngine::startDevice(uint systemId, uint internalId)
{ {
ma_result result; ma_result result;
ma_device_config deviceConfig; ma_device_config deviceConfig;
ma_engine_config engineConfig; ma_engine_config engineConfig;
if (id >= playbackDeviceCount) if (systemId >= playbackDeviceCount)
id = playbackDeviceCount - 1; systemId = playbackDeviceCount - 1;
deviceConfig = ma_device_config_init(ma_device_type_playback); deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.pDeviceID = &pPlaybackDeviceInfos[id].id; deviceConfig.playback.pDeviceID = &pPlaybackDeviceInfos[systemId].id;
deviceConfig.playback.format = resourceManager.config.decodedFormat; deviceConfig.playback.format = resourceManager.config.decodedFormat;
deviceConfig.playback.channels = 0; deviceConfig.playback.channels = 0;
deviceConfig.sampleRate = resourceManager.config.decodedSampleRate; deviceConfig.sampleRate = resourceManager.config.decodedSampleRate;
deviceConfig.dataCallback = audioDataCallback; deviceConfig.dataCallback = audioDataCallback;
deviceConfig.pUserData = &engine; deviceConfig.pUserData = &engine[internalId];
result = ma_device_init(&context, &deviceConfig, &device); result = ma_device_init(&context, &deviceConfig, &device[internalId]);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio device %s.", pPlaybackDeviceInfos[id].name); qCritical("Failed to initialize audio device %s.", pPlaybackDeviceInfos[systemId].name);
return result; return result;
} }
engineConfig = ma_engine_config_init(); engineConfig = ma_engine_config_init();
engineConfig.pDevice = &device; engineConfig.pDevice = &device[internalId];
engineConfig.pResourceManager = &resourceManager; engineConfig.pResourceManager = &resourceManager;
engineConfig.noAutoStart = MA_TRUE; engineConfig.noAutoStart = MA_TRUE;
result = ma_engine_init(NULL, &engine); result = ma_engine_init(NULL, &engine[internalId]);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qCritical("Failed to initialize audio engine."); qCritical("Failed to initialize audio engine.");
return result; return result;
} }
result = ma_engine_start(&engine); result = ma_engine_start(&engine[internalId]);
if (result != MA_SUCCESS) { if (result != MA_SUCCESS) {
qCritical("Failed to start audio engine %i.", id); qCritical("Failed to start audio engine %i.", systemId);
return result; return result;
} }
iChosenDevice = id; qInfo("Initialized audio device internal: %ui system: %d %s", internalId, systemId, pPlaybackDeviceInfos[systemId].name);
qInfo("Initialized audio device %d : %s", id, pPlaybackDeviceInfos[id].name);
return result; return result;
} }
@ -117,7 +114,7 @@ ma_result MiniAudioEngine::getAllAudioDevices()
return result; return result;
} }
ma_result MiniAudioEngine::loadMedia(int layer, char *file) ma_result MiniAudioEngine::loadMedia(int layer, char *file, uint audioDevice)
{ {
ma_result result; ma_result result;
@ -126,7 +123,7 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file)
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, file, \ result = ma_sound_init_from_file(&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_STREAM \

View file

@ -18,11 +18,12 @@ class MiniAudioEngine
public: public:
MiniAudioEngine(); MiniAudioEngine();
void stopEngine(); void stopEngine();
bool startEngine(uint id); bool startEngine();
ma_result startDevice(uint id, uint internalId);
static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); static void audioDataCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
protected: protected:
ma_result loadMedia(int layer, char *media ); ma_result loadMedia(int layer, char *media, uint audioDevice);
void volChanged(int layer, float vol); void volChanged(int layer, float vol);
void panChanged(int layer, float pan); void panChanged(int layer, float pan);
void pitchChanged(int layer, float pitch); void pitchChanged(int layer, float pitch);
@ -42,15 +43,14 @@ private:
ma_device_info* pPlaybackDeviceInfos; ma_device_info* pPlaybackDeviceInfos;
ma_uint32 playbackDeviceCount; ma_uint32 playbackDeviceCount;
ma_uint32 iChosenDevice; ma_uint32 iChosenDevice;
ma_engine engine; ma_engine engine[MAX_AUDIODEVICES];
ma_device device; ma_device device[MAX_AUDIODEVICES];
ma_context context; ma_context context;
ma_sound m_currentSound[MAX_LAYERS]; ma_sound m_currentSound[MAX_LAYERS];
ma_bool8 m_mediaLoaded[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 startDevice(uint id);
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);

View file

@ -51,16 +51,14 @@ void Settings::readFromFile(QString file) {
if(xmlReader->name() == "audioDevice") { if(xmlReader->name() == "audioDevice") {
m_audioDeviceQty = xmlReader->attributes().value("devicesNumber").toLocal8Bit().toInt(); m_audioDeviceQty = xmlReader->attributes().value("devicesNumber").toLocal8Bit().toInt();
for (uint i = 0; i < m_audioDeviceQty; i++) for (uint i = 0; i < m_audioDeviceQty; i++)
{
m_audioDeviceId[i] = xmlReader->attributes().value(QString("id%1").arg(i)).toLocal8Bit().toInt(); m_audioDeviceId[i] = xmlReader->attributes().value(QString("id%1").arg(i)).toLocal8Bit().toInt();
}
} }
if(xmlReader->name() == "layer") { if(xmlReader->name() == "layer") {
dmxSetting temp; dmxSetting temp;
temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1; temp.address = xmlReader->attributes().value("dmx").toLocal8Bit().toInt() - 1;
temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt(); temp.universe = xmlReader->attributes().value("universe").toLocal8Bit().toInt();
temp.layer = xmlReader->attributes().value("id").toLocal8Bit().toInt(); temp.layer = xmlReader->attributes().value("id").toLocal8Bit().toInt();
temp.audioDevice = xmlReader->attributes().value("audioDevice").toLocal8Bit().toInt();
m_settings.append(temp); m_settings.append(temp);
if (!m_universe.contains(temp.universe)) { if (!m_universe.contains(temp.universe)) {
m_universe.insert(temp.universe); m_universe.insert(temp.universe);

View file

@ -22,7 +22,8 @@ public:
inline QString getPathMedia() { return m_pathmedia; } inline QString getPathMedia() { return m_pathmedia; }
inline QList<dmxSetting> getDmxSettings() { return m_settings; } inline QList<dmxSetting> getDmxSettings() { return m_settings; }
inline int getLayersNumber() { return m_layersNumber; } inline int getLayersNumber() { return m_layersNumber; }
inline int getAudioDeviceId() { return m_audioDeviceId[0]; } inline uint *getAudioDeviceId() { return m_audioDeviceId; }
inline uint getAudioDeviceQty() { return m_audioDeviceQty; }
inline bool getShowUi() { return m_ui; } inline bool getShowUi() { return m_ui; }
void readFile(); void readFile();
void readFromFile(QString file); void readFromFile(QString file);