Freitag, 18. Juli 2014

Raspi as a synth?

There are several nice "programming languages" for create digital sound with Linux. The next project might be a test, "how much sound" a Raspi can make.

The experiment should not use a common USB-MIDI-Interface. I will try to build my own using the serial GPIO pins. The following software should be tested:
  • jack
  • fluidsynth
  • csound
  • super-collider
Theres much to do until the test can start. Currently I found a bundle of web-pages to avoid  trouble:
More on this page when I find time to start the work...

Donnerstag, 10. April 2014

Arduino Uno as an Extron Video-Switch-Controller

This is a project for my employer I just finished.

The problem was:
We have a conference room. There are two media sources: A notebook in a control room and a VGA cable for the lecturer in the room itself. We also have a video conference station and a beamer. For some sessions we need to route one of the sources through the video conference station, so that the external participants can see the slides. But sometimes we only need to connect the sources from local to the beamer. All cables are getting together on a patch panel in the control room.

Patching is not very user friendly - especially when the sessions need different setups for every lecturer. So we installed a video-cross-connect (4 Ins, 4 Outs) from Extron. Our video-specialists configured four setups which can be used directly on the video-cross-connect by voodoo-pressing-buttons-in-the-right-order. The result was that inside an important session the configuration of the video-cross-connect was broken by user.

Now(!) the Arduino has his appearance! The Extron video-cross-connect has a RS232 interface where you can setup bondings between Ins and Outs by "magic" codes (for the exact commands: look at your documentation - I don't know if the codes are under license by Extron). So the Arduino has only to convert 0V/+5V to -12V/+12V. I also used a software serial to let the onboard hardware serial free for programming.

The user interface should be as easy as possible: An encoder (with push button) and four LEDs - thats all. Of course you can make betterand bigger interfaces (7-segment-digits, Displays, ...). Every external hardware was build on a stripe circuit board and placed inside a box. The user interface was simply build from a wooden pannel with some cables from the LEDs and encoder towards the Arduino box. Everything was mounted on the wall - the cables were placed inside the wall towards the Arduino box on the other side. The front panel is currently build as aluminium panel by a special company so the wooden one can be replaced very soon.

Here are some pictures:

 The prototype



 Selfmade shield


 The layout plan for the stripe board


 Inside the box without panel



Boxed with pre-panel

Box on wall (backside of the frontpanel)

Frontpanel (made with "Frontplatten-Designer" by  http://www.schaeffer-ag.de)

 Frontpanel on the wall

Perhaps you want to changes the LED resistors. The LEDs are currently a little bit too dark. The code makes some neat things with the LEDs so that the user can easy recognize program changes. Also it recognizes if someone directly chosed a setup on the video-crossbar itself - in this case all LEDs are dark until you choose a configuration by the encoder.

The code is GPLv3 - use at your own risk! Perhaps it can be adapted for other video-cross-connects. The code will is released on SourceForge, see https://sourceforge.net/projects/mediensteuerung/

Montag, 28. Oktober 2013

This time no Arduino - but Raspi scares kids on Halloween :-)

This video shows what I have done for Halloween with a Rasperry Pi (I know that it is dark... this is only an example for the show we made yesterday):






I used the following hardware:

  • Raspberry Pi
  • WLAN USB stick
  • FTDI-RS485 USB adapter for connecting to DMX light hardware
  • Speakers
  • Cables like Power, DMX, ...

... and the following software:

  • SD Card with Raspian
  • OLA daemon see http://www.opendmx.net/index.php/Open...
  • self written C++-daemon for sending DMX data to OLA as middleware (the daemon accepts simple commands for setting modes and values for each DMX channel and can play fades as a background thread - totaly detached from the controlling software; the interface is a simple UDP network connection).
  • self written Perl-script for firing up sounds and light commands to my daemon
The Raspi is configured as a WLAN hotspot, so I can log in from the kitchen without having cables through windows or doors. The audio files and programs are installed on the Raspi.

The program plays a storm sound in the background and makes color changes on the spot and LED-Bar - you can put much more lightning or DMX addressable equipment to the show if you have... . With shortcuts on the keyboard I can play some more scary sounds.

The special fun is the key "G". When pressed the spots are fading to dark and radomly they are flashing white. After that a thunderstorm sound is played.

If you have any questions about this project, feel free to caontact me!

Happy Halloween :-]

Mittwoch, 16. Januar 2013

Arduino drives digital locomotives (Maerklin Motorola II)

After trying to write my own interrupt timer service sketch for generating Maerklin Motorola (II) protocol for my model railroad I found a message from a guy who had done this already: http://forum.rocrail.net/viewtopic.php?t=4583 (sorry, german only). We changed some email an I tried to get his sketch running. After some (self made) trouble it works fine for me. The code was working but it was not very good organized. So I asked him to make a Sourceforge project of Maerklino (now it is called Ardurail to avoid traddemark problems) and began to rewrite.

