Antigona Release #1
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