|
用Arduino做的效果器~可以自己Remix啦~
[复制链接]
参考国外大神制作的一个效果器,可以发出各种奇葩的声音,板子用的是Arduino Uno。通过调节5个4.7K的电位器合成各种不同的声音,当然,也可以通过修改程序发出不同的声音~
程序使用的是一种声音合成算法,这个算法是产生一些短到刚好能分辨的声音小片段(声音粒子grain),然后对它们组合重排处理,在输入多变的参数时,可以形成丰满丰富的连续声音。好吧,其实这个程序我也看得一知半解的。。。囧rz
这是国外大神制作的合成器的项目主页:https://code.google.com/p/tinkerit/wiki/Auduino
代码如下:- // Auduino, the Lo-Fi granular synthesiser
- //
- // by Peter Knight, Tinker.it [url]http://tinker.it[/url]
- //
- // Help: [url]http://code.google.com/p/tinkerit/wiki/Auduino[/url]
- // More help: [url]http://groups.google.com/group/auduino[/url]
- //
- // Analog in 0: Grain 1 pitch
- // Analog in 1: Grain 2 decay
- // Analog in 2: Grain 1 decay
- // Analog in 3: Grain 2 pitch
- // Analog in 4: Grain repetition frequency
- //
- // Digital 3: Audio out (Digital 11 on ATmega8)
- //
- // Changelog:
- // 19 Nov 2008: Added support for ATmega8 boards
- // 21 Mar 2009: Added support for ATmega328 boards
- // 7 Apr 2009: Fixed interrupt vector for ATmega328 boards
- // 8 Apr 2009: Added support for ATmega1280 boards (Arduino Mega)
-
- #include <avr/io.h>
- #include <avr/interrupt.h>
-
- uint16_t syncPhaseAcc;
- uint16_t syncPhaseInc;
- uint16_t grainPhaseAcc;
- uint16_t grainPhaseInc;
- uint16_t grainAmp;
- uint8_t grainDecay;
- uint16_t grain2PhaseAcc;
- uint16_t grain2PhaseInc;
- uint16_t grain2Amp;
- uint8_t grain2Decay;
-
- // Map Analogue channels
- #define SYNC_CONTROL (4)
- #define GRAIN_FREQ_CONTROL (0)
- #define GRAIN_DECAY_CONTROL (2)
- #define GRAIN2_FREQ_CONTROL (3)
- #define GRAIN2_DECAY_CONTROL (1)
-
-
- // Changing these will also requires rewriting audioOn()
-
- #if defined(__AVR_ATmega8__)
- //
- // On old ATmega8 boards.
- // Output is on pin 11
- //
- #define LED_PIN 13
- #define LED_PORT PORTB
- #define LED_BIT 5
- #define PWM_PIN 11
- #define PWM_VALUE OCR2
- #define PWM_INTERRUPT TIMER2_OVF_vect
- #elif defined(__AVR_ATmega1280__)
- //
- // On the Arduino Mega
- // Output is on pin 3
- //
- #define LED_PIN 13
- #define LED_PORT PORTB
- #define LED_BIT 7
- #define PWM_PIN 3
- #define PWM_VALUE OCR3C
- #define PWM_INTERRUPT TIMER3_OVF_vect
- #else
- //
- // For modern ATmega168 and ATmega328 boards
- // Output is on pin 3
- //
- #define PWM_PIN 3
- #define PWM_VALUE OCR2B
- #define LED_PIN 13
- #define LED_PORT PORTB
- #define LED_BIT 5
- #define PWM_INTERRUPT TIMER2_OVF_vect
- #endif
-
- // Smooth logarithmic mapping
- //
- uint16_t antilogTable[] = {
- 64830,64132,63441,62757,62081,61413,60751,60097,59449,58809,58176,57549,56929,56316,55709,55109,
- 54515,53928,53347,52773,52204,51642,51085,50535,49991,49452,48920,48393,47871,47356,46846,46341,
- 45842,45348,44859,44376,43898,43425,42958,42495,42037,41584,41136,40693,40255,39821,39392,38968,
- 38548,38133,37722,37316,36914,36516,36123,35734,35349,34968,34591,34219,33850,33486,33125,32768
- };
- uint16_t mapPhaseInc(uint16_t input) {
- return (antilogTable[input & 0x3f]) >> (input >> 6);
- }
-
- // Stepped chromatic mapping
- //
- uint16_t midiTable[] = {
- 17,18,19,20,22,23,24,26,27,29,31,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,
- 77,82,86,92,97,103,109,115,122,129,137,145,154,163,173,183,194,206,218,231,
- 244,259,274,291,308,326,346,366,388,411,435,461,489,518,549,581,616,652,691,
- 732,776,822,871,923,978,1036,1097,1163,1232,1305,1383,1465,1552,1644,1742,
- 1845,1955,2071,2195,2325,2463,2610,2765,2930,3104,3288,3484,3691,3910,4143,
- 4389,4650,4927,5220,5530,5859,6207,6577,6968,7382,7821,8286,8779,9301,9854,
- 10440,11060,11718,12415,13153,13935,14764,15642,16572,17557,18601,19708,20879,
- 22121,23436,24830,26306
- };
- uint16_t mapMidi(uint16_t input) {
- return (midiTable[(1023-input) >> 3]);
- }
-
- // Stepped Pentatonic mapping
- //
- uint16_t pentatonicTable[54] = {
- 0,19,22,26,29,32,38,43,51,58,65,77,86,103,115,129,154,173,206,231,259,308,346,
- 411,461,518,616,691,822,923,1036,1232,1383,1644,1845,2071,2463,2765,3288,
- 3691,4143,4927,5530,6577,7382,8286,9854,11060,13153,14764,16572,19708,22121,26306
- };
-
- uint16_t mapPentatonic(uint16_t input) {
- uint8_t value = (1023-input) / (1024/53);
- return (pentatonicTable[value]);
- }
-
-
- void audioOn() {
- #if defined(__AVR_ATmega8__)
- // ATmega8 has different registers
- TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
- TIMSK = _BV(TOIE2);
- #elif defined(__AVR_ATmega1280__)
- TCCR3A = _BV(COM3C1) | _BV(WGM30);
- TCCR3B = _BV(CS30);
- TIMSK3 = _BV(TOIE3);
- #else
- // Set up PWM to 31.25kHz, phase accurate
- TCCR2A = _BV(COM2B1) | _BV(WGM20);
- TCCR2B = _BV(CS20);
- TIMSK2 = _BV(TOIE2);
- #endif
- }
-
-
- void setup() {
- pinMode(PWM_PIN,OUTPUT);
- audioOn();
- pinMode(LED_PIN,OUTPUT);
- }
-
- void loop() {
- // The loop is pretty simple - it just updates the parameters for the oscillators.
- //
- // Avoid using any functions that make extensive use of interrupts, or turn interrupts off.
- // They will cause clicks and poops in the audio.
-
- // Smooth frequency mapping
- //syncPhaseInc = mapPhaseInc(analogRead(SYNC_CONTROL)) / 4;
-
- // Stepped mapping to MIDI notes: C, Db, D, Eb, E, F...
- //syncPhaseInc = mapMidi(analogRead(SYNC_CONTROL));
-
- // Stepped pentatonic mapping: D, E, G, A, B
- syncPhaseInc = mapPentatonic(analogRead(SYNC_CONTROL));
-
- grainPhaseInc = mapPhaseInc(analogRead(GRAIN_FREQ_CONTROL)) / 2;
- grainDecay = analogRead(GRAIN_DECAY_CONTROL) / 8;
- grain2PhaseInc = mapPhaseInc(analogRead(GRAIN2_FREQ_CONTROL)) / 2;
- grain2Decay = analogRead(GRAIN2_DECAY_CONTROL) / 4;
- }
-
- SIGNAL(PWM_INTERRUPT)
- {
- uint8_t value;
- uint16_t output;
-
- syncPhaseAcc += syncPhaseInc;
- if (syncPhaseAcc < syncPhaseInc) {
- // Time to start the next grain
- grainPhaseAcc = 0;
- grainAmp = 0x7fff;
- grain2PhaseAcc = 0;
- grain2Amp = 0x7fff;
- LED_PORT ^= 1 << LED_BIT; // Faster than using digitalWrite
- }
-
- // Increment the phase of the grain oscillators
- grainPhaseAcc += grainPhaseInc;
- grain2PhaseAcc += grain2PhaseInc;
-
- // Convert phase into a triangle wave
- value = (grainPhaseAcc >> 7) & 0xff;
- if (grainPhaseAcc & 0x8000) value = ~value;
- // Multiply by current grain amplitude to get sample
- output = value * (grainAmp >> 8);
-
- // Repeat for second grain
- value = (grain2PhaseAcc >> 7) & 0xff;
- if (grain2PhaseAcc & 0x8000) value = ~value;
- output += value * (grain2Amp >> 8);
-
- // Make the grain amplitudes decay by a factor every sample (exponential decay)
- grainAmp -= (grainAmp >> 8) * grainDecay;
- grain2Amp -= (grain2Amp >> 8) * grain2Decay;
-
- // Scale output to the available range, clipping if necessary
- output >>= 9;
- if (output > 255) output = 255;
-
- // Output to PWM (this is faster than using analogWrite)
- PWM_VALUE = output;
- }
复制代码 硬件接法如下图:
最后附上我录制的视频,可以去听听声音,我感觉还行~哈哈,视频中的音箱也是自己做的哦,3寸的全频迷宫式音箱,听人声杠杠的!
http://v.youku.com/v_show/id_XNjQzNzYzMTUy.html
[ 本帖最后由 tanzhaoran 于 2013-12-6 17:34 编辑 ]
|
赞赏
-
1
查看全部赞赏
-
|