From robert.fung@citicorp.com Sun Jun 25 15:04:43 1995 Path: lyra.csx.cam.ac.uk!sunsite.doc.ic.ac.uk!agate!newsxfer.itd.umich.edu!gatech!news.mathworks.com!solaris.cc.vt.edu!spcuna!citicorp.com!maple.cgin.us-md.citicorp.com!rfung From: robert.fung@citicorp.com (Robert Fung) Newsgroups: comp.speech Subject: Whistle Recognition Date: 25 Jun 1995 11:52:58 GMT Organization: Citicorp - CGIN Lines: 498 Message-ID: <3sjimq$h84@spruce.citicorp.com> NNTP-Posting-Host: maple.cgin.us-md.citicorp.com X-Newsreader: TIN [version 1.2 PL2] This program recognizes whistled notes and replays them on a sound blaster card. Whith some enhancement disabled/handicapped people might be able to use it to compose music and replay the notes as MIDI using sound fonts etc. The program was written while trying to recognize vowel formants. /* Whistle.c by Robert Fung 1995-06 This demo hears a note you whistle into a mike and then plays it back on the Sound Blaster using the FM synthsizer. Range 100-3000 hz in 100Hz steps 8 bit DAC 8000Hz sample rate 128 sample FT default: IOport=0x220, IRQ=7, LDMA=1, HDMA=7, Cardtype=1; used with SB16 and Compaq 386/25 & 387 Turbo C 2.0 Use earphones to reduce feedback; check your volume first! */ /* Robert Fung 70650.134@compuserve.com This program was written using code in the public domain. The author/s will not be responsible for any use made of it. Be sure your BLASTER environment settings match the settings in the code before using! */ /* Sound Blaster record code by Lars Otte Ringstr.2 37154 Northeim Germany Email-address: drcaos@fhlip.EE.fh-lippe.de */ /* FM Sound Blaster code modified by R.F. from: freqgen.c Frequency Generator Creative Labs Inc (c) 1994 by Mike Cox */ /* make sure the MIDI volume is up and on */ /* set IOPORT, IRQ, LDMA, HDMA, CardType below to your settings */ #include #include #include #include #include #include #include #define TWO_PI ((double)2.0 * M_PI) int samples; int Buffer[1024]; double real[129],imag[129]; void dspwrite ( unsigned char ); unsigned char dspread ( void ); unsigned char far *data; unsigned char far *aligned; unsigned char aligned_physical; float f[60]; /*-----------------------------------------------------------------------*/ void dspwrite ( unsigned char c ) { while(inportb(0x022C)&0x80); outportb(0x022C,c); } void sbinit ( void ) { unsigned short x; inportb(0x022E); outportb(0x0226,0x01); inportb(0x0226); inportb(0x0226); inportb(0x0226); inportb(0x0226); outportb(0x0226,0x00); for(x=0;x<100;x++) { if(inportb(0x022E)&0x80) { if(inportb(0x022A)==0xAA) break; } } if(x==100) { printf("Sound Blaster not found at 0220h\n"); exit(1); } } /*------------------------------------------------------------------*/ void sbmalloc ( void ) { unsigned long physical; data=farmalloc(80000L); if(data==NULL) { printf("Memory Allocation Error\n"); exit(1); } physical=((unsigned long)FP_OFF(data))+ (((unsigned long)FP_SEG(data))<<4); physical+=0x0FFFFL; physical&=0xF0000L; aligned_physical=(physical>>16)&15; aligned=MK_FP(((unsigned short)aligned_physical<<12)&0xF000,0); } void sbsettc ( unsigned char tc ) /* tc = time constant = 256L - (1000000UL/samples per second)*/ { inportb(0x022E); dspwrite(0x40); dspwrite(tc); } void sbrec ( unsigned short len ) /* len = number of bytes to record to unsigned char *aligned (<=65000) */ { len--; outportb(0x0A,0x05); outportb(0x0C,0x00); outportb(0x0B,0x45); outportb(0x02,0); outportb(0x02,0); outportb(0x83,aligned_physical); outportb(0x03,(unsigned char)(len&0xFF)); outportb(0x03,(unsigned char)((len>>8)&0xFF)); outportb(0x0A,0x01); dspwrite(0x24); dspwrite((unsigned char)(len&0xFF)); dspwrite((unsigned char)((len>>8)&0xFF)); } unsigned short dmacount ( void ) { unsigned short x; x=inportb(0x03); x|=inportb(0x03)<<8; if(x==0xFFFF) inportb(0x022E); return(x); } /*-------------------------------------------------------------*/ double fft2(double hz) /* SFT */ { double creal,cimag,g; int x; creal=0; cimag=0; for (x=0;x17500) freq=17500; fn = (long) ((double)freq * (double)1048576 / (1< 1023) { block++; if (block>7) { block=7; m*=2; if (m>15) m=15; } fn = (long) ((double)freq * (double)1048576 / (1<> 8) & 0x3) /* Set octave and upper two*/ + (block << 2) | KEYON); /* bits of frequency*/ } void StopSound(int channel) { int reg=RegBase[channel], oldval; /* We want to retrieve*/ outp( IOport+FM, reg ); /* previous value and just*/ mydelay(8); /* change the KEYON bit*/ oldval = inp( IOport+FM ); /* (bit 5) to avoid a*/ mydelay(55); /* clinking sound when we*/ fm(0xB0+channel, (oldval & 0xDF) ); /* turn the channel off*/ } void CardInit(void) /* Initialize card settings*/ { int i,reg; lfreq = rfreq = 0; /* Set starting freq's to 0*/ block = 4; /* Set starting octave to 4*/ m = 1; /* Set starting multiplier num to 1*/ fm(1, 0); /* Initialize card*/ if ((Cardtype == 4) || (Cardtype == 6)) { Profm2(5, 1); /* Set to OPL3 mode*/ fm(0xC0, LEFT | RIGHT | 1); /* Set left channel parallel connection*/ fm(0xC1, LEFT | RIGHT | 1); /* Set right channel*/ STEREO = 1; /* Set to stereo*/ } else fm(0xC0, 1); /* parallel connection*/ if (Cardtype == 2) STEREO = 1; fm(8, 0); /* Set up FM mode*/ fm(0xbd, 0); /* Set up FM mode*/ for (i=0,reg=RegBase[i]; i<9; i++,reg=RegBase[i]) { fm(reg+0x43, 0x0); /* Max out carrier volume*/ fm(reg+0x63, 0xff); /* Set carrier attack & decay*/ fm(reg+0x83, 0x05); /* Set carrier sustain & release*/ fm(reg+0x40, 0x3f); /* Set modulator volume level*/ fm(reg+0x60, 0x44); /* Set modulator attack & decay*/ fm(reg+0x80, 0x05); /* Set modulator sustain & release*/ } } void mydelay(unsigned long clocks) { unsigned long elapsed=0; unsigned int last, next, ncopy, diff; outp(0x43, 0); last=inp(0x40); last=~((inp(0x40)<<8) + last); do { outp(0x43, 0); next=inp(0x40); ncopy=next=~((inp(0x40)<<8) + next); next-=last; elapsed+=next; last=ncopy; } while (elapsed f[max]) max=i; } printf("%d\n",100*max); note(max*100,0); /* play the note heard on one channel */ while(dmacount()!=0xFFFF); if(!kbhit()) goto nochmal; } void main() { long ra=8000, ca; /*samplerate=8kHz fg=4kHz*/ clrscr(); sbinit(); sbmalloc(); ca= 256L - ( 1000000L / ra); sbsettc(ca); puts("Whistle notes into your mic."); puts("if the frequency matches one of"); puts("the recognized notes it will replay the note"); cool(); getch(); } /* Piano scale as frequencies A3 26.667 B3 30 C3 32 D3 36 E3 40 F3 42.667 G3 48 A2 53.333 B2 60 C2 64 D2 72 E2 80 F2 85.333 G2 96 A1 106.667 B1 120 C1 128 D1 144 E1 160 F1 170.667 G1 192 A0 213.333 B0 240 C0 256 D0 288 E0 320 F0 341.333 G0 384 A3 426.667 B3 480 C3 512 D3 576 E3 640 F3 682.667 G3 768 A4 853.333 B4 960 C4 1024 D4 1152 E4 1280 F4 1365.333 G4 1536 A5 170.667 B5 1920 C5 2048 D5 2304 E5 2560 F5 2730.667 G5 3072 A6 3413.333 B6 3840 C6 4096 D6 4608 E6 5120 F6 5461.333 G6 6144 A7 6826.667 B7 7680 C7 8192 */