diff options
Diffstat (limited to 'midirip.c')
-rw-r--r-- | midirip.c | 963 |
1 files changed, 963 insertions, 0 deletions
diff --git a/midirip.c b/midirip.c new file mode 100644 index 0000000..8fff403 --- /dev/null +++ b/midirip.c @@ -0,0 +1,963 @@ +/* + * 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. + */ + + +/* TODO + * bytes aus datei lesen + * --overwrite-option? + * zwischen normalem und drum-modus wechseln! + */ + +//LAST STABLE: 08 + +// #define DRUM_MODE + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.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.005 //schon ziemlich knapp. lieber weniger +#define QUIET_LEN 441 +#define WAIT_AFTER 22050 +#define MAX_NOTES 10 +#define DEFAULT_LEN 1000 //TODO richtigen wert finden! +#define LATENCY 1000 + +jack_default_audio_sample_t buf1[RECBUF_LEN], buf2[RECBUF_LEN]; +jack_default_audio_sample_t *recbuf, *workbuf; +jack_default_audio_sample_t silence; +int note=60, laut=100, notelen=22050; +int main_working, all_done; +int workstart, workend, main_rbpos; + +int samp_rate; +int bytes=2; +char wavheader[44]; +int flo_start; + +struct entry_t +{ + char chan; + char patch; + + char loud; + char note[MAX_NOTES]; + int notelen; + + char *file, *dir; + + struct entry_t *next; +}; +typedef struct entry_t entry_t; + +entry_t *recentry, *workentry, *firstentry; + +const int notemap[7]={33,35,24,26,28,29,31}; + +char *dirs[128]; +char *patchname[128]; + + +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; + +} + + +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; +} + + + +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, frame_cnt2; + static int rbpos=0, recend; + 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 und initialisiere + if (flo_start) + { + state=1; + rbpos=0; + recentry=firstentry; + 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, wie in recentry beschrieben +// printf("NOTE ON\n"); + //TODO ggf noch bank select? + + data[0]=MIDI_PROGRAM_CHANGE; + data[1]=recentry->patch; + if (jack_midi_event_write(midipb, 0, data, 2)) + fprintf(stderr,"Note loss when writing\n"); + + data[0]=MIDI_NOTE_ON + (recentry->chan & 0x0F); + data[2]=recentry->loud; + + for (i=0;recentry->note[i]!=-1;i++) + { + data[1]=recentry->note[i]; + if (jack_midi_event_write(midipb, 0, data, 3)) + fprintf(stderr,"Note loss when writing\n"); + } + frame_cnt=recentry->notelen; + frame_cnt2=LATENCY*samp_rate/1000; + + rbpos=0; + recend=-1; + + state=3; + break; + + case 3: // nehme auf und sende ggf note off + if (frame_cnt2 != -1) + { + frame_cnt2-=nframes; + if (frame_cnt2<=0) frame_cnt2=-1; + } + 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 + (recentry->chan & 0x0F); + data[2]=recentry->loud; + for (i=0;recentry->note[i]!=-1;i++) + { + data[1]=recentry->note[i]; + 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: statt segfault tainted setzen und im letzten bufferteil loopen + recbuf[rbpos]=recpb[i]; + rbpos++; + } + if (rbpos>QUIET_LEN) //TODO FINDMICH: QUIET_LEN mit nframes ersetzen??? + { + if (arr_dist(&recbuf[rbpos-QUIET_LEN],QUIET_LEN)<=silence) //es wird still... + { + if (recend==-1) recend=rbpos-QUIET_LEN; + + if ((frame_cnt==-1) && (frame_cnt2==-1)) //ggf aufs noteoff warten + { +// printf ("aufnahme fertig\n"); + + state=4; + } + } + else //nicht (mehr?) still + { + recend=-1; + } + } + break; + + case 4: //auf verarbeitungs-thread warten + if (main_working==0) //main ist fertig? + { + if (recbuf==buf1) //buffer wechseln + { + recbuf=buf2; + workbuf=buf1; + } + else + { + recbuf=buf1; + workbuf=buf2; + } + workend=recend; + main_rbpos=rbpos; + workentry=recentry; + + main_working=1; //befehl zum starten geben + + + recentry=recentry->next; + if (recentry==NULL) //fertig? + { + printf("all done, waiting for main to finish and clean up\n"); + all_done=1; + state=99; + } + else + { + frame_cnt=WAIT_AFTER; + state=5; + } + } + break; + + case 5: //noch einige zeit warten + frame_cnt-=nframes; + if (frame_cnt<=0) + { + frame_cnt=-1; +// printf ("fertig mit warten\n"); + state=2; + } + break; + + case 99: //nichts tun, main wird alles fertig machen, aufräumen und beenden. + 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); + } + + samp_rate=jack_get_sample_rate(jack_client); + + if (jack_activate(jack_client)) + { + fprintf(stderr,"Activating client failed.\n"); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + int i,j,k,l,m; + FILE* f; + char line[1000]; + char *range, *param; + int patchlist[128]; + + int oct,loud,len; + int notenum, note[10]; + int state; + int dontignore; + int rangelen; + + int drumprogram; + + entry_t *curr_entry; + + + //TODO nettes CLI + + + bytes=2; + + //init + recbuf=buf1; workbuf=buf2; + main_working=0; all_done=0; + flo_start=0; + + init_jack(); + + +//TODO patchname und dirs initialisieren FINDMICH + char dummy[]="unknown"; + for (i=0;i<128;i++) + dirs[i]=patchname[i]=dummy; + + f=fopen("patches.txt","r"); + while(!feof(f)) + { + fgets(line,sizeof(line),f); + for (i=strlen(line)-1;i>=0;i--) //remove trailing spaces + { + if ((line[i]=='\n') || (line[i]==' ') || (line[i]=='\t')) + line[i]=0; + else + break; + } + + + if (!isdigit(line[0])) + { + fprintf(stderr,"invalid number in patchlist, ignoring it...\n"); + } + else + { + i=0; + m=getnum(line,&i); + while ( ((line[i]==' ') || (line[i]=='\t')) && line[i] ) i++; //line[i] is letter or NUL + asprintf(&patchname[m], "%s", line+i); + } + } + fclose(f); + +#ifndef DRUM_MODE + f=fopen("groups.txt","r"); + while(!feof(f)) + { + fgets(line,sizeof(line),f); + for (i=strlen(line)-1;i>=0;i--) //remove trailing spaces + { + if ((line[i]=='\n') || (line[i]==' ') || (line[i]=='\t')) + line[i]=0; + else + break; + } + + char *grptmp; + for (i=0;line[i];i++) + if ((line[i]=='\n') || (line[i]==' ') || (line[i]=='\t')) + { + line[i]=0; + grptmp=&line[i+1]; + break; + } + + int grprange[128]; + m=parserange(line,grprange); + if (m<0) + { + printf("error parsing range, ignoring the line...\n"); + } + else + { + char *grptmp2; + asprintf(&grptmp2, "%s", grptmp); + for (i=0;i<m;i++) + dirs[grprange[i]]=grptmp2; + } + } + + fclose(f); +#endif + + f=fopen ("config.txt","r"); + l=0; + curr_entry=firstentry=NULL; + while(!feof(f)) + { + fgets(line,sizeof(line),f); + 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); + goto invalid; + } + + 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); + goto invalid; + } + + while(1) + { + for (i=0;(param[i]!=0) && (param[i]!=',') && (param[i]!='\n');i++); //find ',' + +#ifdef DRUM_MODE + for (j=0;(param[j]!=0) && ((param[j]==' ') || (param[j]=='\t'));j++); //find nonspace + drumprogram=getnum(param,&j); + loud=120; //TODO anderer default? + len=75; + + for (;(param[j]!=0) && ((param[j]==' ') || (param[j]=='\t'));j++); //find next nonspace + if (isdigit(param[j])) + { + printf("loud specified\n"); + loud=getnum(param,&j); + } + for (;(param[j]!=0) && ((param[j]==' ') || (param[j]=='\t'));j++); //find next nonspace + if (isdigit(param[j])) + { + len=getnum(param,&j); + printf("len\n"); + } + + +#else //ifndef DRUM_MODE + state=0; + len=DEFAULT_LEN; + notenum=0; + note[notenum]=0; oct=99; + + for (j=0;j<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); + state=2; + } + else if ((param[j]!=' ') && (param[j]!='\t')) + { + printf("ERROR: expected note or number, found %c in line %i\n",param[j],l); + goto invalid; + } + break; + + case 1: //expects octave (-2 or 4) + if ((param[j]=='-') || ((param[j]>='0') && (param[j]<='9'))) + { +// printf("found octave\n"); + oct=getnum(param,&j); + + note[notenum]+=oct*12; + if ((note[notenum]<0) || (note[notenum]>127)) //illegal note + { + printf("ERROR: invalid note in line %i\n",l); + goto invalid; + } + else + notenum++; + state=0; + } + else + { + printf ("ERROR: expected - or 0-9, found %c in line %i\n",param[j],l); + goto invalid; + } + break; + + + case 2: //expects notelen or 0 + if ((param[j]>='0') && (param[j]<='9')) + { +// printf("found notelen\n"); + len=getnum(param,&j); + if (len<0) + { + printf("WARNING: len was negative in line %i; using absolute value\n",l); + len=-len; + } + state=4; + } + else if ((param[j]!=' ') && (param[j]!='\t')) + { + printf("ERROR: expected number, found %c in line %i\n",param[j],l); + goto invalid; + } + } + } + +#endif + //in die liste eintragen + + for (k=0;k<rangelen;k++) + { + entry_t *tmpptr=malloc(sizeof(entry_t)); + if (tmpptr==NULL) + { + printf("GAAAH... malloc error\n"); + exit(1); + } + if (firstentry==NULL) + firstentry=tmpptr; + else + curr_entry->next=tmpptr; + + tmpptr->loud=loud; + tmpptr->notelen=len*samp_rate /1000; //von msec in samples umrechnen +#ifndef DRUM_MODE + tmpptr->chan=0; + tmpptr->patch=patchlist[k]; + tmpptr->dir=dirs[patchlist[k]]; + + char ntmp[100]; //trim multiple, leading and trailing spaces from param + int supp_spc=1; + j=0; + for (m=0;(param[m]!=0) && (param[m]!=',') && (param[m]!='\n');m++) + { //if there will begin a new parameter, and there's not space or a note + if ( !(((param[m]>='a') && (param[m]<='g')) || + (param[m]==' ') || (param[m]=='\t') ) && supp_spc) break; + + if ((param[m]==' ') || (param[m]=='\t')) + { + if (!supp_spc) + ntmp[j++]=' '; + supp_spc=1; + } + else + { + supp_spc=0; + ntmp[j++]=param[m]; + } + } + ntmp[j]=0; + if (ntmp[j-1]==' ') ntmp[j-1]=0; + + asprintf(&tmpptr->file, "%s/%03i%s %s %03i %ims.wav",tmpptr->dir, tmpptr->patch, + patchname[tmpptr->patch], ntmp, tmpptr->loud, len); + + + for (j=0;j<notenum;j++) + tmpptr->note[j]=note[j]; + tmpptr->note[notenum]=-1; +#else // ifdef DRUM_MODE + tmpptr->chan=9; + tmpptr->note[0]=patchlist[k]; tmpptr->note[1]=-1; + tmpptr->patch=drumprogram; + + tmpptr->dir="drums"; + asprintf(&tmpptr->file, "%s/%03i%s %i %i %ims.wav",tmpptr->dir, tmpptr->note[0], + patchname[tmpptr->note[0]], tmpptr->patch, tmpptr->loud, len); + + + printf("chan=%i, note=%i, patch=%i, loud=%i, len=%i,\n\tdir='%s', file='%s'\n", + tmpptr->chan, tmpptr->note[0], tmpptr->patch, tmpptr->loud, tmpptr->notelen, + tmpptr->dir, tmpptr->file); +#endif + + tmpptr->next=NULL; + + curr_entry=tmpptr; + } + + if (param[i]==',') //is there a next param? + param=¶m[i+1]; + else + break; + } + } + } + + + + + + + //init header + strcpy(wavheader+ 0, "RIFF"); + 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"); + + + + + printf("connect ripmidi's midi port to some MIDI OUT and the audio\n" + "port to the corresponding audio input port; then press enter\n"); + char foo[10]; gets(foo); + + flo_start=1; + + main_working=0; + printf("main: entering loop\n"); + while(1) + { + while ((main_working==0) && (all_done==0)) usleep(100000); // 0.1 sec + + printf("main: starting work cycle\n"); + + workstart=-1; + for (i=1;i<=QUIET_LEN;i++) //Find begin of non-silence + if (arr_dist(workbuf,i) > silence) + { + workstart=i-1; + break; + } + + if (workstart==-1) // [ continued ] + for (i=QUIET_LEN;i<workend;i++) + if (arr_dist(&workbuf[i-QUIET_LEN],QUIET_LEN) > silence) + { + workstart=i-1; + break; + } + + if (workstart!=-1) + { +// printf("main: gotcha. %i - %i [%i - %i]\n",workstart,workend,0,main_rbpos); + jack_default_audio_sample_t max=0.0; //find max amplitude + for (i=workstart; i<=workend; i++) + { + if (workbuf[i]>0) + { + if (workbuf[i]>max) max=workbuf[i]; + } + else + { + if (-workbuf[i]>max) max=-workbuf[i]; + } + } + + int datalen,filelen; + datalen=(workend-workstart+1)*bytes; + filelen=44+datalen; + u32cpy(wavheader+ 4, filelen-8); + u32cpy(wavheader+40, datalen); + + + int ret=mkdir(workentry->dir,S_IRWXU|S_IRWXG|S_IRWXO); + if ((ret==-1) && (errno!=EEXIST)) //a real error occurred + { + fprintf(stderr,"ERROR: could not create %s (%s)\n",workentry->dir,strerror(errno)); + } + + f=fopen(workentry->file,"w"); + if (f==NULL) + { + fprintf(stderr,"ERROR: could not open %s (%s)\n",workentry->file,strerror(errno)); + } + else + { + printf("writing to file %s\n",workentry->file); + unsigned char tmp[2]; + + fwrite(wavheader, 1, 44, f); + if (bytes==1) + for (i=workstart;i<=workend;i++) + { + *tmp=(workbuf[i]/max*127.0)+127; + fwrite(tmp,1,1,f); + } + else + for (i=workstart;i<=workend;i++) + { + s16cpy(tmp, (long)(workbuf[i]/max*32767.0)); + fwrite(&tmp,1,2,f); + } + + fclose(f); + } + + + } + else + { + printf ("ERROR: main: komisch. nur stille aufgenommen bei datei %s...\n",workentry->file); //TODO handlen! + } + + + printf("main: work done\n"); + main_working=0; + + if (all_done) break; + } + + printf("\n=== ALL DONE ===\n[exiting...]\n\n"); + return 0; + + + + invalid: + printf("config file invalid, exiting...\n"); + exit(1); +} + |