Fluxamasynth software serial

Requests for new features and products, news about what we are working on.
Post Reply
stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Fluxamasynth software serial

Post by stevecooley » Thu May 05, 2011 7:44 pm

Hi there. I waited a while and tried taking a crack at converting the fluxamasynth.cpp file from hardware serial over to software serial. I get no compiler errors, but... no sound. So my theory was wrong about using softwareSerial.print(whatever,BIN) instead of Serial.write(whatever) ... any ideas what I can do from here? I'd pretty much *always* use software serial to talk to the shield if it meant I can send note data from my computer in real time... no need to make the hardware serial a selectable mode for me.

Code: Select all


/* 
 Fluxamasynth.cpp
 A library to facilitate playing music on the Modern Device Fluxamasynth board.
 More info at www.moderndevice.com
 This software is in the public domain.
 */

/*
2011-05-05 steve cooley (the impatient)
 mutilation of perfectly functional code, just to get the software serial working on pin 4. Does. It. Work??
 Not yet.
 
 */

#include "WProgram.h"
#include "Fluxamasynth.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial =  SoftwareSerial(5, 4);

Fluxamasynth::Fluxamasynth() {

  mySerial.begin(31250);

}

void Fluxamasynth::noteOn(byte channel, byte pitch, byte velocity) {
  // byte command[3] = { 0x90 | (channel & 0x0f), pitch, velocity };
  mySerial.print(0x90 | (channel & 0x0f), BIN);
  mySerial.print(pitch, BIN);
  mySerial.print(velocity, BIN);  
}

void Fluxamasynth::noteOff(byte channel, byte pitch) {
  //	byte command[3] = { 0x80 | (channel & 0x0f), pitch, byte(0x00) };
  //	mySerial.write(command, 3);
  mySerial.print(0x80 | (channel & 0x0f), BIN);
  mySerial.print(pitch, BIN);
  mySerial.print(0x00, BIN);  

}

void Fluxamasynth::programChange(byte bank, byte channel, byte v) {
  // bank is either 0 or 127

  // byte command[3] = { 0xB0 | (channel & 0x0f), byte(0x00), bank };
  // mySerial.write(command, 3);
  // mySerial.write(0xc0 | (channel & 0x0f));
  // mySerial.write(v);

  mySerial.print(0xB0 | (channel & 0x0f), BIN);
  mySerial.print(byte(0x00), BIN);
  mySerial.print(bank, BIN);
  mySerial.print(0xc0 | (channel & 0x0f), BIN);
  mySerial.print(v, BIN);


}

void Fluxamasynth::pitchBend(byte channel, int v) {
  // v is a value from 0 to 1023
  // it is mapped to the full range 0 to 0x3fff

  v = map(v, 0, 1023, 0, 0x3fff);

  // byte command[3] = { 0xe0 | (channel & 0x0f), byte(v & 0x00ef), byte(v >> 7) };
  // mySerial.write(command, 3);

  mySerial.print(0xe0 | (channel & 0x0f), BIN);
  mySerial.print(byte(v & 0x00ef), BIN);
  mySerial.print(byte(v >> 7) , BIN);    

}

void Fluxamasynth::pitchBendRange(byte channel, byte v) {
  // Also called pitch bend sensitivity
  //BnH 65H 00H 64H 00H 06H vv
  // 	byte command[7] = {0xb0 | (channel & 0x0f), 0x65, 0x00, 0x64, 0x00, 0x06, (v & 0x7f)};
  //	mySerial.write(command, 7);
  mySerial.print(0xb0 | (channel & 0x0f), BIN);
  mySerial.print(0x65, BIN);
  mySerial.print(0x00, BIN);
  mySerial.print(0x64, BIN);
  mySerial.print(0x00, BIN);
  mySerial.print(0x06, BIN);
  mySerial.print((v & 0x7f), BIN);

}

void Fluxamasynth::midiReset() {
  //    mySerial.write(0xff);
  mySerial.print(0xff, BIN);
}

void Fluxamasynth::setChannelVolume(byte channel, byte level) {
  //	byte command[3] = { (0xb0 | (channel & 0x0f)), 0x07, level };
  //	mySerial.write(command, 3);
  mySerial.print((0xb0 | (channel & 0x0f)), BIN);
  mySerial.print(0x07, BIN);
  mySerial.print(level, BIN);

}

