Mercurial > hg > beaglert
diff core/RTAudio.cpp @ 5:09f03ac40fcc
API improvements and cleanups. Now all common audio command-line options can be parsed automatically.
author | andrewm |
---|---|
date | Sat, 08 Nov 2014 16:16:55 +0100 |
parents | 8a575ba3ab52 |
children | a6beeba3a648 |
line wrap: on
line diff
--- a/core/RTAudio.cpp Thu Nov 06 19:02:48 2014 +0000 +++ b/core/RTAudio.cpp Sat Nov 08 16:16:55 2014 +0100 @@ -44,8 +44,6 @@ } InternalAuxiliaryTask; const char gRTAudioThreadName[] = "beaglert-audio"; -const char gRTCalculationThreadNameMedium[] = "dbox-calculation-medium"; -const char gRTCalculationThreadNameLow[] = "dbox-calculation-low"; // Real-time tasks and objects RT_TASK gRTAudioThread; @@ -61,6 +59,7 @@ int gRTAudioVerbose = 0; // Verbosity level for debugging char gPRUFilename[256] = "pru_rtaudio.bin"; // path to PRU binary file int gAmplifierMutePin = -1; +int gAmplifierShouldBeginMuted = 0; // initAudio() prepares the infrastructure for running PRU-based real-time @@ -74,31 +73,41 @@ // // Returns 0 on success. -int initAudio(int periodSize, int useMatrix, - void *userData, - int codecI2CAddress, int ampMutePin) +int BeagleRT_initAudio(RTAudioSettings *settings, void *userData) { rt_print_auto_init(1); + setVerboseLevel(settings->verbose); + if(gRTAudioVerbose == 1) rt_printf("Running with Xenomai\n"); - if(gRTAudioVerbose == 1) - cout << "---------------->Init Audio Thread" << endl; + if(gRTAudioVerbose) { + cout << "Starting with period size " << settings->periodSize << "; "; + if(settings->useMatrix) + cout << "matrix enabled\n"; + else + cout << "matrix disabled\n"; + cout << "DAC level " << settings->dacLevel << "dB; ADC level " << settings->adcLevel; + cout << "dB; headphone level " << settings->headphoneLevel << "dB\n"; + if(settings->beginMuted) + cout << "Beginning with speaker muted\n"; + } // Prepare GPIO pins for amplifier mute and status LED - if(ampMutePin >= 0) { - gAmplifierMutePin = ampMutePin; + if(settings->ampMutePin >= 0) { + gAmplifierMutePin = settings->ampMutePin; + gAmplifierShouldBeginMuted = settings->beginMuted; - if(gpio_export(ampMutePin)) { + if(gpio_export(settings->ampMutePin)) { if(gRTAudioVerbose) cout << "Warning: couldn't export amplifier mute pin\n"; } - if(gpio_set_dir(ampMutePin, OUTPUT_PIN)) { + if(gpio_set_dir(settings->ampMutePin, OUTPUT_PIN)) { if(gRTAudioVerbose) cout << "Couldn't set direction on amplifier mute pin\n"; return -1; } - if(gpio_set_value(ampMutePin, LOW)) { + if(gpio_set_value(settings->ampMutePin, LOW)) { if(gRTAudioVerbose) cout << "Couldn't set value on amplifier mute pin\n"; return -1; @@ -109,15 +118,15 @@ gPRU = new PRU(); gAudioCodec = new I2c_Codec(); - if(gPRU->prepareGPIO(useMatrix, 1, 1)) { + if(gPRU->prepareGPIO(settings->useMatrix, 1, 1)) { cout << "Error: unable to prepare GPIO for PRU audio\n"; return 1; } - if(gPRU->initialise(0, periodSize, true)) { + if(gPRU->initialise(0, settings->periodSize, true)) { cout << "Error: unable to initialise PRU\n"; return 1; } - if(gAudioCodec->initI2C_RW(2, codecI2CAddress, -1)) { + if(gAudioCodec->initI2C_RW(2, settings->codecI2CAddress, -1)) { cout << "Unable to open codec I2C\n"; return 1; } @@ -125,11 +134,13 @@ cout << "Error: unable to initialise audio codec\n"; return 1; } - gAudioCodec->setDACVolume(0); // Set the DAC volume to full-scale - gAudioCodec->setHPVolume(-12); // Headphones 6dB down - gAudioCodec->setADCVolume(-12); // Set the ADC volume to 6dB down - if(!initialise_render(2, useMatrix ? periodSize : 0, periodSize * 2, 22050.0, 44100.0, userData)) { + // Set default volume levels + BeagleRT_setDACLevel(settings->dacLevel); + BeagleRT_setADCLevel(settings->adcLevel); + BeagleRT_setHeadphoneLevel(settings->headphoneLevel); + + if(!initialise_render(2, settings->useMatrix ? settings->periodSize : 0, settings->periodSize * 2, 22050.0, 44100.0, userData)) { cout << "Couldn't initialise audio rendering\n"; return 1; } @@ -161,10 +172,13 @@ } else { // All systems go. Run the loop; it will end when gShouldStop is set to 1 - // First unmute the amplifier - if(gpio_set_value(gAmplifierMutePin, HIGH)) { - if(gRTAudioVerbose) - rt_printf("Warning: couldn't set value (high) on amplifier mute pin\n"); + + if(!gAmplifierShouldBeginMuted) { + // First unmute the amplifier + if(BeagleRT_muteSpeakers(0)) { + if(gRTAudioVerbose) + rt_printf("Warning: couldn't set value (high) on amplifier mute pin\n"); + } } gPRU->loop(); @@ -242,7 +256,7 @@ // It launches the real-time Xenomai task which runs the audio loop. Returns 0 // on success. -int startAudio() +int BeagleRT_startAudio() { // Create audio thread with the highest priority if(rt_task_create(&gRTAudioThread, gRTAudioThreadName, 0, 99, T_JOINABLE | T_FPU)) { @@ -273,11 +287,14 @@ // Stop the PRU-based audio from running and wait // for the tasks to complete before returning. -void stopAudio() +void BeagleRT_stopAudio() { // Tell audio thread to stop (if this hasn't been done already) gShouldStop = true; + if(gRTAudioVerbose) + cout << "Stopping audio...\n"; + // Now wait for threads to respond and actually stop... rt_task_join(&gRTAudioThread); @@ -293,7 +310,7 @@ } // Free any resources associated with PRU real-time audio -void cleanupAudio() +void BeagleRT_cleanupAudio() { cleanup_render(); @@ -318,6 +335,48 @@ gAmplifierMutePin = -1; } +// Set the level of the DAC; affects all outputs (headphone, line, speaker) +// 0dB is the maximum, -63.5dB is the minimum; 0.5dB steps +int BeagleRT_setDACLevel(float decibels) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setDACVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// Set the level of the ADC +// 0dB is the maximum, -12dB is the minimum; 1.5dB steps +int BeagleRT_setADCLevel(float decibels) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setADCVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// Set the level of the onboard headphone amplifier; affects headphone +// output only (not line out or speaker) +// 0dB is the maximum, -63.5dB is the minimum; 0.5dB steps +int BeagleRT_setHeadphoneLevel(float decibels) +{ + if(gAudioCodec == 0) + return -1; + return gAudioCodec->setHPVolume((int)floorf(decibels * 2.0 + 0.5)); +} + +// Mute or unmute the onboard speaker amplifiers +// mute == 0 means unmute; otherwise mute +// Returns 0 on success +int BeagleRT_muteSpeakers(int mute) +{ + int pinValue = mute ? LOW : HIGH; + + // Check that we have an enabled pin for controlling the mute + if(gAmplifierMutePin < 0) + return -1; + + return gpio_set_value(gAmplifierMutePin, pinValue); +} + // Set the verbosity level void setVerboseLevel(int level) {