Mercurial > hg > beaglert
changeset 528:5c8f46fcd4d0 API-update
Updated BelaContext to use separate values for in/ou channels
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Thu, 23 Jun 2016 18:17:35 +0100 |
parents | 1c68ad13bbe4 |
children | bfcbeb437869 |
files | core/PRU.cpp core/RTAudio.cpp examples/01-Basics/passthrough/render.cpp include/Bela.h include/PRU.h include/Utilities.h |
diffstat | 6 files changed, 125 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/core/PRU.cpp Thu Jun 23 18:15:26 2016 +0100 +++ b/core/PRU.cpp Thu Jun 23 18:17:35 2016 +0100 @@ -334,7 +334,7 @@ pru_buffer_spi_dac = (uint16_t *)&pruMem[PRU_MEM_DAC_OFFSET/sizeof(uint32_t)]; /* ADC memory starts after N(ch)*2(buffers)*bufsize samples */ - pru_buffer_spi_adc = &pru_buffer_spi_dac[2 * context->analogChannels * context->analogFrames]; + pru_buffer_spi_adc = &pru_buffer_spi_dac[2 * context->analogInChannels * context->analogFrames]; } else { pru_buffer_spi_dac = pru_buffer_spi_adc = 0; @@ -376,7 +376,12 @@ } if(analog_enabled) { pru_buffer_comm[PRU_USE_SPI] = 1; - pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = context->analogChannels; + if(context->analogInChannels != context->analogOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return 1; + } + unsigned int analogChannels = context->analogInChannels; + pru_buffer_comm[PRU_SPI_NUM_CHANNELS] = analogChannels; } else { pru_buffer_comm[PRU_USE_SPI] = 0; @@ -460,9 +465,9 @@ return 1; } #else - context->analogIn = (float *)malloc(context->analogChannels * context->analogFrames * sizeof(float)); - context->analogOut = (float *)malloc(context->analogChannels * context->analogFrames * sizeof(float)); - last_analog_out_frame = (float *)malloc(context->analogChannels * sizeof(float)); + context->analogIn = (float *)malloc(context->analogInChannels * context->analogFrames * sizeof(float)); + context->analogOut = (float *)malloc(context->analogOutChannels * context->analogFrames * sizeof(float)); + last_analog_out_frame = (float *)malloc(context->analogOutChannels * sizeof(float)); if(context->analogIn == 0 || context->analogOut == 0 || last_analog_out_frame == 0) { rt_printf("Error: couldn't allocate analog buffers\n"); @@ -470,7 +475,7 @@ } #endif - memset(last_analog_out_frame, 0, context->analogChannels * sizeof(float)); + memset(last_analog_out_frame, 0, context->analogOutChannels * sizeof(float)); } // Allocate digital buffers @@ -528,7 +533,12 @@ RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period #else // Polling interval is 1/4 of the period - RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (context->analogChannels / 2) * context->analogFrames / 4; + if(context->analogInChannels != context->analogOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return; + } + unsigned int analogChannels = context->analogInChannels; + RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (analogChannels / 2) * context->analogFrames / 4; #endif uint32_t pru_audio_offset, pru_spi_offset; @@ -540,8 +550,8 @@ if(analog_enabled) { if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { // Remember the content of the last_analog_out_frame - for(unsigned int ch = 0; ch < context->analogChannels; ch++){ - last_analog_out_frame[ch] = context->analogOut[context->analogChannels * (context->analogFrames - 1) + ch]; + for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){ + last_analog_out_frame[ch] = context->analogOut[context->analogOutChannels * (context->analogFrames - 1) + ch]; } } } @@ -605,8 +615,18 @@ } else { // PRU is on buffer 0. We read and write to buffer 1 - pru_audio_offset = context->audioFrames * 2; - pru_spi_offset = context->analogFrames * context->analogChannels; + if(context->audioInChannels != context->audioOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return; + } + unsigned int audioChannels = context->audioInChannels; + pru_audio_offset = context->audioFrames * audioChannels; + if(context->analogInChannels != context->analogOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return; + } + unsigned int analogChannels = context->analogInChannels; + pru_spi_offset = context->analogFrames * analogChannels; if(digital_enabled) context->digital = digital_buffer1; } @@ -644,22 +664,22 @@ int16_to_float_analog(context->analogChannels * context->analogFrames, &pru_buffer_spi_adc[pru_spi_offset], context->analogIn); #else - for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++) { + for(unsigned int n = 0; n < context->analogInChannels * context->analogFrames; n++) { context->analogIn[n] = (float)pru_buffer_spi_adc[n + pru_spi_offset] / 65536.0f; } #endif if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { // Initialize the output buffer with the values that were in the last frame of the previous output - for(unsigned int ch = 0; ch < context->analogChannels; ch++){ + for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){ for(unsigned int n = 0; n < context->analogFrames; n++){ - context->analogOut[n * context->analogChannels + ch] = last_analog_out_frame[ch]; + context->analogOut[n * context->analogOutChannels + ch] = last_analog_out_frame[ch]; } } } else { // Outputs are 0 unless set otherwise - memset(context->analogOut, 0, context->analogChannels * context->analogFrames * sizeof(float)); + memset(context->analogOut, 0, context->analogOutChannels * context->analogFrames * sizeof(float)); } } @@ -688,8 +708,8 @@ if(analog_enabled) { if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { // Remember the content of the last_analog_out_frame - for(unsigned int ch = 0; ch < context->analogChannels; ch++){ - last_analog_out_frame[ch] = context->analogOut[context->analogChannels * (context->analogFrames - 1) + ch]; + for(unsigned int ch = 0; ch < context->analogOutChannels; ch++){ + last_analog_out_frame[ch] = context->analogOut[context->analogOutChannels * (context->analogFrames - 1) + ch]; } } @@ -698,7 +718,7 @@ float_to_int16_analog(context->analogChannels * context->analogFrames, context->analogOut, (uint16_t*)&pru_buffer_spi_dac[pru_spi_offset]); #else - for(unsigned int n = 0; n < context->analogChannels * context->analogFrames; n++) { + for(unsigned int n = 0; n < context->analogOutChannels * context->analogFrames; n++) { int out = context->analogOut[n] * 65536.0f; if(out < 0) out = 0; else if(out > 65535) out = 65535; @@ -717,7 +737,7 @@ #ifdef USE_NEON_FORMAT_CONVERSION float_to_int16_audio(2 * context->audioFrames, context->audioOut, &pru_buffer_audio_dac[pru_audio_offset]); #else - for(unsigned int n = 0; n < 2 * context->audioFrames; n++) { + for(unsigned int n = 0; n < context->audioOutChannels * context->audioFrames; n++) { int out = context->audioOut[n] * 32768.0f; if(out < -32768) out = -32768; else if(out > 32767) out = 32767; @@ -735,9 +755,6 @@ Bela_autoScheduleAuxiliaryTasks(); - // FIXME: TESTING!! - // if(testCount > 100000) - // break; } #ifdef BELA_USE_XENOMAI_INTERRUPTS @@ -745,11 +762,6 @@ rt_intr_disable(pru_interrupt); #endif - // FIXME: TESTING - // RTIME endTime = rt_timer_read(); - // RTIME diffTime = endTime - startTime; - // rt_printf("%d blocks elapsed in %f seconds, %f Hz block rate\n", testCount, ((float)diffTime / 1.0e9), (float)testCount / ((float)diffTime / 1.0e9)); - // Tell PRU to stop pru_buffer_comm[PRU_SHOULD_STOP] = 1;
--- a/core/RTAudio.cpp Thu Jun 23 18:15:26 2016 +0100 +++ b/core/RTAudio.cpp Thu Jun 23 18:17:35 2016 +0100 @@ -177,28 +177,39 @@ // Initialise the rendering environment: sample rates, frame counts, numbers of channels gContext.audioSampleRate = 44100.0; - gContext.audioChannels = 2; + + // TODO: settings a different number of channels for inputs and outputs is not yet supported + gContext.audioInChannels = 2; + gContext.audioOutChannels = 2; if(settings->useAnalog) { gContext.audioFrames = settings->periodSize; gContext.analogFrames = gContext.audioFrames * 4 / settings->numAnalogChannels; - gContext.analogChannels = settings->numAnalogChannels; + // TODO: settings a different number of channels for inputs and outputs is not yet supported + gContext.analogInChannels = settings->numAnalogChannels; + gContext.analogOutChannels = settings->numAnalogChannels; gContext.analogSampleRate = gContext.audioSampleRate * 4.0 / (float)settings->numAnalogChannels; } else { gContext.audioFrames = settings->periodSize; gContext.analogFrames = 0; - gContext.analogChannels = 0; + gContext.analogInChannels = 0; + gContext.analogOutChannels = 0; gContext.analogSampleRate = 0; } + if(gContext.analogInChannels != gContext.analogOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return -1; + } + unsigned int analogChannels = gContext.analogInChannels; // Sanity check the combination of channels and period size - if( gContext.analogChannels != 0 && ((gContext.analogChannels <= 4 && gContext.analogFrames < 2) || - (gContext.analogChannels <= 2 && gContext.analogFrames < 4)) ) + if( analogChannels != 0 && ((analogChannels <= 4 && gContext.analogFrames < 2) || + (analogChannels <= 2 && gContext.analogFrames < 4)) ) { - cout << "Error: " << gContext.analogChannels << " channels and period size of " << gContext.analogFrames << " not supported.\n"; + cout << "Error: " << analogChannels << " channels and period size of " << gContext.analogFrames << " not supported.\n"; return 1; } @@ -231,7 +242,12 @@ } // Get the PRU memory buffers ready to go - if(gPRU->initialise(settings->pruNumber, gContext.analogFrames, gContext.analogChannels, + if(gContext.analogInChannels != gContext.analogOutChannels){ + printf("Error: TODO: a different number of channels for inputs and outputs is not yet supported\n"); + return 1; + } + + if(gPRU->initialise(settings->pruNumber, gContext.analogFrames, analogChannels, settings->numMuxChannels, true)) { cout << "Error: unable to initialise PRU\n"; return 1;
--- a/examples/01-Basics/passthrough/render.cpp Thu Jun 23 18:15:26 2016 +0100 +++ b/examples/01-Basics/passthrough/render.cpp Thu Jun 23 18:17:35 2016 +0100 @@ -22,37 +22,45 @@ */ #include <Bela.h> -#include <rtdk.h> +#include <Scope.h> + +Scope scope; bool setup(BelaContext *context, void *userData) { // Nothing to do here... + printf("%d %d\n", context->audioInChannels, context->audioOutChannels); + scope.setup(8, 44100); return true; } void render(BelaContext *context, void *userData) { + static const unsigned int audioChannels = min(context->audioInChannels, context->audioOutChannels); + static const unsigned int analogChannels = min(context->analogInChannels, context->analogOutChannels); + // Simplest possible case: pass inputs through to outputs for(unsigned int n = 0; n < context->audioFrames; n++) { - for(unsigned int ch = 0; ch < context->audioChannels; ch++){ + for(unsigned int ch = 0; ch < audioChannels; ch++){ // Two equivalent ways to write this code // The long way, using the buffers directly: - // context->audioOut[n * context->audioChannels + ch] = - // context->audioIn[n * context->audioChannels + ch]; + // context->audioOut[n * context->audioOutChannels + ch] = + // context->audioIn[n * context->audioInChannels + ch]; // Or using the macros: audioWrite(context, n, ch, audioRead(context, n, ch)); } } - // Same with analog channelss + // Same with analog channels for(unsigned int n = 0; n < context->analogFrames; n++) { - for(unsigned int ch = 0; ch < context->analogChannels; ch++) { + for(unsigned int ch = 0; ch < analogChannels; ch++) { // Two equivalent ways to write this code // The long way, using the buffers directly: - // context->analogOut[n * context->analogChannels + ch] = context->analogIn[n * context->analogChannels + ch]; + // context->analogOut[n * context->analogOutChannels + ch] = + // context->analogIn[n * context->analogInChannels + ch]; // Or using the macros: analogWrite(context, n, ch, analogRead(context, n, ch));
--- a/include/Bela.h Thu Jun 23 18:15:26 2016 +0100 +++ b/include/Bela.h Thu Jun 23 18:17:35 2016 +0100 @@ -206,8 +206,10 @@ /// Number of audio frames per period const uint32_t audioFrames; - /// Number of audio channels (currently always 2) - const uint32_t audioChannels; + /// Number of input audio channels + const uint32_t audioInChannels; + /// Number of output audio channels + const uint32_t audioOutChannels; /// Audio sample rate in Hz (currently always 44100.0) const float audioSampleRate; @@ -216,10 +218,15 @@ /// This will be 0 if analog I/O is disabled. const uint32_t analogFrames; - /// \brief Number of analog channels + /// \brief Number of input analog channels /// - /// This could take a value of 8, 4 or 2. This will be 0 if analog I/O is disabled. - const uint32_t analogChannels; + /// This will be 0 if analog I/O is disabled. + const uint32_t analogInChannels; + + /// \brief Number of output analog channels + /// + /// This will be 0 if analog I/O is disabled. + const uint32_t analogOutChannels; /// \brief Analog sample rate in Hz ///
--- a/include/PRU.h Thu Jun 23 18:15:26 2016 +0100 +++ b/include/PRU.h Thu Jun 23 18:17:35 2016 +0100 @@ -55,8 +55,10 @@ /// Number of audio frames per period uint32_t audioFrames; - /// Number of audio channels (currently always 2) - uint32_t audioChannels; + /// Number of input audio channels + uint32_t audioInChannels; + /// Number of output audio channels + uint32_t audioOutChannels; /// Audio sample rate in Hz (currently always 44100.0) float audioSampleRate; @@ -65,10 +67,15 @@ /// This will be 0 if analog I/O is disabled. uint32_t analogFrames; - /// \brief Number of analog channels + /// \brief Number of input analog channels /// - /// This could take a value of 8, 4 or 2. This will be 0 if analog I/O is disabled. - uint32_t analogChannels; + /// This will be 0 if analog I/O is disabled. + uint32_t analogInChannels; + + /// \brief Number of output analog channels + /// + /// This will be 0 if analog I/O is disabled. + uint32_t analogOutChannels; /// \brief Analog sample rate in Hz ///
--- a/include/Utilities.h Thu Jun 23 18:15:26 2016 +0100 +++ b/include/Utilities.h Thu Jun 23 18:17:35 2016 +0100 @@ -294,26 +294,36 @@ */ static inline float constrain(float x, float min_val, float max_val); +/** + * Returns the maximum of two numbers + */ +static inline float min(float x, float y); + +/** + * Returns the minimum of two numbers + */ +static inline float max(float x, float y); + /** @} */ // audioRead() // // Returns the value of the given audio input at the given frame number. static inline float audioRead(BelaContext *context, int frame, int channel) { - return context->audioIn[frame * context->audioChannels + channel]; + return context->audioIn[frame * context->audioInChannels + channel]; } // audioWrite() // // Sets a given audio output channel to a value for the current frame static inline void audioWrite(BelaContext *context, int frame, int channel, float value) { - context->audioOut[frame * context->audioChannels + channel] = value; + context->audioOut[frame * context->audioOutChannels + channel] = value; } // analogRead() // // Returns the value of the given analog input at the given frame number. static inline float analogRead(BelaContext *context, int frame, int channel) { - return context->analogIn[frame * context->analogChannels + channel]; + return context->analogIn[frame * context->analogInChannels + channel]; } // analogWrite() @@ -323,17 +333,17 @@ static inline void analogWrite(BelaContext *context, int frame, int channel, float value) { if(context->flags & BELA_FLAG_ANALOG_OUTPUTS_PERSIST) { for(unsigned int f = frame; f < context->analogFrames; f++) - context->analogOut[frame * context->analogChannels + channel] = value; + context->analogOut[frame * context->analogOutChannels + channel] = value; } else - context->analogOut[frame * context->analogChannels + channel] = value; + context->analogOut[frame * context->analogOutChannels + channel] = value; } // analogWriteOnce() // // Sets a given channel to a value for only the current frame static inline void analogWriteOnce(BelaContext *context, int frame, int channel, float value) { - context->analogOut[frame * context->analogChannels + channel] = value; + context->analogOut[frame * context->analogOutChannels + channel] = value; } // digitalRead() @@ -412,4 +422,12 @@ return x; } +static inline float max(float x, float y){ + return x > y ? x : y; +} + +static inline float min(float x, float y){ + return x < y ? x : y; +} + #endif /* UTILITIES_H_ */