void Fluxamasynth::allNotesOff(byte channel) {
  // BnH 7BH 00H
  //	byte command[3] = { (0xb0 | (channel & 0x0f)), 0x7b, 0x00 };
  //	mySerial.write(command, 3);
  mySerial.print((0xb0 | (channel & 0x0f)), BIN);
  mySerial.print(0x7b, BIN);
  mySerial.print(0x00, BIN);

}

void Fluxamasynth::setMasterVolume(byte level) {
  //F0H 7FH 7FH 04H 01H 00H ll F7H
  //    byte command[8] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01, 0x00, (level & 0x7f), 0xf7 };
  //    mySerial.write(command, 8);
  mySerial.print(0xf0, BIN);
  mySerial.print(0x7f, BIN);
  mySerial.print(0x7f, BIN);
  mySerial.print(0x04, BIN);
  mySerial.print(0x01, BIN);
  mySerial.print(0x00, BIN);
  mySerial.print((level & 0x7f), BIN);
  mySerial.print(0xf7, BIN);

}

void Fluxamasynth::setReverb(byte channel, byte program, byte level, byte delayFeedback) {
  // Program 
  // 0: Room1   1: Room2    2: Room3 
  // 3: Hall1   4: Hall2    5: Plate
  // 6: Delay   7: Pan delay
  //  mySerial.write(0xb0 | (channel & 0x0f));
  //  mySerial.write(0x50);
  //  mySerial.write(program & 0x07);

  // Set send level
  //  mySerial.write(0xb0 | (channel & 0x0f));
  //  mySerial.write(0x5b);
  //  mySerial.write(level & 0x7f);

  mySerial.print(0xb0 | (channel & 0x0f), BIN);
  mySerial.print(0x50, BIN);
  mySerial.print(program & 0x07, BIN);

  // Set send level
  mySerial.print(0xb0 | (channel & 0x0f), BIN);
  mySerial.print(0x5b, BIN);
  mySerial.print(level & 0x7f, BIN);  

  if (delayFeedback > 0) {
    //F0H 41H 00H 42H 12H 40H 01H 35H vv xx F7H
    //byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x35, (delayFeedback & 0x7f), 0xf7 };
    //mySerial.write(command, 11);

    mySerial.print(0xf0, BIN);
    mySerial.print(0x41, BIN);
    mySerial.print(byte(0x00), BIN);
    mySerial.print(0x42, BIN);
    mySerial.print(0x12, BIN);
    mySerial.print(0x40, BIN);
    mySerial.print(0x01, BIN);
    mySerial.print(0x35, BIN);
    mySerial.print(0x01, BIN);
    mySerial.print((delayFeedback & 0x7f), BIN);
    mySerial.print(0xf7, BIN);


  }
}

void Fluxamasynth::setChorus(byte channel, byte program, byte level, byte feedback, byte chorusDelay) {
  // Program 
  // 0: Chorus1   1: Chorus2    2: Chorus3 
  // 3: Chorus4   4: Feedback   5: Flanger
  // 6: Short delay   7: FB delay
  //  mySerial.write(0xb0 | (channel & 0x0f));
  //  mySerial.write(0x51);
  //  mySerial.write(program & 0x07);

  mySerial.print(0xb0 | (channel & 0x0f), BIN);
  mySerial.print(0x51, BIN);
  mySerial.print(program & 0x07, BIN);


  // Set send level
  //  mySerial.write(0xb0 | (channel & 0x0f));
  //  mySerial.write(0x5d);
  //  mySerial.write(level & 0x7f);

  mySerial.print(0xb0 | (channel & 0x0f), BIN);
  mySerial.print(0x5d, BIN);
  mySerial.print(level & 0x7f, BIN); 

  if (feedback > 0) {
    //F0H 41H 00H 42H 12H 40H 01H 3BH vv xx F7H
    //	byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x3B, (feedback & 0x7f), 0xf7 };
    //	mySerial.write(command, 11);

    mySerial.print(0xf0, BIN);
    mySerial.print(0x41, BIN);
    mySerial.print(byte(0x00), BIN);
    mySerial.print(0x42, BIN);
    mySerial.print(0x12, BIN);
    mySerial.print(0x40, BIN);
    mySerial.print(0x01, BIN);
    mySerial.print(0x3B, BIN);
    mySerial.print((feedback & 0x7f), BIN);
    mySerial.print(0xf7, BIN);
  }

  if (chorusDelay > 0) {
    // F0H 41H 00H 42H 12H 40H 01H 3CH vv xx F7H
    //	byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x3C, (chorusDelay & 0x7f), 0xf7 };
    //	mySerial.write(command, 11);

    mySerial.print(0xf0, BIN);
    mySerial.print(0x41, BIN);
    mySerial.print(byte(0x00), BIN);
    mySerial.print(0x42, BIN);
    mySerial.print(0x12, BIN);
    mySerial.print(0x40, BIN);
    mySerial.print(0x01, BIN);
    mySerial.print(0x3C, BIN);
    mySerial.print((chorusDelay & 0x7f), BIN);
    mySerial.print(0xf7, BIN);
  }
}


