onilink_ Modérateur
Messages : 9183 Localisation : Montpellier Projet Actuel : Planet Centauri
OniDev
| Sujet: Re: CBNA Rebirth Days Dim 24 Mar 2013 - 15:42 | |
| Un petit synthé audio que j'ai codé dans la matinée: http://host-a.net/u/onilink_/SynthetiseurAudio.7zTouches: QZSEDFTGYHUJKOLPM 0123456 Avec QSDFGHJK... = do ré mi fa sol la si do etc. Formes d'ondes possibles: (touches numpad) 0 = triangle 1 = sinus 2 = square 3 = square 4 = square 5 = square 6 = noise Le code est dispo dans l'archive. C'est fait avec OpenAL (il faut donc les dll pour lancer le projet). Je le met aussi ici: - Code:
-
#include <GL/GL.h> #include <window/io.h> #include <cstdio> #include <cmath> #include "tools.h"
int squareSelected = 0;
const byte SquareWave[4][16] = { {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };
const byte TriangleWave[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
const byte SinWave[] = { 0, 2, 9, 21, 37, 56, 78, 102, 127, 151, 175, 197, 216, 232, 244, 251, 254, 251, 244, 232, 216, 197, 175, 151, 126, 102, 78, 56, 37, 21, 9, 2 };
byte interpLinear(byte v1, byte v2, float x) { return (byte)(v1*(1.f-x) + v2*x); }
inline byte triangleWave(float x) { return 32 * TriangleWave[ ((int)x)%32 ]; }
inline byte squareWave(float x) { return 255 * SquareWave[squareSelected][ ((int)x)%16 ]; }
inline byte sinWave(float x) { return SinWave[ ((int)x)%32 ]; }
byte noiseWave(float freq) { static int shift = 1; static float x = 0; if(x++ >= 4410/freq) { shift = (((shift<<14)^(shift<<8))&0x4000)|(shift>>1); x = 0; } return 255 * (shift&1); }
void Tri(char* samples, int nbSamples, float freq) { static float x = 0; freq /= 1000.f; for(int i=0; i<nbSamples; i++) { samples[i] = interpLinear(triangleWave(x), triangleWave(x+1), x - (int)x); x += freq; if(x >= 32.f) x = 0.f; } }
void Sin(char* samples, int nbSamples, float freq) { static float x = 0; freq /= 1000.f; for(int i=0; i<nbSamples; i++) { samples[i] = interpLinear(sinWave(x), sinWave(x+1), x - (int)x); x += freq; if(x >= 32.f) x = 0.f; } }
void Square(char* samples, int nbSamples, float freq) { static float x = 0; freq /= 1000.f; for(int i=0; i<nbSamples; i++) { samples[i] = interpLinear(squareWave(x), squareWave(x+1), x - (int)x); x += freq; if(x >= 16.f) x = 0.f; } }
void Noise(char* samples, int nbSamples, float freq) { for(int i=0; i<nbSamples; i++) samples[i] = noiseWave(freq); }
int main() { int wid=640, hei=480; windowCreate(wid, hei); setSynchronization(false); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, wid, hei, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0, 0, 0, 0); InitOpenAL(); ALuint buffers[2], source; ALenum format = AL_FORMAT_MONO8; ALsizei frequency = 44100; alGenBuffers(2, buffers); alGenSources(1, &source); int nbSamples = 3330; char *samples = new char[nbSamples]; bool playing = false; char keys[] = "QZSEDFTGYHUJKOLPM"; // Type du signal void (*fill) (char*, int, float); fill = Tri; while(windowIsOpen()) { ioHandle(); if(keyCheck(vk_escape)) break; // Mode if(keyPressed(vk_numpad0)) fill = Tri; else if(keyPressed(vk_numpad1)) fill = Sin; else if(keyPressed(vk_numpad2)) { fill = Square; squareSelected = 0; } else if(keyPressed(vk_numpad3)) { fill = Square; squareSelected = 1; } else if(keyPressed(vk_numpad4)) { fill = Square; squareSelected = 2; } else if(keyPressed(vk_numpad5)) { fill = Square; squareSelected = 3; } else if(keyPressed(vk_numpad6)) fill = Noise; int key = -1; for(int i=0; i<(int)strlen(keys); i++) { if(keyCheck( keys[i] )) { key = i; break; } } float freq = 440; if(key != -1) { if(fill == Square) freq = 440 * powf(2, (key-10.f)/12.f - 1); else freq = 440 * powf(2, (key-10.f)/12.f); } if(mouseCheck(mb_left)) { freq = mouse_x + 440; key = -2; } if(key != -1) { if(!playing) { playing = true; fill(samples, nbSamples, freq); alBufferData(buffers[0], format, samples, nbSamples, frequency); fill(samples, nbSamples, freq); alBufferData(buffers[1], format, samples, nbSamples, frequency); alSourceQueueBuffers(source, 2, buffers); alSourcePlay(source); } else { int nbProcessed; alGetSourcei(source, AL_BUFFERS_PROCESSED, &nbProcessed); for(int i=0; i<nbProcessed; i++) { ALuint buff; alSourceUnqueueBuffers(source, 1, &buff); fill(samples, nbSamples, freq); alBufferData(buff, format, samples, nbSamples, frequency); alSourceQueueBuffers(source, 1, &buff); } } } else { if(playing) { alSourceStop(source); playing = false; ALint nbQueued; ALuint buff; alGetSourcei(source, AL_BUFFERS_QUEUED, &nbQueued);
for(int i=0; i<nbQueued; i++) alSourceUnqueueBuffers(source, 1, &buff); } } screenRefresh(); } delete[] samples; // On purge la file de tampons de la source ALint nbQueued; ALuint buff; alGetSourcei(source, AL_BUFFERS_QUEUED, &nbQueued); for(int i=0; i<nbQueued; i++) alSourceUnqueueBuffers(source, 1, &buff); alSourcei(source, AL_BUFFER, 0); // On détruit les deux tampons alDeleteBuffers(2, buffers); // On détruit la source alDeleteSources(1, &source); ShutdownOpenAL(); return 0; }
Y a quelques petits tics par contre, donc si quelqu'un arrive a les virer qu'il me dise comment il s'y est pris :b |
|