Arduino Chiptunes (8 / 8 étapes)

Étape 8: Rendre le Beatbox.

Voici le code de beatbox :

 #include #include #include #define TRACKLEN 32 #define MAXTRACK 0x92 #define SONGLEN 0x37 #include extern "C" { typedef unsigned char u8; typedef unsigned short u16; typedef char s8; typedef short s16; typedef unsigned long u32; byte songdata[] PROGMEM = { 0x34,0x80,0x0d,0xe4,0x01,0x41,0x30,0x09,0x34,0x41,0x2c,0xd0,0x05,0xc3,0x80,0x18, 0x14,0x03,0x63,0x70,0x0c,0x90,0x41,0x32,0x50,0x06,0xcb,0xe0,0x1b,0xcc,0x83,0x83, 0xb0,0x11,0x5e,0x42,0x51,0xd8,0x0a,0x6f,0x61,0x30,0x5c,0x86,0xd5,0x40,0x1c,0xbc, 0xc3,0x7d,0x80,0x10,0x02,0x08,0x06,0x40,0x90,0x60,0x00,0x06,0x08,0x06,0x80,0x90, 0x60,0x00,0x0a,0x08,0x06,0xc0,0xb0,0x60,0x00,0x0a,0x08,0x06,0xe0,0xa0,0x68,0x40, 0x02,0x08,0x86,0x43,0x90,0x60,0x00,0x06,0x08,0xc6,0x83,0x90,0x60,0x00,0x0a,0x08, 0x86,0xc3,0xb0,0x60,0x00,0x0a,0x08,0x86,0xe3,0xa0,0x68,0x40,0x09,0x02,0x08,0xa0, 0x01,0x80,0x0b,0x19,0x07,0x04,0x02,0xe8,0x00,0x09,0x00,0x08,0xff,0x0b,0x25,0x02, 0xf0,0x00,0x09,0x03,0x08,0xff,0x07,0x01,0x09,0x02,0x01,0x90,0x0b,0x31,0x05,0xa0, 0x02,0xf0,0x00,0x09,0x03,0x08,0x80,0x02,0xe0,0x00,0x09,0x03,0x08,0xff,0x07,0x01, 0x09,0x02,0x01,0x90,0x0b,0x31,0x05,0xa0,0x07,0x02,0x09,0x03,0x08,0x80,0x02,0xf0, 0x00,0x09,0x01,0x08,0x60,0x0b,0x31,0x02,0xf8,0x00,0x09,0x01,0x08,0xc0,0x0b,0x31, 0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xeb,0x04,0x80,0xa4,0x00, 0xa4,0x03,0x20,0x29,0x00,0xe9,0x00,0x48,0x0a,0x40,0x3a,0x00,0x92,0x02,0x00,0xeb, 0x04,0x80,0xa4,0x00,0xa4,0x03,0x20,0x29,0x00,0xe9,0x00,0x48,0x0a,0x40,0x3e,0x00, 0xb2,0x02,0x00,0x03,0x05,0x80,0xb0,0x00,0x04,0x04,0x20,0x2c,0x00,0x01,0x01,0x08, 0x0b,0x40,0x40,0x00,0xc2,0x02,0x00,0x03,0x05,0x80,0xb0,0x00,0x04,0x04,0x20,0x2c, 0x00,0x01,0x01,0x08,0x0b,0x40,0x44,0x00,0xe2,0x02,0x00,0x23,0x05,0x80,0xc0,0x00, 0x84,0x04,0x20,0x30,0x00,0x21,0x01,0x08,0x0c,0x40,0x48,0x00,0x02,0x03,0x00,0x23, 0x05,0x80,0xc0,0x00,0x84,0x04,0x20,0x30,0x00,0x21,0x01,0x08,0x09,0x81,0x21,0x22, 0x00,0x71,0x21,0x22,0x00,0x23,0x05,0x80,0xc0,0x00,0x84,0x04,0x20,0x30,0x00,0xd9, 0x00,0xc8,0x09,0x40,0x36,0xc8,0x06,0x39,0x21,0x27,0x00,0xab,0x09,0x80,0xc0,0x00, 0x64,0x06,0x20,0x35,0x00,0xa9,0x01,0x08,0x0c,0x40,0x66,0x00,0x52,0x03,0x00,0xab, 0x09,0x80,0xc0,0x00,0x64,0x06,0x20,0x35,0x00,0xa9,0x01,0x08,0x0e,0x40,0x6e,0x00, 0x52,0x03,0x00,0xab,0x09,0x80,0xc0,0x00,0x64,0x06,0x20,0x30,0x00,0xc1,0x01,0xc8, 0x0d,0x40,0x6a,0x00,0x32,0x03,0x00,0xab,0x09,0x80,0xc0,0x00,0x64,0x06,0x20,0x35, 0x00,0xa9,0x01,0x08,0x0c,0x40,0x66,0x00,0x02,0x03,0x00,0xcb,0x0c,0x80,0x95,0x08, 0x29,0x61,0x99,0x02,0xb0,0x12,0x01,0x58,0x66,0xb0,0x12,0x21,0x25,0x00,0xcb,0x14, 0x80,0x95,0x08,0x00,0xcb,0x0c,0x80,0x95,0x08,0x29,0x61,0x99,0x02,0xb0,0x12,0x01, 0x58,0x66,0x90,0x0c,0x80,0x64,0xb0,0x4c,0x21,0x19,0x2c,0x33,0x00,0x00,0x83,0x1d, 0x80,0xc1,0x0c,0x4b,0x1d,0x80,0x9c,0x90,0x14,0x76,0x32,0x0c,0x76,0x00,0x06,0x33, 0x2c,0x75,0x00,0x96,0x32,0x00,0x00,0x63,0x1d,0x80,0xb1,0x0c,0x73,0x1d,0x80,0xc4, 0x10,0x18,0x76,0x32,0x8c,0x75,0x00,0x06,0x33,0xcc,0x75,0x00,0xe6,0x32,0x00,0x00, 0x00,0x00,0x00,0x00,0x30,0xd8,0x01,0x88,0x0b,0x40,0x58,0x00,0x72,0x42,0x52,0x58, 0xca,0x00, }; volatile u8 callbackwait; volatile u8 lastsample; volatile u8 timetoplay; volatile u8 test; volatile u8 testwait; u8 trackwait; u8 trackpos; u8 playsong; u8 songpos; u32 noiseseed = 1; u8 light[2]; /*const u16 freqtable[] = { 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165, 0x017a, 0x0191, 0x01a9, 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259, 0x027d, 0x02a3, 0x02cb, 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3, 0x042f, 0x046f, 0x04b2, 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5, 0x070a, 0x0775, 0x07e6, 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c, 0x0bd6, 0x0c8b, 0x0d4a, 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb, 0x13e9, 0x1518, 0x1659, 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b, 0x217c, 0x237a, 0x2596, 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528, 0x3851, 0x3bab, 0x3f37, 0x42f9, 0x46f5, 0x4b2d, 0x4fa6, 0x5462, 0x5967, 0x5eb7, 0x6459, 0x6a51, 0x70a3, 0x7756, 0x7e6f };*/ const u16 freqtable[] = { 0x0085, 0x008d, 0x0096, 0x009f, 0x00a8, 0x00b2, 0x00bd, 0x00c8, 0x00d4, 0x00e1, 0x00ee, 0x00fc, 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165, 0x017a, 0x0191, 0x01a9, 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259, 0x027d, 0x02a3, 0x02cb, 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3, 0x042f, 0x046f, 0x04b2, 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5, 0x070a, 0x0775, 0x07e6, 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c, 0x0bd6, 0x0c8b, 0x0d4a, 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb, 0x13e9, 0x1518, 0x1659, 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b, 0x217c, 0x237a, 0x2596, 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528, 0x3851, 0x3bab, 0x3f37 }; const s8 sinetable[] = { 0, 12, 25, 37, 49, 60, 71, 81, 90, 98, 106, 112, 117, 122, 125, 126, 127, 126, 125, 122, 117, 112, 106, 98, 90, 81, 71, 60, 49, 37, 25, 12, 0, -12, -25, -37, -49, -60, -71, -81, -90, -98, -106, -112, -117, -122, -125, -126, -127, -126, -125, -122, -117, -112, -106, -98, -90, -81, -71, -60, -49, -37, -25, -12 }; const u8 validcmds[] = "0dfijlmtvw~+="; enum { WF_TRI, WF_SAW, WF_PUL, WF_NOI }; volatile struct oscillator { u16 freq; u16 phase; u16 duty; u8 waveform; u8 volume; // 0-255 } osc[4]; struct trackline { u8 note; u8 instr; u8 cmd[2]; u8 param[2]; }; struct track { struct trackline line[TRACKLEN]; }; struct unpacker { u16 nextbyte; u8 buffer; u8 bits; }; struct channel { struct unpacker trackup; u8 tnum; s8 transp; u8 tnote; u8 lastinstr; u8 inum; u16 iptr; u8 iwait; u8 inote; s8 bendd; s16 bend; s8 volumed; s16 dutyd; u8 vdepth; u8 vrate; u8 vpos; s16 inertia; u16 slur; } channel[4]; u16 resources[16 + MAXTRACK]; struct unpacker songup; byte readsongbyte(u16 offset) { return pgm_read_byte_near(&songdata[0] + offset); } void watchdogoff() { } void initup(struct unpacker *up, u16 offset) { up->nextbyte = offset; up->bits = 0; } u8 readbit(struct unpacker *up) { u8 val; if(!up->bits) { up->buffer = readsongbyte(up->nextbyte++); up->bits = 8; } up->bits--; val = up->buffer & 1; up->buffer >>= 1; return val; } u16 readchunk(struct unpacker *up, u8 n) { u16 val = 0; u8 i; for(i = 0; i < n; i++) { if(readbit(up)) { val |= (1 << i); } } return val; } void readinstr(byte num, byte pos, byte *dest) { dest[0] = readsongbyte(resources[num] + 2 * pos + 0); dest[1] = readsongbyte(resources[num] + 2 * pos + 1); } void runcmd(u8 ch, u8 cmd, u8 param) { switch(validcmds[cmd]) { case '0': channel[ch].inum = 0; break; case 'd': osc[ch].duty = param << 8; break; case 'f': channel[ch].volumed = param; break; case 'i': channel[ch].inertia = param << 1; break; case 'j': channel[ch].iptr = param; break; case 'l': channel[ch].bendd = param; break; case 'm': channel[ch].dutyd = param << 6; break; case 't': channel[ch].iwait = param; break; case 'v': osc[ch].volume = param; break; case 'w': osc[ch].waveform = param; break; case '+': channel[ch].inote = param + channel[ch].tnote - 12 * 4; break; case '=': channel[ch].inote = param; break; case '~': if(channel[ch].vdepth != (param >> 4)) { channel[ch].vpos = 0; } channel[ch].vdepth = param >> 4; channel[ch].vrate = param & 15; break; } } void initresources() { u8 i; struct unpacker up; initup(&up, 0); for(i = 0; i < 16 + MAXTRACK; i++) { resources[i] = readchunk(&up, 13); } initup(&songup, resources[0]); } void playroutine() { // called at 50 Hz u8 ch; u8 lights; if(playsong) { if(trackwait) { trackwait--; } else { trackwait = 4; if(!trackpos) { if(playsong) { if(songpos >= SONGLEN) { //playsong = 0; songpos=0; trackpos=0; initresources(); } else { for(ch = 0; ch < 4; ch++) { u8 gottransp; u8 transp; gottransp = readchunk(&songup, 1); channel[ch].tnum = readchunk(&songup, 6); if(gottransp) { transp = readchunk(&songup, 4); if(transp & 0x8) transp |= 0xf0; } else { transp = 0; } channel[ch].transp = (s8) transp; if(channel[ch].tnum) { initup(&channel[ch].trackup, resources[16 + channel[ch].tnum - 1]); } } songpos++; } } } if(playsong) { for(ch = 0; ch < 4; ch++) { if(channel[ch].tnum) { u8 note, instr, cmd, param; u8 fields; fields = readchunk(&channel[ch].trackup, 3); note = 0; instr = 0; cmd = 0; param = 0; if(fields & 1) note = readchunk(&channel[ch].trackup, 7); if(fields & 2) instr = readchunk(&channel[ch].trackup, 4); if(fields & 4) { cmd = readchunk(&channel[ch].trackup, 4); param = readchunk(&channel[ch].trackup, 8); } if(note) { channel[ch].tnote = note + channel[ch].transp; if(!instr) instr = channel[ch].lastinstr; } if(instr) { if(instr == 2) light[1] = 5; if(instr == 1) { light[0] = 5; if(channel[ch].tnum == 4) { light[0] = light[1] = 3; } } if(instr == 7) { light[0] = light[1] = 30; } channel[ch].lastinstr = instr; channel[ch].inum = instr; channel[ch].iptr = 0; channel[ch].iwait = 0; channel[ch].bend = 0; channel[ch].bendd = 0; channel[ch].volumed = 0; channel[ch].dutyd = 0; channel[ch].vdepth = 0; } if(cmd) runcmd(ch, cmd, param); } } trackpos++; trackpos &= 31; } } } for(ch = 0; ch < 4; ch++) { s16 vol; u16 duty; u16 slur; while(channel[ch].inum && !channel[ch].iwait) { u8 il[2]; readinstr(channel[ch].inum, channel[ch].iptr, il); channel[ch].iptr++; runcmd(ch, il[0], il[1]); } if(channel[ch].iwait) channel[ch].iwait--; if(channel[ch].inertia) { s16 diff; slur = channel[ch].slur; diff = freqtable[channel[ch].inote] - slur; //diff >>= channel[ch].inertia; if(diff > 0) { if(diff > channel[ch].inertia) diff = channel[ch].inertia; } else if(diff < 0) { if(diff < -channel[ch].inertia) diff = -channel[ch].inertia; } slur += diff; channel[ch].slur = slur; } else { slur = freqtable[channel[ch].inote]; } osc[ch].freq = slur + channel[ch].bend + ((channel[ch].vdepth * sinetable[channel[ch].vpos & 63]) >> 2); channel[ch].bend += channel[ch].bendd; vol = osc[ch].volume + channel[ch].volumed; if(vol < 0) vol = 0; if(vol > 255) vol = 255; osc[ch].volume = vol; duty = osc[ch].duty + channel[ch].dutyd; if(duty > 0xe000) duty = 0x2000; if(duty < 0x2000) duty = 0xe000; osc[ch].duty = duty; channel[ch].vpos += channel[ch].vrate; } lights = 0; if(light[0]) { light[0]--; lights |= 0x04; } if(light[1]) { light[1]--; lights |= 0x10; } PORTB = lights; } int main() { asm("cli"); watchdogoff(); CLKPR = 0x80; CLKPR = 0x80; DDRC = 0x12; DDRD = 0xff; //PORTC = 0; pinMode(10,OUTPUT); pinMode(12,OUTPUT); timetoplay = 0; trackwait = 0; trackpos = 0; playsong = 1; songpos = 0; osc[0].volume = 0; channel[0].inum = 0; osc[1].volume = 0; channel[1].inum = 0; osc[2].volume = 0; channel[2].inum = 0; osc[3].volume = 0; channel[3].inum = 0; initresources(); TCCR0A = 0x02; TCCR0B = 0x02; // clkIO/8, so 1/8 MHz OCR0A = 125;//125; // 8 KHz TCCR2A=0b10100011; TCCR2B=0b00000001; TIMSK0 = 0x02; asm("sei"); for(;;) { while(!timetoplay); timetoplay--; playroutine(); } } ISR(TIMER0_COMPA_vect) // called at 8 KHz { u8 i; s16 acc; u8 newbit; OCR2B = lastsample; newbit = 0; if(noiseseed & 0x80000000L) newbit ^= 1; if(noiseseed & 0x01000000L) newbit ^= 1; if(noiseseed & 0x00000040L) newbit ^= 1; if(noiseseed & 0x00000200L) newbit ^= 1; noiseseed = (noiseseed << 1) | newbit; if(callbackwait) { callbackwait--; } else { timetoplay++; callbackwait = 180 - 1; } acc = 0; for(i = 0; i < 4; i++) { s8 value; // [-32,31] switch(osc[i].waveform) { case WF_TRI: if(osc[i].phase < 0x8000) { value = -32 + (osc[i].phase >> 9); } else { value = 31 - ((osc[i].phase - 0x8000) >> 9); } break; case WF_SAW: value = -32 + (osc[i].phase >> 10); break; case WF_PUL: value = (osc[i].phase > osc[i].duty)? -32 : 31; break; case WF_NOI: value = (noiseseed & 63) - 32; break; default: value = 0; break; } osc[i].phase += osc[i].freq; acc += value * osc[i].volume; // rhs = [-8160,7905] } // acc [-32640,31620] lastsample = 128 + (acc >> 8); // [1,251] } } 

