# HG changeset patch
# User andrewm
# Date 1433007272 18000
# Node ID be427da6fb9c5fd4271ecbc24c3b17b39efcdca4
# Parent bb40e7e06b8c966e5edd95543d75b20f80dfb147
Removed old testing code that stopped audio after 10 seconds; command line parameter updates; D-Box updates (not fully working yet)
diff -r bb40e7e06b8c -r be427da6fb9c .cproject
--- a/.cproject Thu May 28 17:48:42 2015 -0400
+++ b/.cproject Sat May 30 12:34:32 2015 -0500
@@ -92,7 +92,7 @@
-
+
@@ -167,6 +167,7 @@
@@ -181,7 +182,7 @@
-
+
diff -r bb40e7e06b8c -r be427da6fb9c core/PRU.cpp
--- a/core/PRU.cpp Thu May 28 17:48:42 2015 -0400
+++ b/core/PRU.cpp Sat May 30 12:34:32 2015 -0500
@@ -420,10 +420,13 @@
// Main loop to read and write data from/to PRU
void PRU::loop(RT_INTR *pru_interrupt, void *userData)
{
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
+ 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;
+ RTIME sleepTime = PRU_SAMPLE_INTERVAL_NS * (context->analogChannels / 2) * context->analogFrames / 4;
+#endif
- RTIME irqTimeout = PRU_SAMPLE_INTERVAL_NS * 1024; // Timeout for PRU interrupt: about 10ms, much longer than any expected period
float *lastAnalogOutFrame;
uint32_t *digitalBuffer0, *digitalBuffer1, *lastDigitalBuffer;
uint32_t pru_audio_offset, pru_spi_offset;
@@ -468,10 +471,16 @@
}
// TESTING
- uint32_t testCount = 0;
+ // uint32_t testCount = 0;
// RTIME startTime = rt_timer_read();
+#ifndef BEAGLERT_USE_XENOMAI_INTERRUPTS
+ // Which buffer the PRU was last processing
+ uint32_t lastPRUBuffer = 0;
+#endif
+
while(!gShouldStop) {
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
// Wait for PRU to move to change buffers;
// PRU will send an interrupts which we wait for
rt_intr_enable(pru_interrupt);
@@ -489,6 +498,14 @@
// Clear pending PRU interrupt
prussdrv_pru_clear_event(PRU_EVTOUT_1, PRU1_ARM_INTERRUPT);
+#else
+ // Poll
+ while(pru_buffer_comm[PRU_CURRENT_BUFFER] == lastPRUBuffer && !gShouldStop) {
+ rt_task_sleep(sleepTime);
+ }
+
+ lastPRUBuffer = pru_buffer_comm[PRU_CURRENT_BUFFER];
+#endif
if(gShouldStop)
break;
@@ -512,7 +529,7 @@
// FIXME: some sort of margin is needed here to prevent the audio
// code from completely eating the Linux system
- testCount++;
+ // testCount++;
//rt_task_sleep(sleepTime*4);
//rt_task_sleep(sleepTime/4);
@@ -605,12 +622,14 @@
}
// FIXME: TESTING!!
- if(testCount > 100000)
- break;
+ // if(testCount > 100000)
+ // break;
}
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
// Turn off the interrupt for the PRU if it isn't already off
rt_intr_disable(pru_interrupt);
+#endif
// FIXME: TESTING
// RTIME endTime = rt_timer_read();
diff -r bb40e7e06b8c -r be427da6fb9c core/RTAudio.cpp
--- a/core/RTAudio.cpp Thu May 28 17:48:42 2015 -0400
+++ b/core/RTAudio.cpp Sat May 30 12:34:32 2015 -0500
@@ -52,7 +52,9 @@
// Real-time tasks and objects
RT_TASK gRTAudioThread;
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
RT_INTR gRTAudioInterrupt;
+#endif
PRU *gPRU = 0;
I2c_Codec *gAudioCodec = 0;
@@ -257,8 +259,11 @@
}
}
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
gPRU->loop(&gRTAudioInterrupt, gUserData);
-
+#else
+ gPRU->loop(0, gUserData);
+#endif
// Now clean up
// gPRU->waitForFinish();
gPRU->disable();
@@ -341,12 +346,14 @@
return -1;
}
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
// Create an interrupt which the audio thread receives from the PRU
int result = 0;
if((result = rt_intr_create(&gRTAudioInterrupt, gRTAudioInterruptName, PRU_RTAUDIO_IRQ, I_NOAUTOENA)) != 0) {
cout << "Error: unable to create Xenomai interrupt for PRU (error " << result << ")" << endl;
return -1;
}
+#endif
// Start all RT threads
if(rt_task_start(&gRTAudioThread, &audioLoop, 0)) {
@@ -413,7 +420,9 @@
gAuxTasks.clear();
// Delete the audio task and its interrupt
+#ifdef BEAGLERT_USE_XENOMAI_INTERRUPTS
rt_intr_delete(&gRTAudioInterrupt);
+#endif
rt_task_delete(&gRTAudioThread);
if(gPRU != 0)
diff -r bb40e7e06b8c -r be427da6fb9c core/RTAudioCommandLine.cpp
--- a/core/RTAudioCommandLine.cpp Thu May 28 17:48:42 2015 -0400
+++ b/core/RTAudioCommandLine.cpp Sat May 30 12:34:32 2015 -0500
@@ -24,22 +24,22 @@
{
{"period", 1, NULL, 'p'},
{"verbose", 0, NULL, 'v'},
- {"use-analog", 1, NULL, 'm'},
- {"use-digital-gpio", 1, NULL, 'g'},
+ {"use-analog", 1, NULL, 'N'},
+ {"use-digital", 1, NULL, 'G'},
{"analog-channels", 1, NULL, 'C'},
- {"digital-channels", 1, NULL, 'G'},
+ {"digital-channels", 1, NULL, 'B'},
{"mute-speaker", 1, NULL, 'M'},
{"dac-level", 1, NULL, 'D'},
{"adc-level", 1, NULL, 'A'},
{"hp-level", 1, NULL, 'H'},
- {"receive-port", 1, NULL, 'r'},
- {"transmit-port", 1, NULL, 't'},
- {"server-name", 1, NULL, 's'},
+ {"receive-port", 1, NULL, 'R'},
+ {"transmit-port", 1, NULL, 'T'},
+ {"server-name", 1, NULL, 'S'},
{"pru-file", 1, NULL, OPT_PRU_FILE},
{NULL, 0, NULL, 0}
};
-const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:g:G:r:t:s:";
+const char gDefaultShortOptions[] = "p:vN:M:C:D:A:H:G:B:R:T:S:";
// This function sets the default settings for the BeagleRTInitSettings structure
void BeagleRT_defaultSettings(BeagleRTInitSettings *settings)
@@ -150,10 +150,10 @@
case 'v':
settings->verbose = 1;
break;
- case 'm':
+ case 'N':
settings->useAnalog = atoi(optarg);
break;
- case 'g':
+ case 'G':
settings->useDigital = atoi(optarg);
settings->numDigitalChannels = 0;
break;
@@ -166,7 +166,7 @@
else
settings->numAnalogChannels = 2;
break;
- case 'G':
+ case 'B':
settings->numDigitalChannels = atoi(optarg);
if(settings->numDigitalChannels >= 16)
settings->numDigitalChannels = 16;
@@ -188,13 +188,13 @@
case 'H':
settings->headphoneLevel = atof(optarg);
break;
- case 'r':
+ case 'R':
settings->receivePort = atoi(optarg);
break;
- case 't':
+ case 'T':
settings->transmitPort = atoi(optarg);
break;
- case 's':
+ case 'S':
if(strlen(optarg)serverName, optarg);
else
diff -r bb40e7e06b8c -r be427da6fb9c projects/d-box/FeedbackOscillator.cpp
--- a/projects/d-box/FeedbackOscillator.cpp Thu May 28 17:48:42 2015 -0400
+++ b/projects/d-box/FeedbackOscillator.cpp Sat May 30 12:34:32 2015 -0500
@@ -58,23 +58,11 @@
// Process one sample and store the output value
// Returns true if the wavetable needs rendering
-int FeedbackOscillator::process(uint16_t input, uint16_t *output) {
- float inFloat = input / 65536.0;
- float outFloat = coeffs[COEFF_B0] * inFloat + coeffs[COEFF_B1] * lastInput - coeffs[COEFF_A1] * lastOutput;
+int FeedbackOscillator::process(float input, float *output) {
+ float outFloat = coeffs[COEFF_B0] * input + coeffs[COEFF_B1] * lastInput - coeffs[COEFF_A1] * lastOutput;
int requestRenderLength = 0;
- //outFloat *= 2.0;
-
- int intOut = outFloat * 65536.0 + 32768;
- if(intOut > 65535)
- intOut = 65535;
- if(intOut < 0)
- intOut = 0;
- //intOut = (intOut & 0xFF) << 8;
- //if(intOut > 65535)
- // intOut = 65535;
-
- *output = (uint16_t)intOut;
+ *output = outFloat;
if(canTrigger && outFloat > 0 && lastOutput <= 0) {
triggered = true;
@@ -106,7 +94,7 @@
sampleCount++;
lastOutput = outFloat;
- lastInput = inFloat;
+ lastInput = input;
return requestRenderLength;
}
diff -r bb40e7e06b8c -r be427da6fb9c projects/d-box/FeedbackOscillator.h
--- a/projects/d-box/FeedbackOscillator.h Thu May 28 17:48:42 2015 -0400
+++ b/projects/d-box/FeedbackOscillator.h Sat May 30 12:34:32 2015 -0500
@@ -8,8 +8,6 @@
#ifndef FEEDBACKOSCILLATOR_H
#define FEEDBACKOSCILLATOR_H
-#include
-
class FeedbackOscillator
{
public:
@@ -21,7 +19,7 @@
// Process one sample and store the output value
// Returns the length of table to interpolate; or 0 if nothing to process further
- int process(uint16_t input, uint16_t *output);
+ int process(float input, float *output);
float *wavetable() { return wavetableRead; }
diff -r bb40e7e06b8c -r be427da6fb9c projects/d-box/main.cpp
--- a/projects/d-box/main.cpp Thu May 28 17:48:42 2015 -0400
+++ b/projects/d-box/main.cpp Sat May 30 12:34:32 2015 -0500
@@ -33,7 +33,7 @@
// get_opt_long
#include
-#include "../../include/RTAudio.h"
+#include "../../include/BeagleRT.h"
#include "config.h"
#include "sensors.h"
#include "OscillatorBank.h"
@@ -262,11 +262,13 @@
}
-void parseArguments(arg_data args, RTAudioSettings *settings)
+void parseArguments(arg_data args, BeagleRTInitSettings *settings)
{
// Default filename;
gPartialFilename = strdup("D-Box_sound_250_60_40_h88_2.txt");
+ const int kOptionAudioTest = 1000;
+
// TODO: complete this
struct option long_option[] =
{
@@ -274,10 +276,10 @@
{"audioin", 1, NULL, 'i'},
{"file", 1, NULL, 'f'},
{"keyboard", 1, NULL, 'k'},
- {"audio-test", 0, NULL, 'T'},
- {"sensor-type", 1, NULL, 'S'},
- {"sensor0", 1, NULL, 'Q'},
- {"sensor1", 1, NULL, 'R'},
+ {"audio-test", 0, NULL, kOptionAudioTest},
+ {"sensor-type", 1, NULL, 't'},
+ {"sensor0", 1, NULL, 'q'},
+ {"sensor1", 1, NULL, 'r'},
{"log", 1, NULL, 'l'},
{"usesd", 1, NULL, 'u'},
{"oversamp", 1, NULL, 'o'},
@@ -293,7 +295,7 @@
while (1)
{
int c;
- if ((c = BeagleRT_getopt_long(args.argc, args.argv, "hf:ki:sTQ:R:S:l:u:o:n:g:", long_option, settings)) < 0)
+ if ((c = BeagleRT_getopt_long(args.argc, args.argv, "hf:ki:sq:r:t:l:u:o:n:g:", long_option, settings)) < 0)
break;
switch (c)
{
@@ -313,16 +315,16 @@
case 's':
forceSensors = true;
break;
- case 'T':
+ case kOptionAudioTest:
useAudioTest = true;
break;
- case 'S':
+ case 't':
sensorType = atoi(optarg);
break;
- case 'Q':
+ case 'q':
touchSensor0Address = atoi(optarg);
break;
- case 'R':
+ case 'r':
touchSensor1Address = atoi(optarg);
break;
case 'l':
@@ -361,7 +363,7 @@
int main(int argc, char *argv[])
{
- RTAudioSettings settings; // Standard audio settings
+ BeagleRTInitSettings settings; // Standard audio settings
RT_TASK rtSensorThread;
const char rtSensorThreadName[] = "dbox-sensor";
int oscBankHopSize;
@@ -371,7 +373,7 @@
args.argv = argv;
parseArguments(args, &settings);
- setVerboseLevel(gVerbose);
+ BeagleRT_setVerboseLevel(gVerbose);
if(gVerbose == 1 && useAudioTest)
cout << "main() : running in audio test mode" << endl;
@@ -415,7 +417,7 @@
if(gVerbose==1)
cout << "main() : creating control thread" << endl;
- if(rt_task_create(&rtSensorThread, rtSensorThreadName, 0, 95, T_JOINABLE | T_FPU)) {
+ if(rt_task_create(&rtSensorThread, rtSensorThreadName, 0, BEAGLERT_AUDIO_PRIORITY - 5, T_JOINABLE | T_FPU)) {
cout << "Error:unable to create Xenomai control thread" << endl;
return -1;
}
diff -r bb40e7e06b8c -r be427da6fb9c projects/d-box/render.cpp
--- a/projects/d-box/render.cpp Thu May 28 17:48:42 2015 -0400
+++ b/projects/d-box/render.cpp Sat May 30 12:34:32 2015 -0500
@@ -5,7 +5,7 @@
* Author: Victor Zappi
*/
-#include "../../include/RTAudio.h"
+#include "../../include/BeagleRT.h"
#include "../../include/PRU.h"
#include "StatusLED.h"
#include "config.h"
@@ -39,7 +39,6 @@
#define ADC_PIN6 6
#define ADC_PIN7 7
-
#define N_OCT 4.0 // maximum number of octaves on sensor 1
extern vector gOscBanks;
@@ -49,7 +48,6 @@
extern StatusLED gStatusLED;
extern bool gIsLoading;
extern bool gAudioIn;
-extern int gPeriodSize;
float *gOscillatorBuffer1, *gOscillatorBuffer2;
float *gOscillatorBufferRead, *gOscillatorBufferWrite;
@@ -78,7 +76,7 @@
// sensor 0.
extern float gSensor0LatestTouchPos;
extern int gSensor0LatestTouchNum;
-uint16_t gPitchLatestInput = 0;
+float gPitchLatestInput = 0;
extern float gSensor1LatestTouchPos[];
//extern float gSensor1LatestTouchSizes[];
@@ -94,9 +92,9 @@
// Loop points from matrix input 4
const int gLoopPointsInputBufferSize = 256;
-uint16_t gLoopPointsInputBuffer[gLoopPointsInputBufferSize];
+float gLoopPointsInputBuffer[gLoopPointsInputBufferSize];
int gLoopPointsInputBufferPointer = 0;
-int gLoopPointMin = 0, gLoopPointMax = 0;
+float gLoopPointMin = 0, gLoopPointMax = 0;
// multiplier to activate or mute audio in
int audioInStatus = 0;
@@ -106,7 +104,7 @@
// pitch vars
float octaveSplitter;
-u_int16_t semitones[((int)N_OCT*12)+1];
+float semitones[((int)N_OCT*12)+1];
float deltaTouch = 0;
float deltaWeightP = 0.5;
float deltaWeightI = 0.0005;
@@ -143,22 +141,21 @@
float *tableIn, float *tableOut,
float *sineTable, float sineMix);
-inline uint16_t hysteresis_oscillator(uint16_t input, uint16_t risingThreshold,
- uint16_t fallingThreshold, bool *rising);
+inline float hysteresis_oscillator(float input, float risingThreshold,
+ float fallingThreshold, bool *rising);
+
+void render_medium_prio();
+void render_low_prio();
#ifdef DBOX_CAPE_TEST
void render_capetest(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
uint16_t *matrixIn, uint16_t *matrixOut);
#endif
-bool initialise_render(int numMatrixChannels, int numAudioChannels,
- int numMatrixFramesPerPeriod,
- int numAudioFramesPerPeriod,
- float matrixSampleRate, float audioSampleRate,
- void *userData) {
+bool initialise_render(BeagleRTContext *context, void *userData) {
int oscBankHopSize = *(int *)userData;
- if(numMatrixChannels != 8) {
+ if(context->analogChannels != 8) {
printf("Error: D-Box needs matrix enabled with 8 channels.\n");
return false;
}
@@ -166,19 +163,19 @@
// Allocate two buffers for rendering oscillator bank samples
// One will be used for writing in the background while the other is used for reading
// on the audio thread. 8-byte alignment needed for the NEON code.
- if(posix_memalign((void **)&gOscillatorBuffer1, 8, oscBankHopSize * gNumAudioChannels * sizeof(float))) {
+ if(posix_memalign((void **)&gOscillatorBuffer1, 8, oscBankHopSize * context->audioChannels * sizeof(float))) {
printf("Error allocating render buffers\n");
return false;
}
- if(posix_memalign((void **)&gOscillatorBuffer2, 8, oscBankHopSize * gNumAudioChannels * sizeof(float))) {
+ if(posix_memalign((void **)&gOscillatorBuffer2, 8, oscBankHopSize * context->audioChannels * sizeof(float))) {
printf("Error allocating render buffers\n");
return false;
}
gOscillatorBufferWrite = gOscillatorBuffer1;
gOscillatorBufferRead = gOscillatorBuffer2;
- memset(gOscillatorBuffer1, 0, oscBankHopSize * gNumAudioChannels * sizeof(float));
- memset(gOscillatorBuffer2, 0, oscBankHopSize * gNumAudioChannels * sizeof(float));
+ memset(gOscillatorBuffer1, 0, oscBankHopSize * context->audioChannels * sizeof(float));
+ memset(gOscillatorBuffer2, 0, oscBankHopSize * context->audioChannels * sizeof(float));
// Initialise the dynamic wavetable used by the oscillator bank
// It should match the size of the static one already allocated in the OscillatorBank object
@@ -189,18 +186,18 @@
return false;
}
- gFeedbackOscillator.initialise(8192, 10.0, matrixSampleRate);
+ gFeedbackOscillator.initialise(8192, 10.0, context->analogSampleRate);
for(int n = 0; n < gDynamicWavetableLength + 1; n++)
gDynamicWavetable[n] = 0;
// pitch
- float midPos = (float)65535/2.0;
- octaveSplitter = round((float)65535/(N_OCT));
+ float midPos = 0.5;
+ octaveSplitter = 1.0 / N_OCT;
int numOfSemi = 12*N_OCT;
int middleSemitone = 12*N_OCT/2;
int lastSemitone = middleSemitone+numOfSemi/2;
- float inc = (float)65535/(N_OCT*12.0);
+ float inc = 1.0 / (N_OCT*12.0);
int i = -1;
for(int semi=middleSemitone; semi<=lastSemitone; semi++)
semitones[semi] = ( midPos + (++i)*inc) + 0.5;
@@ -212,7 +209,7 @@
audioInStatus = 1;
// filter
- blockSize = 2*gPeriodSize;
+ blockSize = context->audioFrames;
filterState[0] = (ne10_float32_t *) NE10_MALLOC ((FILTER_TAP_NUM+blockSize-1) * sizeof (ne10_float32_t));
filterState[1] = (ne10_float32_t *) NE10_MALLOC ((FILTER_TAP_NUM+blockSize-1) * sizeof (ne10_float32_t));
filterIn[0] = (ne10_float32_t *) NE10_MALLOC (blockSize * sizeof (ne10_float32_t));
@@ -223,24 +220,23 @@
ne10_fir_init_float(&filter[1], FILTER_TAP_NUM, filterTaps, filterState[1], blockSize);
// peak outputs
- PeakBurst[0].setAttackRate(.00001 * matrixSampleRate);
- PeakBurst[1].setAttackRate(.00001 * matrixSampleRate);
- PeakBurst[0].setDecayRate(.5 * matrixSampleRate);
- PeakBurst[1].setDecayRate(.5 * matrixSampleRate);
+ PeakBurst[0].setAttackRate(.00001 * context->analogSampleRate);
+ PeakBurst[1].setAttackRate(.00001 * context->analogSampleRate);
+ PeakBurst[0].setDecayRate(.5 * context->analogSampleRate);
+ PeakBurst[1].setDecayRate(.5 * context->analogSampleRate);
PeakBurst[0].setSustainLevel(0.0);
PeakBurst[1].setSustainLevel(0.0);
// Initialise auxiliary tasks
- if((gMediumPriorityRender = createAuxiliaryTaskLoop(&render_medium_prio, 90, "dbox-calculation-medium")) == 0)
+ if((gMediumPriorityRender = BeagleRT_createAuxiliaryTask(&render_medium_prio, BEAGLERT_AUDIO_PRIORITY - 10, "dbox-calculation-medium")) == 0)
return false;
- if((gLowPriorityRender = createAuxiliaryTaskLoop(&render_low_prio, 85, "dbox-calculation-low")) == 0)
+ if((gLowPriorityRender = BeagleRT_createAuxiliaryTask(&render_low_prio, BEAGLERT_AUDIO_PRIORITY - 15, "dbox-calculation-low")) == 0)
return false;
return true;
}
-void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
- uint16_t *matrixIn, uint16_t *matrixOut)
+void render(BeagleRTContext *context, void *userData)
{
#ifdef DBOX_CAPE_TEST
render_capetest(numMatrixFrames, numAudioFrames, audioIn, audioOut, matrixIn, matrixOut);
@@ -250,10 +246,10 @@
if(gOscBanks[gCurrentOscBank]->state==bank_playing)
{
- assert(gNumAudioChannels == 2);
+ assert(context->audioChannels == 2);
#ifdef OLD_OSCBANK
- memset(audioOut, 0, numAudioFrames * gNumAudioChannels * sizeof(float));
+ memset(audioOut, 0, numAudioFrames * * sizeof(float));
/* Render the oscillator bank. The oscillator bank function is written in NEON assembly
* and it strips out all extra checks, so find out in advance whether we can render a whole
@@ -290,18 +286,18 @@
gOscBanks[gCurrentOscBank]->oscillatorAmplitudeDerivatives,
gDynamicWavetable/*gOscBanks[gCurrentOscBank]->lookupTable*/);
framesRemaining -= gOscBanks[gCurrentOscBank]->hopCounter;
- audioOutWithOffset += gNumAudioChannels * gOscBanks[gCurrentOscBank]->hopCounter;
+ audioOutWithOffset += * gOscBanks[gCurrentOscBank]->hopCounter;
gOscBanks[gCurrentOscBank]->sampleCount += gOscBanks[gCurrentOscBank]->hopCounter;
gOscBanks[gCurrentOscBank]->nextHop();
}
}
#else
- for(int n = 0; n < numAudioFrames; n++) {
- audioOut[2*n] = gOscillatorBufferRead[gOscillatorBufferReadPointer++]+audioIn[2*n]*audioInStatus;
- audioOut[2*n + 1] = gOscillatorBufferRead[gOscillatorBufferReadPointer++]+audioIn[2*n+1]*audioInStatus;
+ for(unsigned int n = 0; n < context->audioFrames; n++) {
+ context->audioOut[2*n] = gOscillatorBufferRead[gOscillatorBufferReadPointer++]+context->audioIn[2*n]*audioInStatus;
+ context->audioOut[2*n + 1] = gOscillatorBufferRead[gOscillatorBufferReadPointer++]+context->audioIn[2*n+1]*audioInStatus;
- filterIn[0][n] = fabs(audioIn[2*n]); // rectify for peak detection in 1
- filterIn[1][n] = fabs(audioIn[2*n+1]); // rectify for peak detection in 2
+ filterIn[0][n] = fabs(context->audioIn[2*n]); // rectify for peak detection in 1
+ filterIn[1][n] = fabs(context->audioIn[2*n+1]); // rectify for peak detection in 2
/* FIXME why doesn't this work? */
/*
@@ -326,19 +322,19 @@
gOscillatorBufferReadPointer = 0;
gOscillatorNeedsRender = true;
- scheduleAuxiliaryTask(gMediumPriorityRender);
+ BeagleRT_scheduleAuxiliaryTask(gMediumPriorityRender);
}
}
#endif
}
else
{
- for(int n = 0; n < numAudioFrames; n++) {
- audioOut[2*n] = audioIn[2*n]*audioInStatus;
- audioOut[2*n + 1] = audioIn[2*n+1]*audioInStatus;
+ for(unsigned int n = 0; n < context->audioFrames; n++) {
+ context->audioOut[2*n] = context->audioIn[2*n]*audioInStatus;
+ context->audioOut[2*n + 1] = context->audioIn[2*n+1]*audioInStatus;
- filterIn[0][n] = fabs(audioIn[2*n]); // rectify for peak detection in 1
- filterIn[1][n] = fabs(audioIn[2*n+1]); // rectify for peak detection in 2
+ filterIn[0][n] = fabs(context->audioIn[2*n]); // rectify for peak detection in 1
+ filterIn[1][n] = fabs(context->audioIn[2*n+1]); // rectify for peak detection in 2
}
}
@@ -346,7 +342,7 @@
ne10_fir_float_neon(&filter[0], filterIn[0], filterOut[0], blockSize);
ne10_fir_float_neon(&filter[1], filterIn[1], filterOut[1], blockSize);
- for(int n = 0; n < numMatrixFrames; n++) {
+ for(unsigned int n = 0; n < context->analogFrames; n++) {
/* Matrix Out 0, In 0
@@ -354,12 +350,12 @@
* CV loop
* Controls pitch of sound
*/
- int touchPosInt = gSensor0LatestTouchPos * 65536.0;
+ float touchPosInt = gSensor0LatestTouchPos;
if(touchPosInt < 0) touchPosInt = 0;
- if(touchPosInt > 65535) touchPosInt = 65535;
- matrixOut[n*8 + DAC_PIN0] = touchPosInt;
+ if(touchPosInt > 1.0) touchPosInt = 1.0;
+ context->analogOut[n*8 + DAC_PIN0] = touchPosInt;
- gPitchLatestInput = matrixIn[n*8 + ADC_PIN0];
+ gPitchLatestInput = context->analogIn[n*8 + ADC_PIN0];
/* Matrix Out 7
@@ -372,17 +368,17 @@
if(gSensor0LatestTouchNum>0)
{
// current pitch is gPitchLatestInput, already retrieved
- semitoneIndex = ( ( (float)gPitchLatestInput / 65535)*12*N_OCT )+0.5; // closest semitone
+ semitoneIndex = ( gPitchLatestInput * 12 * N_OCT )+0.5; // closest semitone
deltaTarget = (semitones[semitoneIndex]-gPitchLatestInput); // delta between pitch and target
deltaTouch += deltaTarget*deltaWeightI; // update feedback [previous + current]
}
else
deltaTouch = 0;
- int nextOut = touchPosInt + deltaTarget*deltaWeightP + deltaTouch; // add feedback to touch -> next out
+ float nextOut = touchPosInt + deltaTarget*deltaWeightP + deltaTouch; // add feedback to touch -> next out
if(nextOut < 0) nextOut = 0; // clamp
- if(nextOut > 65535) nextOut = 65535; // clamp
- matrixOut[n*8 + DAC_PIN7] = nextOut; // send next nextOut
+ if(nextOut > 1.0) nextOut = 1.0; // clamp
+ context->analogOut[n*8 + DAC_PIN7] = nextOut; // send next nextOut
/*
@@ -392,7 +388,8 @@
* Controls speed of playback
*/
bool wasRising = gSpeedHysteresisOscillatorRising;
- matrixOut[n*8 + DAC_PIN1] = hysteresis_oscillator(matrixIn[n*8 + ADC_PIN1], 48000, 16000, &gSpeedHysteresisOscillatorRising);
+ context->analogOut[n*8 + DAC_PIN1] = hysteresis_oscillator(context->analogIn[n*8 + ADC_PIN1], 48000.0/65536.0,
+ 16000.0/65536.0, &gSpeedHysteresisOscillatorRising);
// Find interval of zero crossing
if(wasRising && !gSpeedHysteresisOscillatorRising) {
@@ -415,12 +412,12 @@
* Controls wavetable used for oscillator bank
*/
- int tableLength = gFeedbackOscillator.process(matrixIn[n*8 + ADC_PIN2], &matrixOut[n*8 + DAC_PIN2]);
+ int tableLength = gFeedbackOscillator.process(context->analogIn[n*8 + ADC_PIN2], &context->analogOut[n*8 + DAC_PIN2]);
if(tableLength != 0) {
gFeedbackOscillatorTableLength = tableLength;
gFeedbackOscillatorTable = gFeedbackOscillator.wavetable();
gDynamicWavetableNeedsRender = true;
- scheduleAuxiliaryTask(gLowPriorityRender);
+ BeagleRT_scheduleAuxiliaryTask(gLowPriorityRender);
}
/*
@@ -432,10 +429,10 @@
*/
volatile int touchCount = gSensor1LatestTouchCount;
if(touchCount == 0)
- matrixOut[n*8 + DAC_PIN3] = 0;
+ context->analogOut[n*8 + DAC_PIN3] = 0;
else {
int touchIndex = (gMatrixSampleCount >> 5) % touchCount;
- matrixOut[n*8 + DAC_PIN3] = gSensor1LatestTouchPos[touchIndex] * 56000.0f;
+ context->analogOut[n*8 + DAC_PIN3] = gSensor1LatestTouchPos[touchIndex] * 56000.0f / 65536.0f;
if(touchIndex != gSensor1LastTouchIndex) {
// Just changed to a new touch output. Reset the counter.
// It will take 2*matrixFrames samples for this output to come back to the
@@ -443,33 +440,33 @@
// let's say 24 samples into it.
// FIXME this won't work for p > 2
- gSensor1InputDelayCounter = 24 + 2*numMatrixFrames;
+ gSensor1InputDelayCounter = 24 + 2*context->analogFrames;
gSensor1InputIndex = touchIndex;
}
gSensor1LastTouchIndex = touchIndex;
}
if(gSensor1InputDelayCounter-- >= 0 && touchCount > 0) {
- gSensor1MatrixTouchPos[gSensor1InputIndex] = (float)matrixIn[n*8 + ADC_PIN3] / 65536.0f;
+ gSensor1MatrixTouchPos[gSensor1InputIndex] = context->analogIn[n*8 + ADC_PIN3];
}
/* Matrix Out 4
*
* Sensor 1 last pos
*/
- touchPosInt = gSensor1LatestTouchPos[gSensor1LatestTouchIndex] * 65536.0;
+ touchPosInt = gSensor1LatestTouchPos[gSensor1LatestTouchIndex];
if(touchPosInt < 0) touchPosInt = 0;
- if(touchPosInt > 65535) touchPosInt = 65535;
- matrixOut[n*8 + DAC_PIN4] = touchPosInt;
+ if(touchPosInt > 1.0) touchPosInt = 1.0;
+ context->analogOut[n*8 + DAC_PIN4] = touchPosInt;
/* Matrix In 4
*
* Loop points selector
*/
- gLoopPointsInputBuffer[gLoopPointsInputBufferPointer++] = matrixIn[n*8 + ADC_PIN4];
+ gLoopPointsInputBuffer[gLoopPointsInputBufferPointer++] = context->analogIn[n*8 + ADC_PIN4];
if(gLoopPointsInputBufferPointer >= gLoopPointsInputBufferSize) {
// Find min and max values
- uint16_t loopMax = 0, loopMin = 65535;
+ float loopMax = 0, loopMin = 1.0;
for(int i = 0; i < gLoopPointsInputBufferSize; i++) {
if(gLoopPointsInputBuffer[i] < loopMin)
loopMin = gLoopPointsInputBuffer[i];
@@ -503,8 +500,8 @@
PeakBurst[0].process(1);
- int convAudio = burstOut*peak[0]*65535;
- matrixOut[n*8 + DAC_PIN5] = convAudio;
+ float convAudio = burstOut*peak[0];
+ context->analogOut[n*8 + DAC_PIN5] = convAudio;
prevFiltered[0] = filterOut[0][n*2+1];
if(prevFiltered[0]>1)
prevFiltered[0] = 1;
@@ -513,8 +510,8 @@
*
* Dissonance, via changing frequency motion of partials
*/
- float amount = (float)matrixIn[n*8 + ADC_PIN5] / 65536.0f;
- gOscBanks[gCurrentOscBank]->freqMovement = 1-amount;
+ float amount = (float)context->analogIn[n*8 + ADC_PIN5];
+ gOscBanks[gCurrentOscBank]->freqMovement = 1.0 - amount;
@@ -537,8 +534,8 @@
PeakBurst[1].process(1);
- convAudio = burstOut*peak[1]*65535;
- matrixOut[n*8 + DAC_PIN6] = convAudio;
+ convAudio = burstOut*peak[1];
+ context->analogOut[n*8 + DAC_PIN6] = convAudio;
prevFiltered[1] = filterOut[1][n*2+1];
if(prevFiltered[1]>1)
prevFiltered[1] = 1;
@@ -550,14 +547,14 @@
if(!gIsLoading) {
// Use hysteresis to avoid jumping back and forth between sounds
if(gOscBanks.size() > 1) {
- int input = matrixIn[n*8 + ADC_PIN6];
- const int hystValue = 16000;
+ float input = context->analogIn[n*8 + ADC_PIN6];
+ const float hystValue = 16000.0 / 65536.0;
- int upHysteresisValue = ((gCurrentOscBank + 1) * 65536 + hystValue) / gOscBanks.size();
- int downHysteresisValue = (gCurrentOscBank * 65536 - hystValue) / gOscBanks.size();
+ float upHysteresisValue = ((gCurrentOscBank + 1) + hystValue) / gOscBanks.size();
+ float downHysteresisValue = (gCurrentOscBank - hystValue) / gOscBanks.size();
if(input > upHysteresisValue || input < downHysteresisValue) {
- gNextOscBank = input * gOscBanks.size() / 65536;
+ gNextOscBank = input * gOscBanks.size();
if(gNextOscBank < 0)
gNextOscBank = 0;
if((unsigned)gNextOscBank >= gOscBanks.size())
@@ -572,8 +569,8 @@
* FSR from primary touch sensor
* Value ranges from 0-1799
*/
- gLastFSRValue = matrixIn[n*8 + ADC_PIN7] * (1799.0 / 65535.0);
- //gLastFSRValue = 1799 - matrixIn[n*8 + ADC_PIN7] * (1799.0 / 65535.0);
+ gLastFSRValue = context->analogIn[n*8 + ADC_PIN7] * 1799.0;
+ //gLastFSRValue = 1799 - context->analogIn[n*8 + ADC_PIN7] * (1799.0 / 65535.0);
//dbox_printf("%i\n",gLastFSRValue);
gMatrixSampleCount++;
@@ -590,7 +587,7 @@
gOscillatorNeedsRender = false;
/* Render one frame into the write buffer */
- memset(gOscillatorBufferWrite, 0, gOscBanks[gCurrentOscBank]->hopCounter * gNumAudioChannels * sizeof(float));
+ memset(gOscillatorBufferWrite, 0, gOscBanks[gCurrentOscBank]->hopCounter * 2 * sizeof(float)); /* assumes 2 audio channels */
oscillator_bank_neon(gOscBanks[gCurrentOscBank]->hopCounter, gOscillatorBufferWrite,
gOscBanks[gCurrentOscBank]->actPartNum, gOscBanks[gCurrentOscBank]->lookupTableSize,
@@ -600,7 +597,7 @@
gOscBanks[gCurrentOscBank]->oscillatorAmplitudeDerivatives,
/*gOscBanks[gCurrentOscBank]->lookupTable*/gDynamicWavetable);
- gOscillatorBufferWriteCurrentSize = gOscBanks[gCurrentOscBank]->hopCounter * gNumAudioChannels;
+ gOscillatorBufferWriteCurrentSize = gOscBanks[gCurrentOscBank]->hopCounter * 2;
/* Update the pitch right before the hop
* Total CV range +/- N_OCT octaves
@@ -681,7 +678,7 @@
gOscBanks[gCurrentOscBank]->lookupTable, sineMix);
}
- if(gLoopPointMin >= 60000 && gLoopPointMax >= 60000) {
+ if(gLoopPointMin >= 60000.0/65536.0 && gLoopPointMax >= 60000.0/65536.0) {
// KLUDGE!
if(gCurrentOscBank == 0)
gOscBanks[gCurrentOscBank]->setLoopHops(50, ((float)gOscBanks[gCurrentOscBank]->getLastHop() * 0.6) - 1);
@@ -689,8 +686,8 @@
gOscBanks[gCurrentOscBank]->setLoopHops(5, ((float)gOscBanks[gCurrentOscBank]->getLastHop() * 0.7) - 1);
}
else {
- float normLoopPointMin = (float)gLoopPointMin * gOscBanks[gCurrentOscBank]->getLastHop() / 65535.0;
- float normLoopPointMax = (float)gLoopPointMax * gOscBanks[gCurrentOscBank]->getLastHop() / 65535.0;
+ float normLoopPointMin = (float)gLoopPointMin * gOscBanks[gCurrentOscBank]->getLastHop();
+ float normLoopPointMax = (float)gLoopPointMax * gOscBanks[gCurrentOscBank]->getLastHop();
int intLoopPointMin = normLoopPointMin;
if(intLoopPointMin < 1)
@@ -733,7 +730,7 @@
}
// Clean up at the end of render
-void cleanup_render()
+void cleanup_render(BeagleRTContext *context, void *userData)
{
free(gOscillatorBuffer1);
free(gOscillatorBuffer2);
@@ -765,9 +762,9 @@
}
// Create a hysteresis oscillator with a matrix input and output
-inline uint16_t hysteresis_oscillator(uint16_t input, uint16_t risingThreshold, uint16_t fallingThreshold, bool *rising)
+inline float hysteresis_oscillator(float input, float risingThreshold, float fallingThreshold, bool *rising)
{
- uint16_t value;
+ float value;
if(*rising) {
if(input > risingThreshold) {
@@ -775,12 +772,12 @@
value = 0;
}
else
- value = 65535;
+ value = 1.0;
}
else {
if(input < fallingThreshold) {
*rising = true;
- value = 65535;
+ value = 1.0;
}
else
value = 0;