And here it is: https://sourceforge.net/projects/ardurail/

Until now we haven't released any files but you can check out the (hopefully) working development version from SVN. The last changes I made were to put the whole code into a class so that it later can be distributed as a simple library. Also I added some functions for better control of the devices.

The next step will be (after testing the actual code): Writing a derived class which implements the P50 protocol (currently it is a method inside the class) and than a derived class for SRCP (see http://srcpd.sourceforge.net/srcp/).

Mittwoch, 11. Januar 2012

Play MIDI files on an Arduino with a Fluxamasynth shield / MIDI to Fluxmasynth converter Version 1.0 is ready for download!

After getting some new ideas how to convert MIDI files for the Arduino/Fluxamashield I am very proud to present version 1.0 of a Perl converter. This one can read MIDI files in format 0 or 1 (it implicitly converts 1 to 0 before converting to Arduino C++ code).

Version 1.0 doesn't need midicsv-tools anymore. It uses the (very nice!) MIDI library of Perl. You can get it from CPAN or try to look for a package at your Linux distribution (e.g. "libmidi-perl" maybe the right search pattern). Also included is the Arduino sketch for playing the converted data.

You can download midi2fluxama-1.0 from Sourceforge.

If you have some right-free and/or "free" licensed MIDI files (or converted files) which sound amazing on the Fluxamaynth it would be nice if you will add them as examples for the converter.

The next steps will be the support of reading the Arduino-Byte-Data from a file on SD for supporting longer and more than one songs.

Dienstag, 13. Dezember 2011

Another funny thing for the Fluxamasynth shield

Here is another simple program which plays GM-Files (GM: General MIDI) with a Fluxamasynth. You cannot use the original MIDI file because the Arduino has not so much memory for bigger files and it is quit easier for the playing code if the data is minimized for only neccesary events.

So I decided to decode the MIDI file with some perl utils (http://www.fourmilab.ch/webtools/midicsv/) to a CSV file. Than the CSV-MIDI-file is parsed by my own Perl program which drops lines which the Fluxamasynth can't handle or should not use. It also stops converting after 22487 bytes of data. This seems to be a size which Arduino can handle without any errors.
  • Notice that this converter only works with midi files format 0 (convert format 1 first)!
  • Notice also that you have to replace every double quote with a single quote before converting CVS to Arduino-Header format!
Take a look at the csv2fluxama-c.pl converter:
#!/usr/bin/perl

use Text::CSV;
use Data::Dumper;

my @data;
my $csv = Text::CSV->new({binary => 1, auto_diag => 1})
          || die "Cannot use CSV: ".Text::CSV->error_diag ();

open(SMF,"<$ARGV[0]") || die("Cannot open $ARGV[0]\n");
while(my $d=$csv->getline(SMF))
{
        push @data,$d;
}
$csv->eof || $csv->error_diag();
close(SMF);

print "FLASH_ARRAY(byte, midi_data,\n";

my $old_time=0;
my $out="";
my $max=22487;

while($d=shift(@data))
{
        if($max<5)
        {
                last;
        }

        if($$d[2] eq " Tempo")
        {
                $tempo=int($$d[3]);
                next;
        }
        elsif($$d[2] eq " System_exclusive")
        {
                next;
        }
        elsif($$d[2] eq " Pitch_bend_c")
        {
                $out=" 3,".$$d[3].",".(($$d[4]&65280)>>8).",".($$d[4]&255);
                $max-=5;
        }
        elsif($$d[2] eq " Control_c" && $$d[4] == 7)
        {
                $out=" 2,".$$d[3].",".$$d[5];
                $max-=4;
        }
        elsif($$d[2] eq " Control_c" && $$d[4] == 10) # Pan
        {
                $out=" 5,".$$d[3].",".$$d[5];
                $max-=4;
        }
        elsif($$d[2] eq " Control_c" && $$d[4] == 64) # Sustain
        {
                $out=" 6,".$$d[3].",".$$d[5];
                $max-=4;
        }
        elsif($$d[2] eq " Program_c")
        {
                $out=" 4,".$$d[3].",".$$d[4];
                $max-=4;
        }
        elsif($$d[2] eq " Time_signature")
        {
                $ticks_per_beat=$$d[5];
                next;
        }
        elsif($$d[2] eq " Note_on_c")
        {
                $out=" 0,".$$d[3].",".$$d[4].",".$$d[5];
                $max-=5;
        }
        elsif($$d[2] eq " Note_off_c")
        {
                $out=" 1,".$$d[3].",".$$d[4];
                $max-=4;
        }
        else
        {
                next;
        }

        # delay value
        print "   ".($$d[1]-$old_time).",".$out;
        $old_time=$$d[1];

        print ", // ".$$d[0].",".$$d[1].",".$$d[2].",".$$d[3].",".$$d[4].",".$$d[5],"\n";
}

print ");\n";
print "const unsigned long tempo=".$tempo.";\n";
print "const unsigned int ticks_per_beat=".$ticks_per_beat.";\n";
 
The output is written to stdout in Flash library format. This file should be included into the following sketch:

#include <Fluxamasynth_NSS.h>
#include <NewSoftSerial.h>
#include <Flash.h>        // needed for storing the song data in PROG_MEM
#include <FlexiTimer2.h>  // for correct, interrupt based timing
#include "converted-midi-file.h"

#define MASTER_VOL_MAX 75    // the maximum volume
#define TEMPO 5

Fluxamasynth synth;
int sp=0;  // the song pointer
const int events=midi_data.count();

void event()
{
  if(sp<events)
  {
    // check the type of event
    switch(midi_data[sp+1])
    {
    case 0:  // NoteOn
      synth.noteOn(midi_data[sp+2],midi_data[sp+3],midi_data[sp+4]);
      sp+=5;
      break;
    case 1:  // NoteOff
      synth.noteOff(midi_data[sp+2],midi_data[sp+3]);
      sp+=4;
      break;
    case 2:  // ChannelVolume
      synth.setChannelVolume(midi_data[sp+2], midi_data[sp+3]);
      sp+=4;
      break;
    case 3:  // PitchBend
      synth.pitchBend(midi_data[sp+2], (midi_data[sp+3]<<8)+midi_data[sp+4]);
      sp+=5;
      break;
    case 4:  // ProgramChange
      synth.programChange(0,midi_data[sp+2], midi_data[sp+3]);
      sp+=4;
      break;
    /* case 5:  // Pan
      synth.Panorama(0,midi_data[sp+2], midi_data[sp+3]);
      sp+=4;
      break;
    case 6:  // Sustain
      synth.Sustain(0,midi_data[sp+2], midi_data[sp+3]);
      sp+=4;
      break; */
    }

    // timer for the next event
    FlexiTimer2::set(midi_data[sp]*ticks_per_beat/TEMPO,1000.0/tempo,event);
    FlexiTimer2::start();
  }
  else
  {
    // after the end of the song reset the Fluxamasynth
    synth.midiReset();
    synth.setMasterVolume(MASTER_VOL_MAX);
    FlexiTimer2::stop();
    sp=0;
    FlexiTimer2::set(5000*ticks_per_beat/TEMPO,1000.0/tempo,event);
    FlexiTimer2::start();
  }
}

void setup()
{
  synth.midiReset();
  synth.setMasterVolume(MASTER_VOL_MAX);
  FlexiTimer2::set(midi_data[sp]*ticks_per_beat/TEMPO,1000.0/tempo,event);
  FlexiTimer2::start();
}

void loop()
{
  ; // Windows like... ;-)
}
You need the following libraries: ... and finally everything should work like this:
Have fun - and don't forget: Pointless resistance!

Now I have my Fluxamasynth shield!

I just wrote a very simple program which uses NewSoftSerial for the MIDI communication towards the Fluxamasynth shield on pin 4. This small program runs through the 256 sounds of the shield (on MIDI channel 1) and plays a chord (randomized start note).



The source code should be easy to understand:

#include <fluxamasynth_nss.h>
#include <newsoftserial.h>

Fluxamasynth synth;

#define c3 48          // define our notes to their midi values
#define e3 52
#define g3 55
#define c4 60

void setup()
{
  Serial.begin(9600);
  synth.setMasterVolume(100);
}

void loop()
{
  byte i=0,n=0,z=0;

  for (n=0;n<=1;n++)
  {
    for(i=0;i<=127;i++)
    {
      synth.programChange(n*127,0, i);

      Serial.print("Bank: ");
      Serial.print(n,DEC);
      Serial.print(" Sound: ");
      Serial.println(i,DEC);

      z=random(0,12);

      synth.noteOn(0, c3+z, 107);
      delay(100);
      synth.noteOn(0, e3+z, 107);
      delay(100);
      synth.noteOn(0, g3+z, 107);
      delay(100);
      synth.noteOn(0, c4+z, 107);

      delay(200);
      synth.noteOff(0, c3+z);
      synth.noteOff(0, e3+z);
      synth.noteOff(0, g3+z);
      synth.noteOff(0, c4+z);
      delay(200);
    }
  }
}

You also need the NewSoftSerial library from http://arduiniana.org/libraries/newsoftserial/ and the Fluxamasynth library from http://wiki.moderndevice.com/pmwiki.php?n=MD.Fluxamasynth.

The next step is to try how to play MIDI songs. The Fluxmasynth shield can play up to 8 voices and a drumset!