Bonjour à tous,
je me suis récemment mis aux micro-contrôleurs par le biais de l’Arduino Uno, et j’ai commencé à faire ce que je souhaitais depuis longtemps: synthétiser de l’audio en temps réel (formes d’ondes diverses, sons de percussions,effets de modulation …). Mes premiers pas sont engageants et j’aimerai aller plus loin.
Nous sommes d’accord que l’Arduino Uno est un peu léger pour synthétiser de l’audio stable mais ça m’a déjà permis de me frotter à certains concepts.
Le code que j’utilise comme coeur de mes projets est le suivant, il n’est pas de moi mais c’est à partir de cette base que j’ai fait évoluer mes premieres expériences. Ce code fait principalement appel à des interruptions, la sortie audio est assurée par PWM.
Même si l’Arduino Uno propose des outils avec sa library d’interruptions (AVR/INTERRUPT.H), je serai bien incapable d’écrire tout ce qui concerne l’ISR par moi-même.Code:#include <avr/interrupt.h> // Use timer interrupt library /******** Sine wave parameters ********/ #define PI2 6.283185 // 2*PI saves calculation later #define AMP 127 // Scaling factor for sine wave #define OFFSET 128 // Offset shifts wave to all >0 values /******** Lookup table ********/ #define LENGTH 256 // Length of the wave lookup table byte wave[LENGTH]; // Storage for waveform void setup() { /* Populate the waveform table with a sine wave */ for (int i=0; i<LENGTH; i++) { // Step across wave table ** float v = (AMP*sin((PI2/LENGTH)*i)); // Compute value ** wave[i] = int(v+OFFSET); // Store value as integer *} /****Set timer1 for 8-bit fast PWM output ****/ *pinMode(9, OUTPUT); // Make timer’s PWM pin an output *TCCR1B = (1 << CS10); // Set prescaler to full 16MHz *TCCR1A |= (1 << COM1A1); // Pin low when TCNT1=OCR1A *TCCR1A |= (1 << WGM10); // Use 8-bit fast PWM mode *TCCR1B |= (1 << WGM12); /******** Set up timer2 to call ISR ********/ *TCCR2A = 0; // No options in control register A *TCCR2B = (1 << CS21); // Set prescaler to divide by 8 *TIMSK2 = (1 << OCIE2A); // Call ISR when TCNT2 = OCRA2 *OCR2A = 32; // Set frequency of generated wave *sei(); // Enable interrupts to generate waveform! } void loop() { // Nothing to do! } /******** Called every time TCNT2 = OCR2A ********/ ISR(TIMER2_COMPA_vect) { // Called when TCNT2 == OCR2A *static byte index=0; // Points to each table entry *OCR1AL = wave[index++]; // Update the PWM output *asm(“NOP;NOP”); // Fine tuning *TCNT2 = 6; // Timing to compensate for ISR run time }
Au final j’aimerai savoir quelles sont les approches utilisées dans les µc pour fabriquer de l’audio en temps réel.
Il me semble avoir compris qu’on pouvait le faire de 3 façons différentes:
- en direct (en prenant soin de préserver le timing des opérations). Mais la stabilité du signal n’est pas du tout assuré.
- à l’aide d’interruptions (comme dans l’exemple présenté ci-dessus)
- avec un buffer en sortie ( mais je ne sais pas si ce buffer doit être intégré à l’ µc ou pas)
Bref tout cela est très flou pour le moment et j’aimerai avoir un vision un peu globale des outils que je dois utiliser et des possibilités d’approche.
Enfin je pense passer à des µc plus puissants, l’Arduino Zero (ATSAMD21Gm3 /32 bits/48MHz/DAC 10bits) me semble pas mal mais cela sera t’il suffisant pour faire ce que je veux?
Comme il ne semble pas exister de libray d’interruptions pour la Zero je crains de ne pouvoir synthétiser de l’audio aussi simplement que je le souhaite.
Si cette carte ne fait pas l’affaire vers quel type d’µc me diriger?
Merci de vos réponses pour éclairer mon obscurité.
-----