Articles Liés

Arduino Chiptunes-encore une fois... Installer une librairie Arduino

Arduino Chiptunes-encore une fois... Installer une librairie Arduino

j'aime chiptunes et j'ai donc dû avoir plus. Si vous avez lu mon projet Chiptunes, vous saurez ce que je veux dire.Merci à Drew Crawford d'une hauteur impressionnante.Je vais aussi vous apprendre à installer un Code de bibliothèque d'Arduino.Ici :Éta
Arduino Chiptune Song

Arduino Chiptune Song

ce tutoriel est de vous renseigner sur les transistors, diodes flyback et fonctions de base Arduino. Ce Instructable est basé sur un circuit de la trousse d'expérimentation Arduino.Il s'agit d'un bon tutoriel pour ceux qui débutent avec Arduino. Ces
Le Guide ultime pour créer des Chiptunes sur la GameBoy !

Le Guide ultime pour créer des Chiptunes sur la GameBoy !

Nouveaux sur la scène de « Chiptune » Gameboy ?  Ou peut-être votre tente toujours d'aller au fond de ce que toute cette affaire de Chiptune ?  Quelle que soit votre situation, à la fin de ce Instructable, je peux vous promettre, vous serez un pro !R
Arduino, capteurs et MIDI

Arduino, capteurs et MIDI

