From dd53ec31c7123597d2c0fff93262293edfd12248 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Jun 2017 21:48:29 -0400 Subject: [PATCH] sound: add an Electric Duet dumper --- mockingboard/Makefile | 40 +++++++++++++ mockingboard/dump_ed.c | 39 +++++++++++++ mockingboard/notes.c | 126 +++++++++++++++++++++++++++++++++++++++++ mockingboard/notes.h | 2 + 4 files changed, 207 insertions(+) create mode 100644 mockingboard/Makefile create mode 100644 mockingboard/dump_ed.c create mode 100644 mockingboard/notes.c create mode 100644 mockingboard/notes.h diff --git a/mockingboard/Makefile b/mockingboard/Makefile new file mode 100644 index 00000000..ac85de56 --- /dev/null +++ b/mockingboard/Makefile @@ -0,0 +1,40 @@ +include ../Makefile.inc + +DOS33 = ../dos33fs-utils/dos33 +PNG2GR = ../gr-utils/png2gr + +all: dump_ed + +mock.dsk: + $(DOS33) -y tfv.dsk BSAVE -a 0x1000 TFV + $(DOS33) -y tfv.dsk BSAVE -a 0x400 TITLE.GR + $(DOS33) -y tfv.dsk BSAVE -a 0x900 ED + +TFV: tfv.o + ld65 -o TFV tfv.o -C ./apple2_1000.inc + +tfv.o: tfv.s title.inc + ca65 -o tfv.o tfv.s -l tfv.lst + +ED: duet.o + ld65 -o ED duet.o -C ./apple2_900.inc + +duet.o: duet.s + ca65 -o duet.o duet.s -l duet.lst + +TITLE.GR: title.png + $(PNG2GR) title.png TITLE.GR + +notes.o: notes.c + $(CC) $(CFLAGS) -c notes.c + +dump_ed.o: dump_ed.c notes.h + $(CC) $(CFLAGS) -c dump_ed.c + +dump_ed: dump_ed.o notes.o + $(CC) $(LFLAGS) -o dump_ed dump_ed.o notes.o + + +clean: + rm -f *~ TITLE.GR *.o *.lst ED + diff --git a/mockingboard/dump_ed.c b/mockingboard/dump_ed.c new file mode 100644 index 00000000..f4e219d8 --- /dev/null +++ b/mockingboard/dump_ed.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +#include "notes.h" + +int main(int argc, char **argv) { + + unsigned char triad[3]; + char temp[5]; + int fd,result; + + fd=open("HIGHWIND.ED",O_RDONLY); + if (fd<0) { + fprintf(stderr,"Could not open HIGHWIND.ED\n"); + return -1; + } + + while(1) { + result=read(fd,triad,3); + if (result<3) break; + + if (triad[0]==0) { + printf("Instrument 1=%d, Instrument 2=%d\n",triad[1],triad[2]); + } + else { + printf("Duration %d, ",triad[0]); + printf("%s ",ed_to_note(triad[1],temp)); + printf("%s ",ed_to_note(triad[2],temp)); + printf("\n"); + } + + } + + close(fd); + + return 0; +} diff --git a/mockingboard/notes.c b/mockingboard/notes.c new file mode 100644 index 00000000..e0a1dc1b --- /dev/null +++ b/mockingboard/notes.c @@ -0,0 +1,126 @@ +#include +#include +#include + +/* https://sourceforge.net/p/ed2midi/code/ */ +/* From a spreadsheet from ed2midi */ +/* Octave 1 2 3 4 5 + A 255 128 64 32 16 + A#/B- 240 120 60 30 15 + B 228 114 57 28 14 + C 216 108 54 27 13 + C#/D- 204 102 51 25 12 + D 192 96 48 24 12 + D#/E- 180 90 45 22 11 + E 172 86 43 21 10 + F 160 80 40 20 10 + F#/G- 152 76 38 19 9 + G 144 72 36 18 9 + G#/A- 136 68 34 17 8 +*/ + +int note_to_ed(char note, int flat, int sharp, int octave) { + + int value=0,result=0; + int octave_divider[5]={1,2,4,8,16}; + + switch(note) { + case 'A': + if (flat==1) value=272; + else if (sharp==1) value=240; + else value=256; + break; + case 'B': + if (flat==1) value=240; + else if (sharp==1) value=216; + else value=228; + break; + case 'C': + if (flat==1) value=228; + else if (sharp==1) value=204; + else value=216; + break; + case 'D': + if (flat==1) value=204; + else if (sharp==1) value=180; + else value=192; + break; + case 'E': + if (flat==1) value=180; + else if (sharp==1) value=160; + else value=172; + break; + case 'F': + if (flat==1) value=172; + else if (sharp==1) value=152; + else value=160; + break; + case 'G': + if (flat==1) value=152; + else if (sharp==1) value=136; + else value=144; + break; + default: + fprintf(stderr,"Unknown note %c\n",note); + } + + if ((octave<1) || (octave>5)) { + fprintf(stderr,"Invalid octave %d\n",octave); + return -1; + } + + result=value/octave_divider[octave-1]; + if (result>255) result=255; + + return result; +} + +static struct note_mapping_type { + int freq[12]; +} note_mapping[5]={ + /* A A# B C C# D D# E F F# G G# */ + {{ 255,240,228,216,204,192,180,172,160,152,144,136}}, // 1 + {{ 128,120,114,108,102, 96, 90, 86, 80, 76, 72, 68}}, // 2 + {{ 64, 60, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34}}, // 3 + {{ 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17}}, // 4 + {{ 16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8}}, // 5 +}; + +static char notes[12]= {'A','A','B','C','C','D','D','E','F','F','G','G'}; +static char sharps[12]={' ','#',' ',' ','#',' ','#',' ',' ','#',' ','#'}; + + +char *ed_to_note(int freq, char *out) { + + int i,j; + int note=0,octave=0; + +// printf("Freq=%d\n",freq); + + for(i=0;i<5;i++) { + if ((freq<=note_mapping[i].freq[0]) && + (freq>=note_mapping[i].freq[11])) { + octave=i+1; + break; + } + } + + for(j=0;j<12;j++) { + if (freq==note_mapping[i].freq[j]) { + note=j; + break; + } + } + if (j==12) { + sprintf(out,"%3d",freq); + } + else { + out[0]=notes[note]; + out[1]=sharps[note]; + out[2]=octave+'0'; + } + out[3]=0; + + return out; +} + diff --git a/mockingboard/notes.h b/mockingboard/notes.h new file mode 100644 index 00000000..96746afa --- /dev/null +++ b/mockingboard/notes.h @@ -0,0 +1,2 @@ +int note_to_ed(char note, int flat, int sharp, int octave); +char *ed_to_note(int freq, char *out);