Hi there,
Iv'e build a microtonal synthesisers that uses the Scala files for alternatives tuning systems using MaxMSP programme
I would like to build a synthesizer using the scala files but to be all hardware without using the computer.
I understand that for audio stuff it will be better using Teensy over Arduino? this for its better memory size(?)
Is someone build a synth that can play microtonal scales? Any links or idea where should I start?
I guess I will need to build a polyphonic sound engine to play the scales and I will need to store those scales (it is rather a cents values or ratios values) on an external sd card ?
Note: Some of the example 'cent' values are showing 9 significant digits. On most basic Arduinos the 'double' and 'float' types are the same and can only hold about 6.8 significant digits (the 7th significant digit is correct only 80% of the time). You might need a processor with a true 'double' type.
Spurious precision due to being printed out that way, nothing to worry about.
Using double precision for a frequency might be appropriate for an atomic frequency standard or a pulsar, but not for a musical scale - rounding to the nearest cent is perfectly fine.
const char scale1 [] = " ! DORIAN_PENT.scl
!
Schlesinger's Dorian Harmonia in the pentachromatic genus
7
!
55/53
11/10
11/8
11/7
55/34
22/13
2/1
"
how can I extract the name of the scale(first line) into one variable, the description of the scale (third line) into another variable, the number of notes (fourth line) into another variable and the ratios (sixth line until the end) into another variable array that will be already in hertz after multiplying by an fundamental frequency of 261.6 hertz (middle C (midi 60)).
edit: so if to make the task simple: I would like to separate the long string into 4 strings:
the name of the scale (first line in scale1 string)
the description of the scale (third line)
number of notes in scale (fourth line)
ratios in scale (sixth line until end of string)
each of those I then would like to store to a variable and make use of it later on.
You would read each line and decide what to do with each. The first non-comment line is the name. The second non-comment line is the number of notes. All further non-comment lines are notes.
Is there better ways to make the reading from the multiplex?
Perhaps I should transfer it into a function to be more readable as my project increase over time?
edit: I did transfer it into a function:
void MUX_check()
{
for (int i = 0; i < 3; i++)
{
digitalWrite(s0, HIGH && (i & B00000001));
digitalWrite(s1, HIGH && (i & B00000010));
digitalWrite(s2, HIGH && (i & B00000100));
MUX_channel[i] = analogRead(MUX_In);
Serial.print("pot ");
Serial.print(i+1);
Serial.print(": ");
Serial.println(MUX_channel[i]);
delay(1000);
}
}
void loop() {
MUX_check();
}
also , this part of code
digitalWrite(s0, HIGH && (i & B00000001));
digitalWrite(s1, HIGH && (i & B00000010));
digitalWrite(s2, HIGH && (i & B00000100));
Is still encrypted for me. is there different way to achieve the same? can someone explain those lines?
edit2:
Why the values I'm reading are only between 0 and 255? isn't it should be 0 to 1023?
I found my mistake: I declare uint8_t which can represent only numbers between 0 to 255 instead of using uint16_t.
I try to print to the serial only when a value is changed with no success:
uint16_t MUX_channel_old[numOfPots] = {0}; // new array to store old values
void MUX_check()
{
for (int i = 0; i < numOfPots; i++)
{
digitalWrite(s0, HIGH && (i & B00000001));
digitalWrite(s1, HIGH && (i & B00000010));
digitalWrite(s2, HIGH && (i & B00000100));
MUX_channel[i] = analogRead(MUX_In);
if(MUX_channel_old[i] != MUX_channel[i])
{
Serial.print("pot ");
Serial.print(i+1);
Serial.print(": ");
Serial.println(MUX_channel[i]);
delay(150);
}
MUX_channel_old[i] = MUX_channel[i];
}
}
edit: my code is working, is just that the value is indeed constantly changing. a small jitter of around 1-3 values. Is it happening due to noise In the rail? because I'm using breadboard?
how can I smooth that?
& is the bitwise-and operator in C. B00000010 is the same as 0b00000010, a binary constant (from C++ version 14 the 0b syntax became part of the language).
So
0b00111100 &
0b01110110 =
0b00110100
Those digitalWrite lines extract the bottom 3 bits from the number in order to feed them to the address pins of the analog switch.