I am trying to call multiple AudioCallbacks simultaneously, but I can’t. I can only hear one of them. I think it can be due to the configuration of the output of each AudioCallback.
The idea is that each AudioCallback contains a different sound process and to be able to mix them later. How could I do this?
Here part of the code:
#include "daisy_seed.h"
#include "daisysp.h"
using namespace daisy;
using namespace daisysp;
DaisySeed hardware;
Oscillator osc[32];
int bin[32];
float freq[32];
void Audio0Callback(float **in, float **out, size_t size)
{
for(size_t i = 0; i < size; i++)
{
out[0][i] = osc[0].Process();
out[1][i] = osc[0].Process();
}
}
void Audio1Callback(float **in, float **out, size_t size)
{
for(size_t i = 0; i < size; i++)
{
out[0][i] = osc[1].Process();
out[1][i] = osc[1].Process();
}
}
void Audio2Callback(float **in, float **out, size_t size)
{
for(size_t i = 0; i < size; i++)
{
out[0][i] = osc[2].Process();
out[1][i] = osc[2].Process();
}
}
void SetupOsc(float samplerate)
{
for(int i = 0; i < 32; i++)
{
osc[i].Init(samplerate);
osc[i].SetAmp(.7);
}
}
void FreqOsc()
{
for(int i = 0; i < 32; i++)
{
//NO FUNCIONAN!! srand (time(NULL)); srand (getpid());
freq[i] = 100.0 + rand() % 5000;
osc[i].SetFreq(freq[i]);
}
}
int main
{
hardware.Configure();
hardware.Init();
float samplerate = hardware.AudioSampleRate();
AdcChannelConfig adcConfig[2];
adcConfig[0].InitSingle(hardware.GetPin(21));
adcConfig[1].InitSingle(hardware.GetPin(22));
hardware.adc.Init(adcConfig, 2);
hardware.adc.Start();
SetupOsc(samplerate);
FreqOsc();
int val = hardware.adc.GetFloat(0);
for(int i = 0; i < 32; i++)
{
int temp = val >> i;
bin[i] = temp& 0x00000001; /
}
if(bin[0] == 1)
{
hardware.StartAudio(Audio0Callback);
}
if(bin[1] == 1)
{
hardware.StartAudio(Audio1Callback);
}
if(bin[2] == 1)
{
hardware.StartAudio(Audio2Callback);
}
for(;;) {}
}
I know that I could put the oscillators in the same AudioCallback but the idea is to be able to activate and deactivate their output based on a series of bits that I saved in an array. In the end I would like to create 32 AudioCallback. One for each cell in the array.
Thanks.
Your idea is wrong. There’s just 1 audio callback that you must set during patch initialization. You can do whatever mixing you want inside it.
In that case, how could I call different oscillators over time? When I call osc [i] .Process (); I can’t find a way to make it stop
For example:
void AudioCallback(float **in, float **out, size_t size)
{
float out_osc0, out_osc1, out_osc2;
for(size_t i = 0; i < size; i++)
{
if(bin[0] == 1)
{
osc_out0 = osc[0].Process();
}
if(bin[1] == 1)
{
osc_out1 = osc[1].Process();
}
if(bin[2] == 1)
{
osc_out2 = osc[2].Process();
}
out[0][i] = osc_out0 + osc_out1 + osc_out2;
out[1][i] = osc_out0 + osc_out1 + osc_out2;
}
}
This is not working for me.
I think your code should look something like this if you want to run 32 osc’s at the same time:
void AudioCallback(float *in, float *out, size_t size)
{
float sig;
for(size_t i = 0; i < size; i += 2)
{
sig = 0;
for (int j = 0; j < 32; j++)
{
sig += osc[j].Process() / 32;
}
out[i] = sig;
out[i + 1] = sig;
}
}
You control the volume from each osc using for example an ADSR or a multiplication factor in the audio callback (instead of dividing by 32, you could multiply with 1/32 or 0 if you want that osc to be silent).
You can look at my code here (OscPocketD - Portable music tool (sequencing drums and synths) - #10 by StaffanMelin) to see how I mix different oscillators in the audio callback.
If this is not what you want, please elaborate on what your goal is.
Staffan
1 Like
This method generates a single sample, you don’t need to stop anything.
Thank you very much @StaffanMelin and @antisvin.
The example you give me works for me.
Based on what you have told me, I will try to explain what I am trying to do. I am passing the value of the variable hardware.adc.GetFloat(0) to binary and storing the bits in a bin[32] vector that should be updated if the value of hardware.adc.GetFloat (0) changes. Afterwards, what I try is that the values stored in bin[], turn each oscillator on or off according to the equality bin [i] == 1. This I am applying on the amplitude of each oscillator in void AmpOsc () but it does not work for me.
The result should be that each oscillator independently sounds or not if I change the value of hardware.adc.GetFloat (0).
I hope you can understand me. My English and my programming experience are not good.
int bin[32];
void AudioCallback(float *in, float *out, size_t size)
{
float sig;
for(size_t i = 0; i < size; i += 2)
{
sig = 0;
for (int j = 0; j < 32; j++)
{
sig += osc[j].Process() / 32);
}
out[i] = sig;
out[i + 1] = sig;
}
}
void SetupOsc(float samplerate)
{
//float sig[32];
for(int i = 0; i < 32; i++)
{
osc[i].Init(samplerate);
}
}
void AmpOsc(int bin[])
{
for(int i = 0; i < 32; i++)
{
if (bin[i] == 1)
{
osc[i].SetAmp(.7);
}
else
{
osc[i].SetAmp(0.0);
}
}
}
void FreqOsc()
{
for(int i = 0; i < mod; i++)
{
freq[i] = 100.0 + rand() % 2000;
osc[i].SetFreq(freq[i]);
}
}
int main(void)
{
hardware.Configure();
hardware.Init();
float samplerate = hardware.AudioSampleRate();
AdcChannelConfig adcConfig[2];
adcConfig[0].InitSingle(hardware.GetPin(21));
adcConfig[1].InitSingle(hardware.GetPin(22));
hardware.adc.Init(adcConfig, 2);
hardware.adc.Start();
SetupOsc(samplerate);
FreqOsc();
//Decimal to binario
//--------------
int val = hardware.adc.GetFloat(0);
for(int i = 0; i < mod; i++)
{
int temp = val >> i;
bin[i] = temp& 0x00000001;
}
AmpOsc(bin);
hardware.StartAudio(AudioCallback);
for(;;) {}
}
Your english is not bad at all!
Your code should be structured more like this:
#define OSC_COUNT 32
int bin[OSC_COUNT];
void AudioCallback(float *in, float *out, size_t size)
{
float sig;
float factor;
int val = hardware.adc.GetFloat(0);
for(int i = 0; i < OSC_COUNT; i++)
{
int temp = val >> i;
bin[i] = temp& 0x00000001;
}
for(size_t i = 0; i < size; i += 2)
{
sig = 0;
for (int j = 0; j < OSC_COUNT; j++)
{
if (bin[j] == 1)
{
factor = 1 / 32.0f;
} else {
factor = 0;
}
sig += osc[j].Process() * factor;
}
out[i] = sig;
out[i + 1] = sig;
}
}
void SetupOsc(float samplerate)
{
for (int i = 0; i < 32; i++)
{
osc[i].Init(samplerate);
freq[i] = 100.0 + rand() % 2000;
osc[i].SetFreq(freq[i]);
osc[i].SetAmp(0.7);
}
}
int main(void)
{
hardware.Configure();
hardware.Init();
float samplerate = hardware.AudioSampleRate();
AdcChannelConfig adcConfig[2];
adcConfig[0].InitSingle(hardware.GetPin(21));
adcConfig[1].InitSingle(hardware.GetPin(22));
hardware.adc.Init(adcConfig, 2);
hardware.adc.Start();
SetupOsc(samplerate);
hardware.StartAudio(AudioCallback);
for(;;) {}
}
I’m not really sure how you are translating the pot values into 0:s or 1:s, but that is your problem!
Remember that what happens in main() is only run once (except the for-loop at the end). The audio callback is run repeatedly. (It is a bit like setup() and loop() in Arduino.)
Good luck and please don’t hesitate to ask for more help!
Staffan
SWEDEN
1 Like