Then, here's a slightly updated note randomizer sketch that uses the hardware serial to debug what's going on in the firmware.

Code: Select all

#include <SoftwareSerial.h>

#include <Fluxamasynth.h>



Fluxamasynth synth;

int counter = 0;
int channel = 0;
int voice = 0;
int j = 0;

void setup() {
  Serial.begin(57600);
  Serial.println("hello world");
  synth.programChange(0, 9, 40);
  synth.programChange(0, 1, 0);
}

void loop()
{


  while(counter < 128)
  {
    if(voice >128)
    {
      voice = 0;
    }

    synth.programChange(channel, 0, voice);
    Serial.print("program changed - voice : ");
    Serial.println(voice);


    for(int i=0; i<10; i++)
    {

      int note = int(random(36,100));

      synth.noteOn(channel, note, 127);  // play 1 note (C4) on channel 0
      Serial.print("played note ");
      Serial.print(note);
      Serial.print(" on channel ");
      Serial.println(channel);
      int coinflip = int(random(0,20));

      if(coinflip == 5)
      {
        while(j < 200)
        {
          synth.pitchBend(channel, j);
          j+= 16;
          delay(10);
        }
        j = 0; 
      }

      delay(100);
      synth.noteOff(channel, note);

    }

    voice++;

    /*
 synth.noteOn(1, c3, 127);
     synth.noteOn(1, e3, 127);  // play 3 notes (C3, E3, G3) on channel 1
     synth.noteOn(1, g3, 127);
     
     //delay(1000);
     synth.noteOff(1, c3);
     synth.noteOff(1, e3);
     synth.noteOff(1, g3);
     */
  }
  Serial.println("counter = "+counter);
  channel++;
  counter++;


  Serial.println("looping...");
}


again, no compiler errors, it seems to run just fine, except for the fact that there's no sound. :) This sketch at least let me see in the serial monitor what was going on... or supposed to be going on. I'd love some help getting this to work. In order for this to be something I'd actually use for performances, I need to be able to send it midi data. I can ship data into the arduino over the serial line from a processing sketch... but the hardware serial line has to be freed up. do I need to hook up a second arduino to one of the free pins on the flux shield ? I could do that.. no lack of arduinos in my garage.

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Thu May 05, 2011 7:52 pm

Arrrrgh.
http://www.arduino.cc/en/Reference/SoftwareSerial
Only speeds up to 9600 baud work

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Fri May 06, 2011 3:45 pm

just tried replacing standard software serial with http://arduiniana.org/libraries/NewSoftSerial/ ... no luck.

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Fri May 06, 2011 3:45 pm

although, my guess is that luck really has nothing to do with it.

paul
Site Admin
Posts: 734
Joined: Mon May 12, 2008 4:19 pm

Re: Fluxamasynth software serial

Post by paul » Sat May 07, 2011 1:57 pm

Have a look through the software serial code. If there is a "digitalWrite" in sight, there's a lot of speed gain to be had by getting rid of that for some direct port manipulation.

Paul

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Thu May 19, 2011 6:21 pm

I can't even get it to work with a software serial library... at all. So, my speed is 0 baud. 0 BPM, 0 mph. I'm still hoping to see some code you had mentioned a solution for this.

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Thu Jun 02, 2011 12:02 am

Heya, Paul. It was great meeting you at Maker Faire!! This is me bugging you, at your advisement, about the software serial code for the fluxamasynth shield. :)

paul
Site Admin
Posts: 734
Joined: Mon May 12, 2008 4:19 pm

Re: Fluxamasynth software serial

Post by paul » Thu Jun 02, 2011 11:35 am

OK I'll see what's going on with the programmer I gave this task to.

Paul

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Wed Jun 08, 2011 7:52 pm

It's just that I want to use this shield in my live act... so I'm still hopeful. :)

stevecooley
Posts: 24
Joined: Mon Aug 24, 2009 12:20 pm

Re: Fluxamasynth software serial

Post by stevecooley » Tue Aug 02, 2011 2:13 pm

Oh well.

Post Reply