Maintenant que vous êtes au courant sur l'utilisation des intrants et des extrants de l'Arduino, ce Instructable vous donnera tout ce dont vous avez besoin pour commencer à utiliser des capteurs pour déclencher des notes MIDI d'Arduino. Ce poste est
Arduino GRANDE le microcontrôleur énorme

Arduino GRANDE le microcontrôleur énorme

Nous aimons Arduino ! Mais les planches sont si minuscules qu'ils peuvent être difficiles à câliner. Et pas si facile à voir, non plus, si vous êtes un étudiant assis à l'arrière d'une salle de classe. Alors pourquoi ne pas résoudre les deux problème
Le bouclier de DoAnything Arduino

Le bouclier de DoAnything Arduino

The Arduino DoAnything Shield est un bouclier qui vous sauve vraiment rien d'autre qu'un tas de coupe. Après que j'avais fait mon projet Chiptunes sur l'Arduino, j'ai eu l'envie de faire un bouclier afin qu'il n'y aurait pas de fils lâches et shorts
Poisson Feeder Arduino Raspberry Pi lien

Poisson Feeder Arduino Raspberry Pi lien

« Quel une ennuyeuse boîte noire »Oui, c'est, mais :– Il nourrit de mon poisson quand je ne suis pas là.– Il se nourrit en un temps prédéfini.– Il détecte la nourriture donnée aux poissons– Vous pouvez vous connecter à distance dans le pi framboise p
DIY - Comment utiliser l’Arduino Uno pour envoyer un Email, de SMS et de faire une voix appeler

