PWM引脚输出错误?

时间:2019-01-28 20:11:38

标签: audio arduino atmega pwm synthesizer

我对编程还很陌生,由于对音乐很着迷,因此我想从使用网络代码构建简单的音序器开始。

现在,我找到了一个完美的代码,但由于某种原因它无法按需运行,因此我希望在此处获得一些建议,以了解更多信息并最终构建自己的合成器!

/* analog inputs:
 * A0 pitch step 1 (syncPhaseInc)
 * A1 pitch step 2
 * A2 pitch step 3
 * A3 pitch step 4
 * A4 tempo
 * A5 effect (grainPhaseInc)
 * plus volume potentiometer
 *
 * audio out via 220 ohm resistor to 3.5mm jack
 * audio out via 10K/10K voltage divider and 10K volume pot and 10uF cap to internal mono amp with speaker
 * power switch on amp
 * built with Arduino Nano on perf board powered by USB cable
 */

#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;

// 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__) || defined(__AVR_ATmega2560__)
 //
 // 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
 }

long counter = 0;
 long tempo;
 int pattern = 0;

const byte pat0 = 4;
 const byte pat1 = 5;
 const byte pat2 = 6;
 const byte pat3 = 7;

void setup() {
 pinMode(PWM_PIN, OUTPUT);
 audioOn();
 pinMode(LED_PIN, OUTPUT);

pinMode(pat0, OUTPUT);
 pinMode(pat1, OUTPUT);
 pinMode(pat2, OUTPUT);
 pinMode(pat3, OUTPUT);
 digitalWrite(pat0, LOW);
 digitalWrite(pat1, LOW);
 digitalWrite(pat2, LOW);
 digitalWrite(pat3, LOW);

// presets for 3 less important pots
 grainDecay = 200 / 8;
 grain2PhaseInc = mapPhaseInc(200) / 2;
 grain2Decay = 200 / 4;
 }

void loop() {

tempo = map(analogRead(A4), 0, 1023, 100, 4000);
 counter++;
 if (counter > tempo) {
 counter = 0;
 if (pattern == 4) {
 pattern = 0;
 }
 switch (pattern) {
 case 0:
 syncPhaseInc = mapPentatonic(analogRead(A0));
 digitalWrite(pat3, LOW);
 digitalWrite(pat0, HIGH);
 break;
 case 1:
 syncPhaseInc = mapPentatonic(analogRead(A1));
 digitalWrite(pat0, LOW);
 digitalWrite(pat1, HIGH);
 break;
 case 2:
 syncPhaseInc = mapPentatonic(analogRead(A2));
 digitalWrite(pat1, LOW);
 digitalWrite(pat2, HIGH);
 break;
 case 3:
 syncPhaseInc = mapPentatonic(analogRead(A3));
 digitalWrite(pat2, LOW);
 digitalWrite(pat3, HIGH);
 break;
 }

grainPhaseInc = mapPhaseInc(analogRead(A5)) / 2;
 pattern++;
 }
 }

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;
 }
  • 我无法解释的一件事是声音输出引脚与代码中的不同。该代码指出,我使用的ATmega328的输出引脚为PWM 3,但是当我使用放大器芯片放大声音时,该引脚发出的声音超柔和嘈杂。
  • PWM 13产生干净而响亮的声音,但是在声音上放置滤镜和效果似乎无效。

有人知道为什么会这样吗?我真的很想在声音上使用效果。因为什么是没有出色效果的合成器?!

谢谢!

0 个答案:

没有答案