summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2013-05-19 19:20:08 +0200
committerFlorian Jung <flo@windfisch.org>2013-05-19 19:20:08 +0200
commitfcf34b20d40d511cbc36964d53fa00656ad8807a (patch)
tree22a323e94c6308a4f562f994b697aea49c5ea78e
initial commit
-rw-r--r--config.txt2
-rw-r--r--groups.txt17
-rw-r--r--midirip.c340
-rw-r--r--parse0.c276
-rw-r--r--patches.txt128
-rw-r--r--trim.c61
-rw-r--r--wav.c102
7 files changed, 926 insertions, 0 deletions
diff --git a/config.txt b/config.txt
new file mode 100644
index 0000000..0b49a0a
--- /dev/null
+++ b/config.txt
@@ -0,0 +1,2 @@
+2,3) a4 100 500, a4 a5 100 500
+
diff --git a/groups.txt b/groups.txt
new file mode 100644
index 0000000..5b25603
--- /dev/null
+++ b/groups.txt
@@ -0,0 +1,17 @@
+0-7 00Piano
+8-15 01Chromatic
+16-23 02Organ
+24-31 03Guitar
+32-39 04Bass
+40-47 05Strings
+48-55 06Ensemble
+56-63 07Brass
+64-71 08Reed
+72-79 09Pipe
+80-87 10SynLead
+88-95 11SynPad
+96-103 12SynFX
+104-111 13Ethnic
+112-119 14Perc
+120-127 15FX
+
diff --git a/midirip.c b/midirip.c
new file mode 100644
index 0000000..f0c86a5
--- /dev/null
+++ b/midirip.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2010 Florian Jung <flo@windfisch.org>
+ * for the MIDI constants and some jack-midi code, which has been
+ * taken from jack-keyboard:
+ * Copyright (c) 2007, 2008 Edward Tomasz Napierała <trasz@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <jack/jack.h>
+#include <jack/midiport.h>
+#include <jack/ringbuffer.h>
+
+
+#define MIDI_PORT_NAME "midi"
+#define REC_PORT_NAME "rec"
+
+jack_port_t *recport, *midiport;
+double rate_limit = 0.0;
+jack_client_t *jack_client = NULL;
+
+#define MIDI_NOTE_ON 0x90
+#define MIDI_NOTE_OFF 0x80
+#define MIDI_PROGRAM_CHANGE 0xC0
+#define MIDI_CONTROLLER 0xB0
+#define MIDI_RESET 0xFF
+#define MIDI_HOLD_PEDAL 64
+#define MIDI_ALL_SOUND_OFF 120
+#define MIDI_ALL_MIDI_CONTROLLERS_OFF 121
+#define MIDI_ALL_NOTES_OFF 123
+#define MIDI_BANK_SELECT_MSB 0
+#define MIDI_BANK_SELECT_LSB 32
+
+#define BANK_MIN 0
+#define BANK_MAX 127
+#define PROGRAM_MIN 0
+#define PROGRAM_MAX 16383
+#define CHANNEL_MIN 1
+#define CHANNEL_MAX 16
+
+#define time_offsets_are_zero 0
+
+struct MidiMessage {
+ jack_nframes_t time;
+ int len; /* Length of MIDI message, in bytes. */
+ unsigned char data[3];
+};
+
+#define RINGBUFFER_SIZE 1024*sizeof(struct MidiMessage)
+
+jack_ringbuffer_t *ringbuffer;
+
+/* Number of currently selected channel (0..15). */
+int channel = 9;
+
+
+
+//FINDMICH
+#define RECBUF_LEN 44100*60
+#define SILENCE_LEN 44100*2
+#define SILENCE_ADD 0.01
+#define QUIET_LEN 44100*1
+#define WAIT_AFTER 22050
+
+jack_default_audio_sample_t recbuf[RECBUF_LEN];
+int rbpos;
+jack_default_audio_sample_t silence;
+int note=60, laut=100, notelen=22050;
+
+int flo_start=0;
+
+jack_default_audio_sample_t arr_dist (jack_default_audio_sample_t a[], int l)
+{
+ int i;
+ jack_default_audio_sample_t max,min;
+ min=max=a[0];
+
+ for (i=0;i<l;i++)
+ if (a[i]>max)
+ max=a[i];
+ else if (a[i]<min)
+ min=a[i];
+
+ return max-min;
+}
+
+
+int process_callback(jack_nframes_t nframes, void *notused) //WICHTIG FINDMICH
+{
+ static int state = 0;
+ static int frame_cnt;
+
+ int i;
+ void *midipb;
+ jack_nframes_t last_frame_time;
+ unsigned char data[3];
+
+ last_frame_time = jack_last_frame_time(jack_client);
+
+
+ jack_default_audio_sample_t *recpb=
+ (jack_default_audio_sample_t *) jack_port_get_buffer (recport, nframes);
+ if (recpb==NULL) printf("rec fail\n");
+
+ midipb = jack_port_get_buffer(midiport, nframes);
+ if (midipb==NULL) printf("midi fail\n");
+ jack_midi_clear_buffer(midipb);
+
+
+ switch(state)
+ {
+ case 0: // warte auf freigabe
+ if (flo_start)
+ {
+ state=1;
+ rbpos=0;
+ printf("messe stille\n");
+ }
+ break;
+
+ case 1: // sammle daten über stille
+ for (i=0;i<nframes;i++)
+ {
+ recbuf[rbpos]=recpb[i];
+ rbpos++;
+ }
+ if (rbpos>=SILENCE_LEN) //genug?
+ {
+ silence=arr_dist(recbuf,SILENCE_LEN) + SILENCE_ADD;
+ printf(" stille=%f\n",silence);
+ state=2;
+ }
+ break;
+
+ case 2: // spiele note
+ //TODO: hole nächsten eintrag
+ printf("NOTE ON\n");
+ data[0]=MIDI_NOTE_ON;
+ data[1]=note; //TODO
+ data[2]=laut; //TODO
+ if (jack_midi_event_write(midipb, 0, data, 3))
+ fprintf(stderr,"Note loss when writing\n");
+ frame_cnt=notelen; //TODO
+
+ rbpos=0;
+
+ state=3;
+ break;
+
+ case 3: // nehme auf und sende ggf note off
+ if (frame_cnt != -1) //ggf note off
+ {
+ if (frame_cnt < nframes) //noteoff in diesem frame?
+ {
+ printf("NOTE OFF in %i\n",frame_cnt);
+ data[0]=MIDI_NOTE_OFF;
+ data[1]=note; //TODO
+ data[2]=laut; //TODO
+
+ if (jack_midi_event_write(midipb, frame_cnt, data, 3))
+ fprintf(stderr,"Note loss when writing\n");
+
+ frame_cnt=-1;
+ }
+ else
+ frame_cnt-=nframes;
+ }
+
+ for (i=0;i<nframes;i++) //aufnehmen
+ {
+ if (rbpos>=RECBUF_LEN)
+ printf("WARNING: segfault\n"); //TODO
+ recbuf[rbpos]=recpb[i];
+ rbpos++;
+ }
+ if (rbpos>QUIET_LEN)
+ {
+// printf ("%f\n",arr_dist(&recbuf[rbpos-QUIET_LEN],QUIET_LEN));
+ if (arr_dist(&recbuf[rbpos-QUIET_LEN],QUIET_LEN)<=silence) //es wird still...
+ {
+ if (recend!=-1) recend=rbpos-QUIET_LEN;
+
+ if (frame_cnt==-1) //ggf aufs noteoff warten
+ {
+ printf ("aufnahme fertig\n");
+ frame_cnt=WAIT_AFTER;
+
+ for (i=1;i<=QUIET_LEN;i++)
+ if (arr_dist(recbuf,i) > silence)
+ recstart=i-1;
+
+ if (recstart==-1)
+ for (i=QUIET_LEN;i<recend;i++)
+ if (arr_dist(&recbuf[i-QUIET_LEN],QUIET_LEN) > silence)
+ recstart=i-1;
+
+ if (recstart!=-1)
+ {
+ printf("gotcha.\n"); //TODO: speichern
+ }
+ else
+ {
+ printf ("komisch. nur stille aufgenommen...\n"); //TODO handlen!
+ }
+
+ state=4; //fertig mit aufnehmen
+ }
+ }
+ else //nicht (mehr?) still?
+ {
+ if (recend!=-1)
+ printf("komisch... erst still, dann laut?\n");
+ recend=-1;
+ }
+ }
+ break;
+
+ case 4: //fertig mit aufnehmen, es ist bereits wieder still; noch einige zeit warten
+ frame_cnt-=nframes;
+ if (frame_cnt<=0)
+ {
+ frame_cnt=-1;
+ printf ("fertig mit warten\n");
+ state=2;
+ }
+
+ break;
+ }
+
+ if (nframes <= 0) {
+ fprintf(stderr,"Process callback called with nframes = 0; bug in JACK?\n");
+ return 0;
+ }
+
+
+ return 0;
+}
+
+void init_jack(void) //WICHTIG !!!
+{
+ jack_client = jack_client_open("ripmidi", JackNullOption, NULL);
+ if (jack_client == NULL)
+ {
+ fprintf(stderr,"Registering client failed.\n");
+ exit(1);
+ }
+
+ ringbuffer = jack_ringbuffer_create(RINGBUFFER_SIZE);
+ if (ringbuffer == NULL)
+ {
+ fprintf(stderr,"Creating ringbuffer failed.\n");
+ exit(1);
+ }
+ jack_ringbuffer_mlock(ringbuffer);
+
+ if (jack_set_process_callback(jack_client, process_callback, 0))
+ {
+ fprintf(stderr,"Registering callback failed.\n");
+ exit(1);
+ }
+
+ recport=jack_port_register(jack_client, REC_PORT_NAME, JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsInput, 0);
+ midiport = jack_port_register(jack_client, MIDI_PORT_NAME, JACK_DEFAULT_MIDI_TYPE,
+ JackPortIsOutput, 0);
+
+ if ((midiport == NULL) || (recport == NULL)) {
+ fprintf(stderr,"Registering ports failed.\n");
+ exit(1);
+ }
+
+ if (jack_activate(jack_client))
+ {
+ fprintf(stderr,"Activating client failed.\n");
+ exit(1);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ //init header
+ strcpy(wavheader+ 0, "RIFF");
+ //u32cpy(wavheader+ 4, filelen-8);
+ strcpy(wavheader+ 8, "WAVE");
+
+ strcpy(wavheader+12, "fmt ");
+ u32cpy(wavheader+16, 16);
+ u16cpy(wavheader+20, 1);
+ u16cpy(wavheader+22, 1);
+ u32cpy(wavheader+24, samp_rate);
+ u32cpy(wavheader+28, samp_rate*bytes);
+ u16cpy(wavheader+32, bytes);
+ u16cpy(wavheader+34, bytes*8);
+
+ strcpy(wavheader+36, "data");
+ //u32cpy(wavheader+40, datalen);
+
+
+
+
+ rbpos=0;
+ init_jack();
+
+ char foo[10]; gets(foo);
+
+ flo_start=1;
+
+ gets(foo);
+
+ return 0;
+}
+
diff --git a/parse0.c b/parse0.c
new file mode 100644
index 0000000..5a015d8
--- /dev/null
+++ b/parse0.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2010 Florian Jung <flo@windfisch.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+
+#include <stdio.h>
+
+// a0 b0 c0 d0 e0 f0 g0
+const int notemap[7]={33,35,24,26,28,29,31};
+
+int getnum(char *s, int *i)
+{
+ int minus=0;
+ int num=0;
+
+ if (s[*i]=='-')
+ {
+ minus=1;
+ (*i)++;
+ }
+ while((s[*i]>='0') && (s[*i]<='9'))
+ {
+ num=num*10+s[*i]-'0';
+ (*i)++;
+ }
+
+ if (minus) return -num; else return num;
+}
+
+int parserange(char *s, int l[])
+{
+ int i, state=0;
+ int j=0;
+ int num, end;
+
+ for (i=0;;i++)
+ if ((s[i]!=' ') && (s[i]!='\t'))
+ {
+ switch(state)
+ {
+ case 0: //expects the (first) number
+ if ((s[i]>='0') && (s[i]<='9')) //a number?
+ {
+ num=getnum(s,&i);
+ i--;
+ state=1;
+ }
+ break;
+ case 1: //expects a , or a -
+ if (s[i]=='-')
+ {
+ state=2;
+ }
+ else if ((s[i]==',') || (s[i]==0))
+ {
+ l[j]=num;
+ j++;
+ printf ("num=%i\n",num);
+ state=0;
+ }
+ else
+ {
+ printf("ERROR: expected ',' or '-', found '%c'\n",s[i]);
+ return -1;
+ }
+ break;
+
+ case 2: //expects the second number that ends a range
+ if ((s[i]>='0') && (s[i]<='9')) //a number?
+ {
+ end=getnum(s,&i);
+ printf("numrange=%i-%i\n",num,end);
+ for (;num<=end;num++)
+ {
+ l[j]=num;
+ j++;
+ }
+
+ i--;
+ state=3;
+ }
+ else
+ {
+ printf("ERROR: expected number, found '%c'\n",s[i]);
+ return -1;
+ }
+ break;
+
+ case 3: //expects ','
+ if ((s[i]==',') || (s[i]==0))
+ state=0;
+ else
+ {
+ printf("ERROR: expected ',', found '%c'\n",s[i]);
+ return -1;
+ }
+ }
+ if (s[i]==0) break;
+ }
+
+ return j;
+
+}
+
+int main(int argc, char** argv)
+{
+ int i,l;
+ FILE* f;
+ char line[1000];
+ char *range, *param;
+ int patchlist[128];
+
+ int oct,loud,len;
+ int notenum, note[10];
+ int j;
+ int state;
+ int dontignore;
+ int rangelen;
+
+ f=fopen ("config.txt","r");
+ l=0;
+ while(!feof(f))
+ {
+ fgets(line,sizeof(line),f);
+ printf ("read %s",line);
+ l++;
+
+ dontignore=0;
+ for (i=0;line[i];i++)
+ if ((line[i]!=' ') && (line[i]!='\t') && (line[i]!='\n'))
+ {
+ dontignore=1;
+ }
+
+ if (dontignore)
+ {
+ for (i=0;(line[i]!=0) && (line[i]!=')');i++); //find ')'
+ if (line[i]==0)
+ {
+ printf("ERROR: expected ), found EOL in line %i\n",l);
+ }
+ else
+ {
+ line[i]=0;
+ range=line;
+ param=line+i+1;
+
+ rangelen=parserange(range,patchlist);
+ if (rangelen==-1)
+ {
+ printf ("ERROR: invalid range specified in line %i\n",l);
+ }
+
+ while(1)
+ {
+ for (i=0;(param[i]!=0) && (param[i]!=',') && (param[i]!='\n');i++); //find ','
+
+ printf("'%s', '%s'\n",range,param);
+
+ state=0;
+ len=1337;//TODO sane default
+ notenum=0;
+ note[notenum]=0; oct=99;
+
+ for (j=0;j<i;j++)
+ {
+ printf ("%i: ",j);
+ switch (state)
+ {
+ case 0: //expects a note (a4) or loudness (<num>) or \0
+ if ((param[j]>='a') && (param[j]<='g')) //found a note
+ {
+ printf("found a note\n");
+ note[notenum]=notemap[param[j]-'a'];
+ if ((param[j+1]=='b') || param[j+1]=='#') //vorzeichen?
+ {
+ if (param[j+1]=='b')
+ note[notenum]--;
+ else
+ note[notenum]++;
+ j++;
+ }
+ state=1;
+ }
+ else if ((param[j]>='0') && (param[j]<='9')) //found a number
+ {
+ printf("found loudness\n");
+ loud=getnum(param,&j);
+ printf("j=%i\n",j);
+ state=2;
+ }
+ else if ((param[j]!=' ') && (param[j]!='\t'))
+ {
+ printf("ERROR: expected note or number, found %c in line %i\n",param[j],l);
+ }
+ break;
+
+ case 1: //expects octave (-1 or 4)
+ if ((param[j]=='-') || ((param[j]>='0') && (param[j]<='9')))
+ {
+ printf("found octave\n");
+ oct=getnum(param,&j);
+ note[notenum]+=oct*12;
+ printf (" note=%i\n",note[notenum]);
+
+ notenum++;
+ state=0;
+ }
+ else
+ {
+ printf ("ERROR: expected - or 0-9, found %c in line %i\n",param[j],l);
+ }
+ break;
+
+
+ case 2: //expects notelen or 0
+ if ((param[j]>='0') && (param[j]<='9'))
+ {
+ printf("found notelen\n");
+ len=getnum(param,&j);
+ state=4;
+ }
+ else if ((param[j]!=' ') && (param[j]!='\t'))
+ {
+ printf("ERROR: expected number, found %c in line %i\n",param[j],l);
+ }
+ }
+ }
+
+ //TODO: neuen eintrag erstellen
+ printf ("==== RESULT: loud=%i, len=%i, notes=",loud,len);
+ for (j=0;j<notenum;j++)
+ printf("%i ",note[j]);
+
+ printf("\n");
+
+ if (param[i]==',') //is there a next param?
+ {
+ param=&param[i+1];
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ printf("%i\n",i);
+ }
+
+ return 0;
+}
diff --git a/patches.txt b/patches.txt
new file mode 100644
index 0000000..2e0eebd
--- /dev/null
+++ b/patches.txt
@@ -0,0 +1,128 @@
+0 AcPiano
+1 BrPiano
+2 ElPiano
+3 Honkytonk
+4 ElPiano1
+5 ElPiano2
+6 Harps
+7 Clavi
+8 Celesta
+9 Glockenspiel
+10 MusicBox
+11 Vibraphone
+12 Marimba
+13 Xylophone
+14 TubBells
+15 Dulcimer
+16 DrawOrg
+17 PercOrg
+18 RockOrg
+19 ChurchOrg
+20 ReedOrg
+21 Accordion
+22 Harmonica
+23 TangoAcc
+24 NylonGuit
+25 SteelGuit
+26 JazzGuit
+27 CleanGuit
+28 MutedGuit
+29 OvDrGuit
+30 DistGuit
+31 GuitHarm
+32 AcBass
+33 FingerBass
+34 PickBass
+35 Fretless Bass
+36 SlapBass1
+37 SlapBass2
+38 SynBass1
+39 SynBass2
+40 Violin
+41 Viola
+42 Cello
+43 Contrabass
+44 TremStr
+45 PizzStr
+46 Harp
+47 Timpani
+48 Strings1
+49 Strings2
+50 SynStrings1
+51 SynStrings2
+52 Aahs
+53 Oohs
+54 SynVoice
+55 OrchHit
+56 Trumpet
+57 Trombone
+58 Tuba
+59 MutedTrumpet
+60 FrenchHorn
+61 BrassSect
+62 SynBrass1
+63 SynBrass2
+64 SopSax
+65 AltSax
+66 TenSax
+67 BariSax
+68 Oboe
+69 EngHorn
+70 Bassoon
+71 Clarinet
+72 Piccolo
+73 Flute
+74 Recorder
+75 PanFlute
+76 Bottle
+77 Shakuhachi
+78 Whistle
+79 Ocarina
+80 SqLead
+81 SawLead
+82 CallLead
+83 ChiffLead
+84 CharLead
+85 VoiceLead
+86 FifthsLead
+87 BassLead
+88 NewAgePad
+89 WarmPad
+90 Polysynth
+91 ChoirPad
+92 BowedPad
+93 MetalPad
+94 HaloPad
+95 SweepPad
+96 FXRain
+97 FXSndTrck
+98 FXCrystal
+99 FXAtmo
+100 FXBright
+101 FXGoblins
+102 FXEchoes
+103 FXSciFi
+104 Sitar
+105 Banjo
+106 Shamisen
+107 Koto
+108 Kalimba
+109 Bagpipe
+110 Fiddle
+111 Shanai
+112 TinkBell
+113 Agogo
+114 SteelDrums
+115 Woodblock
+116 TaikoDrum
+117 MelTom
+118 SynDrum
+119 RevCymbal
+120 GuitFret
+121 Breath
+122 Seashore
+123 Bird
+124 Telephone
+125 Helicopter
+126 Applause
+127 Gunshot
diff --git a/trim.c b/trim.c
new file mode 100644
index 0000000..baccd57
--- /dev/null
+++ b/trim.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 Florian Jung <flo@windfisch.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+ char param[]=" a4 c#5 e5 200 ";
+
+ char ntmp[100];
+ int supp_spc=1;
+ int i,j;
+ j=0;
+ for (i=0;param[i];i++)
+ { //if there will begin a new parameter, and there's not space or a note
+ if ( !((param[i]>='a') && (param[i]<='g') ||
+ (param[i]==' ') || (param[i]=='\t') ) && supp_spc) break;
+
+ if ((param[i]==' ') || (param[i]=='\t'))
+ {
+ if (!supp_spc)
+ ntmp[j++]=' ';
+ supp_spc=1;
+ }
+ else
+ {
+ supp_spc=0;
+ ntmp[j++]=param[i];
+ }
+ }
+ ntmp[j]=0;
+ if (ntmp[j-1]==' ') ntmp[j-1]=0;
+
+printf("'%s'\n",ntmp);
+ return 0;
+}
diff --git a/wav.c b/wav.c
new file mode 100644
index 0000000..e2ca4fd
--- /dev/null
+++ b/wav.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010 Florian Jung <flo@windfisch.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+
+#include <stdio.h>
+
+
+
+void u16cpy(char *dest, int src)
+{
+ dest[0]=src%256;
+ dest[1]=src/256;
+}
+
+void s16cpy(char *dest, int src)
+{
+ if (src<0)
+ src=(~(-src))+1;
+
+ u16cpy(dest,src);
+}
+
+void u32cpy(char *dest, long int src)
+{
+ dest[0]=src%256;
+ dest[1]=(src/256)%256;
+ dest[2]=(src/256/256)%256;
+ dest[3]=(src/256/256/256)%256;
+}
+
+int main(int argc, char** argv)
+{
+ FILE *f;
+ f=fopen("test.wav","w");
+
+ //char buf[44];
+ char buf[244];
+
+ int datalen,filelen,n_chans,samp_rate,bytes;
+
+ datalen=100;
+ n_chans=1;
+ samp_rate=22050;
+ bytes=2;
+
+
+ filelen=12 + 24 + 8+datalen; //RIFF<len>WAVE|fmt <len><fmt>|DATA<len><data>
+
+ strcpy(buf+ 0, "RIFF");
+ u32cpy(buf+ 4, filelen-8);
+ strcpy(buf+ 8, "WAVE");
+
+ strcpy(buf+12, "fmt ");
+ u32cpy(buf+16, 16);
+ u16cpy(buf+20, 1); // format=1 (PCM)
+ u16cpy(buf+22, n_chans); // mono
+ u32cpy(buf+24, samp_rate);
+ u32cpy(buf+28, samp_rate*n_chans*bytes);
+ u16cpy(buf+32, n_chans*bytes);
+ u16cpy(buf+34, bytes*8);
+
+ strcpy(buf+36, "data");
+ u32cpy(buf+40, datalen);
+ //data follows
+
+ int i;
+ for (i=0;i<100;i++)
+ {
+ s16cpy(buf+i*2+44, sin((double)i/50.0*3.141592654*2)*30000);
+ //buf[i*2+44]= (sin((double)i/100.0*3.141592654*2)*30000);
+ }
+
+
+ fwrite(buf,1,244,f);
+ fclose(f);
+
+ return 0;
+}