DIY - Comment utiliser l’Arduino Uno pour envoyer un Email, de SMS et de faire une voix appeler

Vous vous demandez comment faire pour envoyer des e-mails via votre Arduino Uno ? Ne vous inquiétez pas... Ce tutoriel vidéo vous éclairera sur le processus étape par étape pour envoyer des emails, messages SMS ainsi que faire des voix appeler à l'ai
Arduino IR Automarion maison

Arduino IR Automarion maison

Télécommande IR est qu'un Controller est une manette sans fil en quelques électronique tels que TV, lecteur DVD et autres appareils ménagers.Télécommande IR envoyer des impulsions codées numériquement du rayonnement infrarouge pour contrôler les fonc
Arduino & Neopixel Coke bouteille Party Light

Arduino & Neopixel Coke bouteille Party Light

Donc mes taches de Doon fils une lumière très cool partie faite de vieilles bouteilles de coke et les entrailles gluants de Glow Sticks et demande si nous pouvons faire un pour sa PartAYYY d'Examens scolaires sont plus Blowout à venir!!! Je dis bien
Ventilateur à commande thermostatique Arduino

Ventilateur à commande thermostatique Arduino

J'ai et quelques membres du groupe avons décidé que, pour l'été, il serait utile de créer un ventilateur qui s'allume à 70 degrés Fahrenheit et continue d'augmenter en intensité avec la chaleur. Voilà donc ce que nous faisions. :)Étape 1: engrenages
Flux des Mi - distributeur de nourriture chien Arduino

Flux des Mi - distributeur de nourriture chien Arduino

Pour un récent projet de l'Université, on nous a donné le défi de faire un distributeur de nourriture automatique chien entièrement fonctionnel à l'aide d'un Arduino. Voici la pièce finie et tous les fichiers appropriés et les instructions que vous p
Chargeur automatique de nourriture de poisson à l’aide d’Arduino Uno

Chargeur automatique de nourriture de poisson à l’aide d’Arduino Uno

Dans cette Instructables, je vais vous montrer comment construire un Chargeur automatique de nourriture des poissons. Si vous n'avez pas n'oubliez pas de nourrir vos poissons tous les jours car votre Arduino le fera pour vous. Vous pouvez également d
Connectez votre Pi framboise et Arduino Uno !

Connectez votre Pi framboise et Arduino Uno !

Le Raspberry Pi et Arduino Uno sont des appareils très puissants, bien à différentes choses. Les cartes Arduino sont impressionnantes en lecture des entrées et sorties de diverses choses différentes. Le Raspberry Pi est en fait un mini, un ordinateur