New Top

All Products By Category

Soundboxen #4: Fluxamasynth Radio Station in a Box

Soundboxen are songs wrapped up in objects, originally inspired by Stockhausen’s Zodiac music boxes. Some are simple music boxes; #1 was an implementation of Riley’s In C (w/tempo knob). Others are instruments constrained to a certain song. #3 is a jukebox of bytebeat; #4 is an algorithmic radio station in a box. This is a great example of what you can do with a Fluxamasynth music generator; read below the fold for the code.



#include 
#include     // Uses the Adafruit FM radio transceiver 

#define RESETPIN 12
     
#define FMSTATION 10250     // 10230 == 102.30 MHz

Adafruit_Si4713 radio = Adafruit_Si4713(RESETPIN); 

#include 
#include 

Fluxamasynth synth = Fluxamasynth();

#define numInstruments 4


byte parts[4];
int measures[16];
int notes[16];
int rhythm[16];
int percussion[16];
char partName[4] = {'a','b','c','d'};
int noteName[16];
int binaryChoice[16];
int noteOn[4] = {0, 0, 0, 0};
int rhythmOn[4] = {0, 0, 0, 0};
int tempo=30;

// Limit instrument choice
int instrument[numInstruments] = {13, 13, 13, 13};

void setup() {
  randomSeed(millis()+analogRead(0));
  Serial.begin(9600);
  chooseParts();
  synth.setMasterVolume(127);
  for (int i=0; i50) {
        binaryChoice[i] = 1;
      } else {
        binaryChoice[i] = 0;
      }
    }
    tempo = tempo-random(tempo/160);

    //TODO: Add four time channels: triplet, quad, quintuplet, septuplet

    while(random(100)<10) {
      for (int i=0; i<8; i++) {
      Serial.println();
      for (int part =0; part<4; part++) {
        if ((parts[part]>>i) & 0x01) {
          Serial.print(partName[part]);
          for (int beat =0; beat<8; beat++) {
            delay(tempo);
            //Serial.print("|");
            for (int voice=0; voice<4; voice++) {
              if (((measures[part+voice]>>beat) & 0x01)==binaryChoice[part+voice]) {
                if (noteOn[voice]!=noteName[part+voice]) {
                  if (noteOn[voice]==0) {
                    Serial.print(voice);
                    synth.noteOn(voice, noteName[part+voice], 127);
                    noteOn[voice] = noteName[part+voice];
                  } else {
                    synth.noteOff(voice, noteOn[voice]);
                    synth.noteOn(voice, noteName[part+voice], 127);
                    //Serial.print("PrevOff");
                    //Serial.print("On");
                    noteOn[voice] = noteName[part+voice];
                  }
                } else {
                    //Serial.print("Hold");
                }
               // Serial.print(voice);
                //Serial.print(": ");
                //Serial.print(noteName[part+voice]);
                //Serial.print(" ");
              } else {
                if (noteOn[voice]) {
                  synth.noteOff(voice, noteOn[voice]);
                  noteOn[voice]=0;
                  //Serial.print(voice);
                  // Serial.print(": off");
                }
              }
              if (((rhythm[part+voice]>>beat) & 0x01)==binaryChoice[part+voice]) {
                if (!rhythmOn[voice]) {
                  rhythmOn[voice]=1;
                  synth.noteOn(9, percussion[voice], 100) ;
                  synth.noteOff(9, percussion[voice]) ;
                } 
              } else {
                rhythmOn[voice]=0;
              }
            }
          }
        }
      }
     }
   }
  }
  delay(2000);

}

void pan(int channel, int value) {
  // TODO: Add this to library
  byte command[3] = {
    (0xb0 | (channel & 0x0f)), 0x0A, (value)   };
  synth.fluxWrite(command, 3);
}