refactorizado todo a una struct.
Maximo de dispositivos MAX_AUDIODEVICES, sin testear mas de dos. Los devices auxiliares leen de data source rb en vez de en el callback. la idea del nodegraph funcionando en una engine dummy no ha funcionado, pero puede que fuera por la refactorización y la introducción de las data sources rb. Ahora que está todo más ordenado se puede volver a intentar. Pero tampoco merece mucho la pena, la principal diferencia era el master bus, pero se puede atacar la salida de auxNode[0] a una capa de master en vez de al endpoint directamente.
This commit is contained in:
parent
a935d4e619
commit
5d56921aeb
4 changed files with 234 additions and 250 deletions
|
@ -40,15 +40,10 @@ libreMediaServerAudio::libreMediaServerAudio()
|
||||||
m_updateUi[i][3] = -1;
|
m_updateUi[i][3] = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!m_mae.startEngine(m_layersQty)) {
|
if (!m_mae.startEngine(m_layersQty, m_settings->getAudioDeviceId(), m_settings->getAudioDeviceQty())) {
|
||||||
cout << "Can not start Audio Engine!" << endl;
|
cout << "Can not start Audio Engine!" << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
uint *audioDevList = m_settings->getAudioDeviceId();
|
|
||||||
if (!m_mae.startDevice(audioDevList, m_settings->getAudioDeviceQty())) {
|
|
||||||
cout << "Can not start Audio Device!" << audioDevList << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
m_ola = new olaThread(this, m_layersQty);
|
m_ola = new olaThread(this, m_layersQty);
|
||||||
Q_CHECK_PTR(m_ola);
|
Q_CHECK_PTR(m_ola);
|
||||||
m_ola->blockSignals(true);
|
m_ola->blockSignals(true);
|
||||||
|
|
|
@ -28,7 +28,6 @@ static void ma_writer_node_process_pcm_frames(ma_node* pNode, const float** ppFr
|
||||||
ma_pcm_rb_commit_write(pWriteNode->pBuffer, *pFrameCountIn);
|
ma_pcm_rb_commit_write(pWriteNode->pBuffer, *pFrameCountIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//*pFrameCountOut = 0;
|
|
||||||
ma_copy_pcm_frames(ppFramesOut[0], ppFramesIn[0], *pFrameCountOut, ma_format_f32, pWriteNode->channels);
|
ma_copy_pcm_frames(ppFramesOut[0], ppFramesIn[0], *pFrameCountOut, ma_format_f32, pWriteNode->channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,6 @@
|
||||||
#define BIAS 0.99f
|
#define BIAS 0.99f
|
||||||
#define FILTER_ORDER 3
|
#define FILTER_ORDER 3
|
||||||
|
|
||||||
static ma_pcm_rb aux1Buffer;
|
|
||||||
static ma_data_source_node g_dataSupplyNode;
|
|
||||||
static ma_data_source_rb g_dataSourceRB;
|
|
||||||
|
|
||||||
MiniAudioEngine::MiniAudioEngine() {}
|
MiniAudioEngine::MiniAudioEngine() {}
|
||||||
|
|
||||||
void MiniAudioEngine::audioDataCallback(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)
|
||||||
|
@ -21,83 +17,78 @@ void MiniAudioEngine::audioDataCallback(ma_device* pDevice, void* pOutput, const
|
||||||
(void)pInput;
|
(void)pInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::audioDataCallback1(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
|
||||||
{
|
|
||||||
(void)pDevice;
|
|
||||||
ma_result result;
|
|
||||||
|
|
||||||
ma_uint32 pcmFramesAvailableInRB = 0;
|
|
||||||
ma_uint32 pcmFramesProcessed = 0;
|
|
||||||
while (pcmFramesProcessed < frameCount) {
|
|
||||||
pcmFramesAvailableInRB = ma_pcm_rb_available_read(&aux1Buffer);
|
|
||||||
if (pcmFramesAvailableInRB == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ma_uint32 framesToRead = frameCount - pcmFramesProcessed;
|
|
||||||
if (framesToRead > pcmFramesAvailableInRB) {
|
|
||||||
framesToRead = pcmFramesAvailableInRB;
|
|
||||||
}
|
|
||||||
void* pReadBuffer = NULL;
|
|
||||||
ma_pcm_rb_acquire_read(&aux1Buffer, &framesToRead, &pReadBuffer);
|
|
||||||
if (pReadBuffer != NULL) {
|
|
||||||
ma_copy_pcm_frames(pOutput, pReadBuffer, framesToRead, FORMAT, CHANNELS);
|
|
||||||
ma_pcm_rb_commit_read(&aux1Buffer, framesToRead);
|
|
||||||
pcmFramesProcessed += framesToRead;
|
|
||||||
}/* else { break; }*/
|
|
||||||
}
|
|
||||||
(void)pInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MiniAudioEngine::stopEngine()
|
void MiniAudioEngine::stopEngine()
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < m_layersQty; i++) {
|
for (uint i = 0; i < m_mae.layersQty; i++) {
|
||||||
ma_sound_uninit(&m_currentSound[i]);
|
if (m_mae.mediaLoaded[i])
|
||||||
|
ma_sound_uninit(&m_mae.sounds[i]);
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < m_devicesSelected; i++) {
|
for (uint i = 0; i < m_mae.layersQty; i++) {
|
||||||
for (uint j = 0; j < m_layersQty; j++) {
|
ma_node_uninit(&m_mae.filters[i].input, NULL);
|
||||||
ma_node_uninit(&m_filterBank[i][j].input, NULL);
|
ma_hpf_node_uninit(&m_mae.filters[i].hpf, NULL);
|
||||||
ma_hpf_node_uninit(&m_filterBank[i][j].hpf, NULL);
|
ma_loshelf_node_uninit(&m_mae.filters[i].loshelf, NULL);
|
||||||
ma_loshelf_node_uninit(&m_filterBank[i][j].loshelf, NULL);
|
ma_peak_node_uninit(&m_mae.filters[i].mLow, NULL);
|
||||||
ma_peak_node_uninit(&m_filterBank[i][j].mLow, NULL);
|
ma_peak_node_uninit(&m_mae.filters[i].mHigh, NULL);
|
||||||
ma_peak_node_uninit(&m_filterBank[i][j].mHigh, NULL);
|
ma_hishelf_node_uninit(&m_mae.filters[i].hishelf, NULL);
|
||||||
ma_hishelf_node_uninit(&m_filterBank[i][j].hishelf, NULL);
|
ma_splitter_node_uninit(&m_mae.filters[i].output, NULL);
|
||||||
ma_splitter_node_uninit(&m_filterBank[i][j].output, NULL);
|
}
|
||||||
|
for (uint i = 0; i < m_mae.audioDevicesQty; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
ma_writer_node_uninit(&m_mae.sendAuxNode[i], NULL);
|
||||||
|
ma_pcm_rb_uninit(&m_mae.auxBuffers[i]);
|
||||||
}
|
}
|
||||||
//ma_writer_node_uninit(&m_sendToAux[0], NULL);
|
ma_engine_uninit(&m_mae.engines[i]);
|
||||||
//ma_pcm_rb_uninit(&aux1Buffer);
|
ma_device_uninit(&m_mae.devices[i]);
|
||||||
ma_engine_uninit(&m_engine[i]);
|
|
||||||
ma_device_uninit(&m_device[i]);
|
|
||||||
}
|
}
|
||||||
ma_context_uninit(&m_context);
|
ma_context_uninit(&m_mae.context);
|
||||||
ma_resource_manager_uninit(&m_resourceManager);
|
ma_resource_manager_uninit(&m_mae.resourceManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MiniAudioEngine::startEngine(uint layers)
|
bool MiniAudioEngine::startEngine(uint layers, uint* audioDevicesId, uint audioDevicesQty)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
|
|
||||||
m_layersQty = layers;
|
m_mae.layersQty = layers;
|
||||||
for (uint i =0; i < m_layersQty; i++) {
|
m_mae.audioDevicesId = audioDevicesId;
|
||||||
m_mediaLoaded[i] = false;
|
m_mae.audioDevicesQty = audioDevicesQty;
|
||||||
m_currentLayerValues[i].status = Status::Iddle;
|
for (uint i =0; i < m_mae.layersQty; i++) {
|
||||||
m_currentLayerValues[i].pan = 128;
|
m_mae.mediaLoaded[i] = false;
|
||||||
m_currentLayerValues[i].pitch = 128;
|
m_mae.currentStatus[i].status = Status::Iddle;
|
||||||
m_currentLayerValues[i].vol = 0;
|
m_mae.currentStatus[i].pan = 128;
|
||||||
m_currentLayerValues[i].cursor = 0;
|
m_mae.currentStatus[i].pitch = 128;
|
||||||
|
m_mae.currentStatus[i].vol = 0;
|
||||||
|
m_mae.currentStatus[i].cursor = 0;
|
||||||
}
|
}
|
||||||
result = this->startContext();
|
result = this->startContext();
|
||||||
if (result != MA_SUCCESS) return false;
|
if (result != MA_SUCCESS) return false;
|
||||||
result = this->getAllAudioDevices();
|
result = this->getAllAudioDevices();
|
||||||
if (result != MA_SUCCESS) return false;
|
if (result != MA_SUCCESS) return false;
|
||||||
|
result = this->startDevices();
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed start audio devices." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
result = this->setNodeGraph();
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed to set node graph." << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < m_mae.audioDevicesQty; i++) {
|
||||||
|
result = ma_engine_start(&m_mae.engines[i]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed to start audio device" << m_mae.audioDevicesId[i] << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_result MiniAudioEngine::createFilterBank(int id, uint layer)
|
ma_result MiniAudioEngine::createFilterBank(uint layer)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_node_graph *ng = ma_engine_get_node_graph(&m_engine[id]);
|
ma_node_graph *ng = ma_engine_get_node_graph(&m_mae.engines[0]);
|
||||||
ma_node *endpoint = ma_engine_get_endpoint(&m_engine[id]);
|
ma_node *endpoint = ma_engine_get_endpoint(&m_mae.engines[0]);
|
||||||
filterBank *fb = &m_filterBank[id][layer];
|
filterBank *fb = &m_mae.filters[layer];
|
||||||
|
|
||||||
ma_splitter_node_config splitterConfig = ma_splitter_node_config_init(CHANNELS);
|
ma_splitter_node_config splitterConfig = ma_splitter_node_config_init(CHANNELS);
|
||||||
result = ma_splitter_node_init(ng, &splitterConfig, NULL, &fb->input);
|
result = ma_splitter_node_init(ng, &splitterConfig, NULL, &fb->input);
|
||||||
|
@ -140,13 +131,12 @@ ma_result MiniAudioEngine::createFilterBank(int id, uint layer)
|
||||||
cout << "ERROR " << result << ": Failed to init hi shelf filter node." << endl;
|
cout << "ERROR " << result << ": Failed to init hi shelf filter node." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
splitterConfig.outputBusCount = m_mae.audioDevicesQty;
|
||||||
result = ma_splitter_node_init(ng, &splitterConfig, NULL, &fb->output);
|
result = ma_splitter_node_init(ng, &splitterConfig, NULL, &fb->output);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "ERROR " << result << ": Failed to init output node." << endl;
|
cout << "ERROR " << result << ": Failed to init output node." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = ma_node_attach_output_bus(&fb->input, 0, &fb->hpf, 0);
|
result = ma_node_attach_output_bus(&fb->input, 0, &fb->hpf, 0);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "ERROR " << result << ": Failed to attach input node." << endl;
|
cout << "ERROR " << result << ": Failed to attach input node." << endl;
|
||||||
|
@ -183,137 +173,143 @@ ma_result MiniAudioEngine::createFilterBank(int id, uint layer)
|
||||||
cout << "ERROR " << result << ": Failed to attach high shelf filter node." << endl;
|
cout << "ERROR " << result << ": Failed to attach high shelf filter node." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (id == 0) {
|
if (m_mae.audioDevicesQty == 1) {
|
||||||
result = ma_node_attach_output_bus(&fb->output, 0, &m_sendToAux[id], 0);
|
result = ma_node_attach_output_bus(&fb->output, 0, endpoint, 0);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "ERROR " << result << ": Failed to attach output node to engine." << endl;
|
cout << "ERROR " << result << ": Failed to attach output to endpoint." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = ma_node_attach_output_bus(&fb->output, 1, &m_sendToAux[id], 1);
|
} else {
|
||||||
|
result = ma_node_attach_output_bus(&fb->output, 0, &m_mae.sendAuxNode[1], 0);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "ERROR " << result << ": Failed to attach output node to aux send 1." << endl;
|
cout << "ERROR " << result << ": Failed to attach output node to aux send 1." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = ma_node_attach_output_bus(&fb->output, 1, &m_mae.sendAuxNode[1], 1);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "ERROR " << result << ": Failed to attach output node to aux send 1." << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (uint i = 2; i < m_mae.audioDevicesQty; i++) {
|
||||||
|
result = ma_node_attach_output_bus(&fb->output, i, &m_mae.sendAuxNode[i], 1);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "ERROR " << result << ": Failed to attach output node to aux send 1." << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_result MiniAudioEngine::setNodeGraph(int id) {
|
ma_result MiniAudioEngine::setNodeGraph() {
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
uint i = 0;
|
|
||||||
|
|
||||||
if (id == 0) {
|
ma_node_graph *ng = ma_engine_get_node_graph(&m_mae.engines[0]);
|
||||||
ma_node_graph *ng = ma_engine_get_node_graph(&m_engine[id]);
|
for (uint i = 1; i < m_mae.audioDevicesQty; i++) {
|
||||||
size_t sizeInFrames = SAMPLE_RATE; // ma_get_bytes_per_frame(FORMAT, CHANNELS);
|
size_t sizeInFrames = SAMPLE_RATE;
|
||||||
result = ma_pcm_rb_init(FORMAT, CHANNELS, sizeInFrames, NULL, NULL, &aux1Buffer);
|
result = ma_pcm_rb_init(FORMAT, CHANNELS, sizeInFrames, NULL, NULL, &m_mae.auxBuffers[i]);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
printf("Failed to initialize ring buffer.\n");
|
printf("Failed to initialize ring buffer.\n");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
ma_silence_pcm_frames(aux1Buffer.rb.pBuffer, sizeInFrames, FORMAT, CHANNELS);
|
ma_silence_pcm_frames(m_mae.auxBuffers[i].rb.pBuffer, sizeInFrames, FORMAT, CHANNELS);
|
||||||
ma_writer_node_config writerConfig = ma_writer_node_config_init(CHANNELS, SAMPLE_RATE * 5, &aux1Buffer);
|
ma_writer_node_config writerConfig = ma_writer_node_config_init(CHANNELS, SAMPLE_RATE * 5, &m_mae.auxBuffers[i]);
|
||||||
result = ma_writer_node_init(ng, &writerConfig, NULL, &m_sendToAux[id]);
|
result = ma_writer_node_init(ng, &writerConfig, NULL, &m_mae.sendAuxNode[i]);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "ERROR " << result << ": Failed to init writer node." << endl;
|
cout << "ERROR " << result << ": Failed to init writer node." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = ma_node_attach_output_bus(&m_sendToAux[id], 0, ma_engine_get_endpoint(&m_engine[id]), 0); // Pull API
|
// esto va a dar problemas al sumar en el envío 0 una vez por cad envío extra.
|
||||||
if (result != MA_SUCCESS) {
|
// writer_node puede ser silencioso
|
||||||
cout << "ERROR " << result << ": Failed to attach writer node." << endl;
|
// así ya estamos en el caso de disparar varios bang por cada envío en el mismo nodegraph
|
||||||
return result;
|
// es mejor que writer node tenga varias entradas, una por cada envío
|
||||||
}
|
// que se dispara con un único engine y proporciona un único stream de audio de vuelta a ese engine
|
||||||
|
// en vez de un puntero hay que pasarle un array de rb
|
||||||
|
result = ma_node_attach_output_bus(&m_mae.sendAuxNode[i], 0, ma_engine_get_endpoint(&m_mae.engines[0]), 0);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "ERROR " << result << ": Failed to attach writer node." << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = ma_data_source_rb_init(&m_mae.dataSourceRB[i], &m_mae.auxBuffers[i]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed to init data source ring buffer" << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
ma_data_source_node_config dataSupplyNodeConfig = ma_data_source_node_config_init(&m_mae.dataSourceRB[i]);
|
||||||
|
result = ma_data_source_node_init(ma_engine_get_node_graph(&m_mae.engines[i]), &dataSupplyNodeConfig, NULL, &m_mae.dataSupplyNode[i]);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed to init data source node" << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = ma_node_attach_output_bus(&m_mae.dataSupplyNode[i], 0, ma_engine_get_endpoint(&m_mae.engines[i]), 0);
|
||||||
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "Error " << result << ": Failed to attach data source rb node" << endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (result == MA_SUCCESS && i < m_layersQty) {
|
for (uint i = 0; i < m_mae.layersQty; i++) {
|
||||||
result = this->createFilterBank(id, i);
|
result = this->createFilterBank(i);
|
||||||
i++;
|
if (result != MA_SUCCESS) {
|
||||||
|
cout << "ERROR " << result << ": Failed creating filter bank." << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MiniAudioEngine::startDevice(uint *systemId, uint nb)
|
ma_result MiniAudioEngine::startDevices()
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
ma_device_config deviceConfig;
|
ma_device_config deviceConfig;
|
||||||
ma_engine_config engineConfig;
|
ma_engine_config engineConfig;
|
||||||
|
|
||||||
m_devicesSelected = nb;
|
deviceConfig = ma_device_config_init(ma_device_type_duplex);
|
||||||
for (uint internalId = 0; internalId < nb; internalId++) {
|
deviceConfig.capture.format = m_mae.resourceManager.config.decodedFormat;
|
||||||
deviceConfig = ma_device_config_init(ma_device_type_duplex);
|
deviceConfig.capture.channels = CHANNELS;
|
||||||
deviceConfig.capture.pDeviceID = &m_pPlaybackDeviceInfos[systemId[internalId]].id;
|
deviceConfig.playback.channels = CHANNELS;
|
||||||
deviceConfig.capture.format = m_resourceManager.config.decodedFormat;
|
deviceConfig.capture.shareMode = ma_share_mode_shared;
|
||||||
deviceConfig.capture.channels = CHANNELS;
|
deviceConfig.playback.format = m_mae.resourceManager.config.decodedFormat;
|
||||||
deviceConfig.capture.shareMode = ma_share_mode_shared;
|
deviceConfig.sampleRate = m_mae.resourceManager.config.decodedSampleRate;
|
||||||
deviceConfig.playback.pDeviceID = &m_pPlaybackDeviceInfos[systemId[internalId]].id;
|
deviceConfig.dataCallback = audioDataCallback;
|
||||||
deviceConfig.playback.format = m_resourceManager.config.decodedFormat;
|
engineConfig = ma_engine_config_init();
|
||||||
deviceConfig.playback.channels = CHANNELS;
|
engineConfig.pResourceManager = &m_mae.resourceManager;
|
||||||
deviceConfig.sampleRate = m_resourceManager.config.decodedSampleRate;
|
engineConfig.gainSmoothTimeInMilliseconds = SAMPLE_RATE / 25;
|
||||||
if (internalId == 0)
|
engineConfig.noAutoStart = MA_TRUE;
|
||||||
deviceConfig.dataCallback = audioDataCallback;
|
|
||||||
else if (internalId == 1)
|
for (uint internalId = 0; internalId < m_mae.audioDevicesQty; internalId++) {
|
||||||
deviceConfig.dataCallback = audioDataCallback1;
|
deviceConfig.capture.pDeviceID = &m_mae.pPlaybackDeviceInfos[m_mae.audioDevicesId[internalId]].id;
|
||||||
deviceConfig.pUserData = &m_engine[internalId];
|
deviceConfig.playback.pDeviceID = &m_mae.pPlaybackDeviceInfos[m_mae.audioDevicesId[internalId]].id;
|
||||||
result = ma_device_init(&m_context, &deviceConfig, &m_device[internalId]);
|
deviceConfig.pUserData = &m_mae.engines[internalId];
|
||||||
|
result = ma_device_init(&m_mae.context, &deviceConfig, &m_mae.devices[internalId]);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to initialize audio device " << m_pPlaybackDeviceInfos[*systemId].name << endl;
|
cout << "Error " << result << ": Failed to initialize audio device " << m_mae.pPlaybackDeviceInfos[m_mae.audioDevicesId[internalId]].name << endl;
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
engineConfig = ma_engine_config_init();
|
engineConfig.pDevice = &m_mae.devices[internalId];
|
||||||
engineConfig.pDevice = &m_device[internalId];
|
result = ma_engine_init(&engineConfig, &m_mae.engines[internalId]);
|
||||||
engineConfig.pResourceManager = &m_resourceManager;
|
|
||||||
engineConfig.gainSmoothTimeInMilliseconds = SAMPLE_RATE / 100;
|
|
||||||
engineConfig.noAutoStart = MA_TRUE;
|
|
||||||
result = ma_engine_init(&engineConfig, &m_engine[internalId]);
|
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to initialize audio engine" << endl;
|
cout << "Error " << result << ": Failed to initialize audio engine" << endl;
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
result = this->setNodeGraph(internalId);
|
cout << "Initialized Audio Device. internalId: " << internalId << " systemId: " << m_mae.audioDevicesId[internalId] << " " << m_mae.pPlaybackDeviceInfos[m_mae.audioDevicesId[internalId]].name << endl;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
//result = ma_data_source_rb_init(&g_dataSourceRB, &aux1Buffer);
|
return result;
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
cout << "Error " << result << ": Failed to init data source ring buffer" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ma_data_source_node_config dataSupplyNodeConfig = ma_data_source_node_config_init(&g_dataSourceRB);
|
|
||||||
//result = ma_data_source_node_init(ma_engine_get_node_graph(&m_engine[1]), &dataSupplyNodeConfig, NULL, &g_dataSupplyNode);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
cout << "Error " << result << ": Failed to init data source node" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//result = ma_node_attach_output_bus(&g_dataSupplyNode, 0, ma_engine_get_endpoint(&m_engine[1]), 0);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
cout << "Error " << result << ": Failed to attach data source rb node" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cout << "data source node state " << ma_node_get_state(&g_dataSupplyNode.base) << endl;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_result MiniAudioEngine::startContext()
|
ma_result MiniAudioEngine::startContext()
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
|
|
||||||
m_resourceManagerConfig = ma_resource_manager_config_init();
|
ma_resource_manager_config resourceManagerConfig = ma_resource_manager_config_init();
|
||||||
m_resourceManagerConfig.decodedFormat = FORMAT;
|
resourceManagerConfig.decodedFormat = FORMAT;
|
||||||
m_resourceManagerConfig.decodedChannels = CHANNELS;
|
resourceManagerConfig.decodedChannels = CHANNELS;
|
||||||
m_resourceManagerConfig.decodedSampleRate = SAMPLE_RATE;
|
resourceManagerConfig.decodedSampleRate = SAMPLE_RATE;
|
||||||
m_resourceManagerConfig.jobThreadCount = 4;
|
resourceManagerConfig.jobThreadCount = MAX_LAYERS;
|
||||||
result = ma_resource_manager_init(&m_resourceManagerConfig, &m_resourceManager);
|
result = ma_resource_manager_init(&resourceManagerConfig, &m_mae.resourceManager);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to initialize audio resource manager." << endl;
|
cout << "Error " << result << ": Failed to initialize audio resource manager." << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = ma_context_init(NULL, 0, NULL, &m_context);
|
result = ma_context_init(NULL, 0, NULL, &m_mae.context);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to initialize audio context." << endl;
|
cout << "Error " << result << ": Failed to initialize audio context." << endl;
|
||||||
}
|
}
|
||||||
|
@ -325,15 +321,15 @@ ma_result MiniAudioEngine::getAllAudioDevices()
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
|
|
||||||
result = ma_context_get_devices(&m_context, &m_pPlaybackDeviceInfos, &m_playbackDeviceCount, NULL, NULL);
|
result = ma_context_get_devices(&m_mae.context, &m_mae.pPlaybackDeviceInfos, &m_mae.playbackDeviceCount, NULL, NULL);
|
||||||
if (result != MA_SUCCESS) {
|
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);
|
ma_context_uninit(&m_mae.context);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
cout << "Audio devices available:" << endl;
|
cout << "Audio devices available:" << endl;
|
||||||
for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < m_playbackDeviceCount; iAvailableDevice += 1) {
|
for (ma_uint32 iAvailableDevice = 0; iAvailableDevice < m_mae.playbackDeviceCount; iAvailableDevice += 1) {
|
||||||
cout << iAvailableDevice << " : " << m_pPlaybackDeviceInfos[iAvailableDevice].name << endl;
|
cout << iAvailableDevice << " : " << m_mae.pPlaybackDeviceInfos[iAvailableDevice].name << endl;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -342,28 +338,26 @@ ma_result MiniAudioEngine::loadMedia(int layer, char *file, uint audioDevice)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
|
|
||||||
// - iniciar un sonido por cada capa, copiar la capa en otro dispositivo
|
if (m_mae.mediaLoaded[layer] == true)
|
||||||
// - writer node y source con el buffer escrito en el otro device
|
|
||||||
if (m_mediaLoaded[layer] == true)
|
|
||||||
{
|
{
|
||||||
ma_sound_uninit(&m_currentSound[layer]);
|
ma_sound_uninit(&m_mae.sounds[layer]);
|
||||||
m_mediaLoaded[layer] = false;
|
m_mae.mediaLoaded[layer] = false;
|
||||||
}
|
}
|
||||||
result = ma_sound_init_from_file(&m_engine[audioDevice], file, \
|
result = ma_sound_init_from_file(&m_mae.engines[0], file, \
|
||||||
MA_SOUND_FLAG_NO_SPATIALIZATION \
|
MA_SOUND_FLAG_NO_SPATIALIZATION \
|
||||||
, NULL, NULL, &m_currentSound[layer]);
|
, NULL, NULL, &m_mae.sounds[layer]);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to load file " << file << endl;
|
cout << "Error " << result << ": Failed to load file " << file << endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = ma_node_attach_output_bus(&m_currentSound[layer], 0, &m_filterBank[audioDevice][layer].input, 0);
|
result = ma_node_attach_output_bus(&m_mae.sounds[layer], 0, &m_mae.filters[layer].input, 0);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to attach sound output bus " << audioDevice << endl;
|
cout << "Error " << result << ": Failed to attach sound output bus " << audioDevice << endl;
|
||||||
//return result;
|
return result;
|
||||||
}
|
}
|
||||||
m_mediaLoaded[layer] = true;
|
m_mae.mediaLoaded[layer] = true;
|
||||||
this->refreshValues(layer);
|
this->refreshValues(layer);
|
||||||
m_currentLayerValues[layer].media = file;
|
m_mae.currentStatus[layer].media = file;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,9 +366,9 @@ float MiniAudioEngine::getDuration(int layer)
|
||||||
ma_result result;
|
ma_result result;
|
||||||
float ret;
|
float ret;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return MA_DOES_NOT_EXIST;
|
return MA_DOES_NOT_EXIST;
|
||||||
result = ma_sound_get_length_in_seconds(&m_currentSound[layer], &ret);
|
result = ma_sound_get_length_in_seconds(&m_mae.sounds[layer], &ret);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -386,9 +380,9 @@ float MiniAudioEngine::getCursor(int layer)
|
||||||
ma_result result;
|
ma_result result;
|
||||||
float ret = 0;
|
float ret = 0;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return MA_DOES_NOT_EXIST;
|
return MA_DOES_NOT_EXIST;
|
||||||
result = ma_sound_get_cursor_in_seconds(&m_currentSound[layer], &ret);
|
result = ma_sound_get_cursor_in_seconds(&m_mae.sounds[layer], &ret);
|
||||||
if (result != MA_SUCCESS)
|
if (result != MA_SUCCESS)
|
||||||
{
|
{
|
||||||
cout << "Error" << result << ": Can not get cursor " << layer << endl;
|
cout << "Error" << result << ": Can not get cursor " << layer << endl;
|
||||||
|
@ -403,16 +397,16 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
|
||||||
ma_uint32 channels;
|
ma_uint32 channels;
|
||||||
ma_uint32 sampleRate;
|
ma_uint32 sampleRate;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return MA_DOES_NOT_EXIST;
|
return MA_DOES_NOT_EXIST;
|
||||||
ma_result result = ma_sound_get_data_format(&m_currentSound[layer], \
|
ma_result result = ma_sound_get_data_format(&m_mae.sounds[layer], \
|
||||||
&format, &channels, &sampleRate, NULL, 0);
|
&format, &channels, &sampleRate, NULL, 0);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
cout << "Error " << result << ": Failed to get data format " << layer;
|
cout << "Error " << result << ": Failed to get data format " << layer;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
} else {
|
} else {
|
||||||
cout << "Layer:" << layer << " ";
|
cout << "Layer:" << layer << " ";
|
||||||
cout << m_currentLayerValues[layer].media.toLatin1().data();
|
cout << m_mae.currentStatus[layer].media.toLatin1().data();
|
||||||
cout << " samples/sec:" << sampleRate << " format:" << format;
|
cout << " samples/sec:" << sampleRate << " format:" << format;
|
||||||
cout << " channels:" << channels << endl;
|
cout << " channels:" << channels << endl;
|
||||||
}
|
}
|
||||||
|
@ -422,50 +416,50 @@ ma_result MiniAudioEngine::printFormatInfo(int layer)
|
||||||
// Expects between 0 and 1 vol value
|
// Expects between 0 and 1 vol value
|
||||||
void MiniAudioEngine::volChanged(int layer, float vol)
|
void MiniAudioEngine::volChanged(int layer, float vol)
|
||||||
{
|
{
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
if (vol >= 1)
|
if (vol >= 1)
|
||||||
vol = 0.99f;
|
vol = 0.99f;
|
||||||
ma_sound_group_set_fade_in_milliseconds(&m_currentSound[layer], -1, pow(vol, 3), FADE_TIME);
|
ma_sound_group_set_fade_in_milliseconds(&m_mae.sounds[layer], -1, pow(vol, 3), FADE_TIME);
|
||||||
m_currentLayerValues[layer].vol = vol;
|
m_mae.currentStatus[layer].vol = vol;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::panChanged(int layer, float value)
|
void MiniAudioEngine::panChanged(int layer, float value)
|
||||||
{
|
{
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
result = (value / 128.0) - 1.0;
|
result = (value / 128.0) - 1.0;
|
||||||
ma_sound_group_set_pan(&m_currentSound[layer], result);
|
ma_sound_group_set_pan(&m_mae.sounds[layer], result);
|
||||||
m_currentLayerValues[layer].pan = value;
|
m_mae.currentStatus[layer].pan = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::pitchChanged(int layer, float value)
|
void MiniAudioEngine::pitchChanged(int layer, float value)
|
||||||
{
|
{
|
||||||
float pitch;
|
float pitch;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return;
|
return;
|
||||||
pitch = value / 128.0;
|
pitch = value / 128.0;
|
||||||
ma_sound_group_set_pitch(&m_currentSound[layer], pitch);
|
ma_sound_group_set_pitch(&m_mae.sounds[layer], pitch);
|
||||||
m_currentLayerValues[layer].pitch = value;
|
m_mae.currentStatus[layer].pitch = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_result MiniAudioEngine::playbackChanged(int layer, Status status)
|
ma_result MiniAudioEngine::playbackChanged(int layer, Status status)
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return MA_DOES_NOT_EXIST;
|
return MA_DOES_NOT_EXIST;
|
||||||
bool loop = false;
|
bool loop = false;
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case Status::Paused:
|
case Status::Paused:
|
||||||
result = ma_sound_stop_with_fade_in_milliseconds(&m_currentSound[layer], FADE_TIME);
|
result = ma_sound_stop_with_fade_in_milliseconds(&m_mae.sounds[layer], FADE_TIME);
|
||||||
break;
|
break;
|
||||||
case Status::Stopped:
|
case Status::Stopped:
|
||||||
ma_sound_stop_with_fade_in_milliseconds(&m_currentSound[layer], FADE_TIME);
|
ma_sound_stop_with_fade_in_milliseconds(&m_mae.sounds[layer], FADE_TIME);
|
||||||
result = this->seekToCursor(layer, m_currentLayerValues[layer].cursor);
|
result = this->seekToCursor(layer, m_mae.currentStatus[layer].cursor);
|
||||||
break;
|
break;
|
||||||
case Status::PlayingLoop:
|
case Status::PlayingLoop:
|
||||||
loop = true;
|
loop = true;
|
||||||
|
@ -473,18 +467,18 @@ ma_result MiniAudioEngine::playbackChanged(int layer, Status status)
|
||||||
case Status::PlayingFolder:
|
case Status::PlayingFolder:
|
||||||
case Status::PlayingFolderLoop:
|
case Status::PlayingFolderLoop:
|
||||||
case Status::PlayingFolderRandom:
|
case Status::PlayingFolderRandom:
|
||||||
ma_sound_set_stop_time_in_milliseconds(&m_currentSound[layer], ~(ma_uint64)0);
|
ma_sound_set_stop_time_in_milliseconds(&m_mae.sounds[layer], ~(ma_uint64)0);
|
||||||
ma_sound_set_looping(&m_currentSound[layer], loop);
|
ma_sound_set_looping(&m_mae.sounds[layer], loop);
|
||||||
result = ma_sound_start(&m_currentSound[layer]);
|
result = ma_sound_start(&m_mae.sounds[layer]);
|
||||||
if (m_currentLayerValues[layer].cursor != 0) {
|
if (m_mae.currentStatus[layer].cursor != 0) {
|
||||||
usleep(1000 * 50); // Avoid small glitch at start, how to flush the cached buffers in audio pipe line?
|
usleep(1000 * 50); // Avoid small glitch at start, how to flush the cached buffers in audio pipe line?
|
||||||
}
|
}
|
||||||
this->volChanged(layer, m_currentLayerValues[layer].vol);
|
this->volChanged(layer, m_mae.currentStatus[layer].vol);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (result == MA_SUCCESS)
|
if (result == MA_SUCCESS)
|
||||||
m_currentLayerValues[layer].status = status;
|
m_mae.currentStatus[layer].status = status;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,13 +487,13 @@ ma_result MiniAudioEngine::seekToCursor(int layer, int cursor)
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
ma_uint64 end, start;
|
ma_uint64 end, start;
|
||||||
|
|
||||||
if (m_mediaLoaded[layer] == false)
|
if (m_mae.mediaLoaded[layer] == false)
|
||||||
return MA_DOES_NOT_EXIST;
|
return MA_DOES_NOT_EXIST;
|
||||||
result = ma_sound_get_length_in_pcm_frames(&m_currentSound[layer], &end);
|
result = ma_sound_get_length_in_pcm_frames(&m_mae.sounds[layer], &end);
|
||||||
if (result != MA_SUCCESS) { return result; }
|
if (result != MA_SUCCESS) { return result; }
|
||||||
start = (cursor * end) / 65025;
|
start = (cursor * end) / 65025;
|
||||||
result = ma_sound_seek_to_pcm_frame(&m_currentSound[layer], start);
|
result = ma_sound_seek_to_pcm_frame(&m_mae.sounds[layer], start);
|
||||||
//result = ma_data_source_set_loop_point_in_pcm_frames(&m_currentSound[layer], start, end); // this do nothing here, it must be done after set_looping or start?
|
//result = ma_data_source_set_loop_point_in_pcm_frames(&m_mae.sounds[layer], start, end); // this do nothing here, it must be done after set_looping or start?
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,30 +501,30 @@ ma_result MiniAudioEngine::setCursor(int layer, int cursor)
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
|
|
||||||
m_currentLayerValues[layer].cursor = cursor;
|
m_mae.currentStatus[layer].cursor = cursor;
|
||||||
result = this->seekToCursor(layer, cursor);
|
result = this->seekToCursor(layer, cursor);
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status MiniAudioEngine::getStatus(int layer)
|
Status MiniAudioEngine::getStatus(int layer)
|
||||||
{
|
{
|
||||||
return m_currentLayerValues[layer].status;
|
return m_mae.currentStatus[layer].status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniAudioEngine::refreshValues(int layer)
|
void MiniAudioEngine::refreshValues(int layer)
|
||||||
{
|
{
|
||||||
this->seekToCursor(layer, m_currentLayerValues[layer].cursor);
|
this->seekToCursor(layer, m_mae.currentStatus[layer].cursor);
|
||||||
this->panChanged(layer, m_currentLayerValues[layer].pan);
|
this->panChanged(layer, m_mae.currentStatus[layer].pan);
|
||||||
this->volChanged(layer, m_currentLayerValues[layer].vol);
|
this->volChanged(layer, m_mae.currentStatus[layer].vol);
|
||||||
this->pitchChanged(layer, m_currentLayerValues[layer].pitch);
|
this->pitchChanged(layer, m_mae.currentStatus[layer].pitch);
|
||||||
this->playbackChanged(layer, m_currentLayerValues[layer].status);
|
this->playbackChanged(layer, m_mae.currentStatus[layer].status);
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_result MiniAudioEngine::filterParamChanged(int layer, int audioDevice, int channel, int value)
|
ma_result MiniAudioEngine::filterParamChanged(int layer, int audioDevice, int channel, int value)
|
||||||
{
|
{
|
||||||
|
(void)audioDevice;
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
|
filterBank *fb = &m_mae.filters[layer];
|
||||||
filterBank *fb = &m_filterBank[audioDevice][layer];
|
|
||||||
|
|
||||||
if (channel == HP_FREQ) {
|
if (channel == HP_FREQ) {
|
||||||
fb->hpfConfig.hpf.cutoffFrequency = double((value * 1.31) + 16.0f); // 16 - 350
|
fb->hpfConfig.hpf.cutoffFrequency = double((value * 1.31) + 16.0f); // 16 - 350
|
||||||
|
@ -641,7 +635,8 @@ ma_result MiniAudioEngine::filterParamChanged(int layer, int audioDevice, int ch
|
||||||
|
|
||||||
bool MiniAudioEngine::setBypass(int audioDevice, int layer, bool bypass)
|
bool MiniAudioEngine::setBypass(int audioDevice, int layer, bool bypass)
|
||||||
{
|
{
|
||||||
filterBank *fb = &m_filterBank[audioDevice][layer];
|
(void)audioDevice;
|
||||||
|
filterBank *fb = &m_mae.filters[layer];
|
||||||
|
|
||||||
if (bypass) {
|
if (bypass) {
|
||||||
ma_node_set_output_bus_volume(&fb->input, 1, 1.0f);
|
ma_node_set_output_bus_volume(&fb->input, 1, 1.0f);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ma_splitter_node input;
|
ma_splitter_node input;
|
||||||
|
@ -30,32 +29,40 @@ typedef struct
|
||||||
ma_hishelf_node hishelf;
|
ma_hishelf_node hishelf;
|
||||||
ma_hishelf_node_config hishelfConfig;
|
ma_hishelf_node_config hishelfConfig;
|
||||||
ma_splitter_node output;
|
ma_splitter_node output;
|
||||||
ma_writer_node send1;
|
|
||||||
ma_data_source_node return1;
|
|
||||||
ma_audio_buffer_ref supplyReturn1;
|
|
||||||
} filterBank;
|
} filterBank;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ma_engine m_engine[MAX_AUDIODEVICES];
|
ma_engine engines[MAX_AUDIODEVICES];
|
||||||
filterBank m_filterBank[MAX_AUDIODEVICES][MAX_LAYERS];
|
ma_device devices[MAX_AUDIODEVICES];
|
||||||
ma_writer_node m_sendAux1[MAX_LAYERS];
|
filterBank filters[MAX_LAYERS];
|
||||||
ma_pcm_rb *aux1Buffer;
|
ma_writer_node sendAuxNode[MAX_AUDIODEVICES];
|
||||||
} audioObjects;
|
ma_pcm_rb auxBuffers[MAX_AUDIODEVICES];
|
||||||
|
ma_node_graph ng;
|
||||||
|
layerData currentStatus[MAX_LAYERS];
|
||||||
|
ma_sound sounds[MAX_LAYERS];
|
||||||
|
ma_resource_manager resourceManager;
|
||||||
|
ma_context context;
|
||||||
|
ma_device_info* pPlaybackDeviceInfos;
|
||||||
|
ma_uint32 playbackDeviceCount;
|
||||||
|
ma_uint32 devicesSelected;
|
||||||
|
ma_bool8 mediaLoaded[MAX_LAYERS];
|
||||||
|
uint layersQty;
|
||||||
|
uint *audioDevicesId;
|
||||||
|
uint audioDevicesQty;
|
||||||
|
ma_data_source_node dataSupplyNode[MAX_AUDIODEVICES];
|
||||||
|
ma_data_source_rb dataSourceRB[MAX_AUDIODEVICES];
|
||||||
|
} MAE;
|
||||||
|
|
||||||
class MiniAudioEngine
|
class MiniAudioEngine
|
||||||
{
|
{
|
||||||
friend class libreMediaServerAudio;
|
friend class libreMediaServerAudio;
|
||||||
static ma_pcm_rb *rb;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MiniAudioEngine();
|
MiniAudioEngine();
|
||||||
void stopEngine();
|
void stopEngine();
|
||||||
bool startEngine(uint layersQty);
|
bool startEngine(uint layersQty, uint* audioDevicesID, uint audioDevicesQty);
|
||||||
bool startDevice(uint *id, uint nb);
|
|
||||||
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);
|
||||||
static void audioDataCallback1(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
|
|
||||||
bool setBypass(int audioDevice, int layer, bool bypass);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ma_result loadMedia(int layer, char *media, uint audioDevice);
|
ma_result loadMedia(int layer, char *media, uint audioDevice);
|
||||||
|
@ -69,33 +76,21 @@ protected:
|
||||||
float getCursor(int layer);
|
float getCursor(int layer);
|
||||||
Status getStatus(int layer);
|
Status getStatus(int layer);
|
||||||
inline float getVol(int layer) {
|
inline float getVol(int layer) {
|
||||||
return ma_sound_get_volume(&m_currentSound[layer]); }
|
return ma_sound_get_volume(&m_mae.sounds[layer]); }
|
||||||
inline bool getAtEnd(int layer) { return m_currentSound[layer].atEnd; }
|
inline bool getAtEnd(int layer) { return m_mae.sounds[layer].atEnd; }
|
||||||
ma_result filterParamChanged(int layer, int audioDevice, int channel, int value);
|
ma_result filterParamChanged(int layer, int audioDevice, int channel, int value);
|
||||||
|
bool setBypass(int audioDevice, int layer, bool bypass);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ma_resource_manager_config m_resourceManagerConfig;
|
MAE m_mae;
|
||||||
ma_resource_manager m_resourceManager;
|
|
||||||
ma_context m_context;
|
|
||||||
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_AUDIODEVICES][MAX_LAYERS];
|
|
||||||
ma_engine m_engine[MAX_AUDIODEVICES];
|
|
||||||
uint m_layersQty;
|
|
||||||
ma_writer_node m_sendToAux[MAX_LAYERS];
|
|
||||||
audioObjects m_audioObjects;
|
|
||||||
|
|
||||||
|
ma_result startDevices();
|
||||||
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);
|
ma_result setNodeGraph();
|
||||||
ma_result createFilterBank(int id, uint layer);
|
ma_result createFilterBank(uint layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MINIAUDIOENGINE_H
|
#endif // MINIAUDIOENGINE_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue