Quiero reproducir algunos clips cortos de audio (que van desde 50ms a 100ms) de mi microcontrolador atmega168 y la salida a un altavoz barato.
Estaba siguiendo este tutorial pero como estoy usando un atmega168 y no un atmega2560, tuve que modificar mi codigo asi como reemplazar el sonido.
Como en el tutorial, estoy usando un oscilador interno de 8MHz (puse LFUSE = 0xE2 en el Makefile) y todos los ajustes PWM son los mismos...lo que significa que
- Uso de un temporizador/contador de 161 con resolución PWM de 8 bits
- Ajustar OC1A en la comparación (y borrar en la parte inferior)
- Sin preescalado
En cuanto al clip de sonido, lo muestreé a 15,625 kHz y lo exporté a un archivo wav PCM de 8 bits. A continuación, obtener un volcado hexadecimal a través de xxd -i que me da el archivo c de salida. No he eliminado el encabezado como me imaginé que sólo puede saltar por sólo ir a la 44º puesto de la matriz de salida, ya que es la posición de los datos.
El problema que tengo es que, si bien obtengo mi sonido (distorsionado y suave), hay un fuerte pitido que se superpone a mi sonido y no tengo ni idea de cuál es la causa.
Por desgracia, no tengo acceso a un osciloscopio, así que no puedo precisar si se trata de la forma en que he muestreado mi sonido, o si mi sonido es demasiado corto o algo que está más allá de mi comprensión actual.
Main.c
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/power.h>
#include <util/setbaud.h>
#include <avr/interrupt.h>
#include "switch.h"
#define WAV_DATA_POSITION 44
#define BASE_LEVEL 0xff
unsigned int count=WAV_DATA_POSITION;;
volatile uint16_t timerOverflowCount;
unsigned char sample_count =2;
// This interrupt service reads new data,
ISR(TIMER1_OVF_vect){
sample_count--;
if(sample_count ==0)
{
sample_count = 2;
if (count < switchResampled_len){
OCR1A= pgm_read_byte(&switch_raw[count]);
count++;
}
}
else{
OCR1A= BASE_LEVEL;
}
}
void pwm_init()
{
SREG |=0x80;
//select Fast PWM with 8-bit resolution,set OC1A on compare match and clear at bottom
TCCR1A|=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM10);
//No prescaling therefore timer frequency = 8 MHz and PWM frequency = 31250 Hz
TCCR1B|=(1<<WGM12)|(1<<CS10);
TCNT1=0x00;
OCR1A=BASE_LEVEL;
//Enable the timer interrupt
TIMSK1 |= ( 1 <<TOIE1);
//Clear all interupt flags
TIFR1|=(1<<ICF1)|(1<<OCF1B)|(1<<OCF1A)|(1<<TOV1);
//Enable interrupts
sei();
}
int main(void)
{
//PB1 is OC1A. Use this for output
DDRB |= (1 << PB1);
pwm_init();
/* insert your hardware initialization here */
for(;;){
/* insert your main loop code here */
}
return 0; /* never reached */
}
Switch.h (Archivo de sonido)
const unsigned char switch_raw[] PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x0d, 0x04, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x09, 0x3d, 0x00, 0x00, 0x09, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
0x64, 0x61, 0x74, 0x61, 0x4b, 0x03, 0x00, 0x00, 0x80, 0x7f, 0x7f, 0x7e,
0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x7f, 0x7e, 0x7e,
0x7f, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7f, 0x81, 0x7e, 0x7e, 0x7f, 0x7f,
0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x80, 0x81, 0x7e, 0x7b, 0x7e, 0x7f,
0x7f, 0x81, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e,
0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x7d, 0x7b,
0x80, 0x7f, 0x7f, 0x83, 0x7f, 0x7b, 0x7f, 0x80, 0x7f, 0x82, 0x7f, 0x7e,
0x80, 0x7e, 0x81, 0x7f, 0x7f, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e,
0x7f, 0x85, 0x80, 0x83, 0x7b, 0x77, 0x83, 0x81, 0x86, 0x7e, 0x7b, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x7f, 0x7e, 0x7e, 0x7e,
0x81, 0x83, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x83,
0x7f, 0x7d, 0x7b, 0x80, 0x80, 0x94, 0x79, 0x68, 0x87, 0x75, 0x98, 0x87,
0x6e, 0x7f, 0x8c, 0x81, 0x54, 0x7c, 0xc4, 0x8a, 0x46, 0x31, 0x72, 0xe2,
0xc1, 0x8a, 0x41, 0x2f, 0x71, 0xb3, 0xc8, 0x96, 0x51, 0x41, 0x67, 0x9c,
0xb1, 0x98, 0x74, 0x57, 0x5f, 0x76, 0x99, 0xa8, 0x96, 0x72, 0x5b, 0x64,
0x7e, 0x97, 0xa1, 0x8f, 0x6f, 0x56, 0x66, 0x89, 0xa0, 0x9d, 0x7e, 0x62,
0x5c, 0x78, 0x93, 0x9d, 0x90, 0x70, 0x58, 0x68, 0x88, 0x9c, 0x95, 0x7c,
0x66, 0x64, 0x7c, 0x90, 0x95, 0x82, 0x6f, 0x6b, 0x75, 0x86, 0x8e, 0x88,
0x79, 0x72, 0x75, 0x80, 0x88, 0x89, 0x81, 0x78, 0x74, 0x78, 0x84, 0x85,
0x84, 0x7d, 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x81, 0x76, 0x74, 0x7e,
0x82, 0x89, 0x84, 0x7c, 0x77, 0x78, 0x84, 0x83, 0x84, 0x7c, 0x78, 0x7b,
0x83, 0x83, 0x80, 0x83, 0x80, 0x7d, 0x7a, 0x7e, 0x83, 0x87, 0x82, 0x79,
0x78, 0x7e, 0x87, 0x8b, 0x80, 0x76, 0x79, 0x7e, 0x87, 0x87, 0x80, 0x7a,
0x7a, 0x80, 0x82, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7a, 0x82, 0x88, 0x7f,
0x7a, 0x79, 0x7f, 0x85, 0x85, 0x7f, 0x7d, 0x7a, 0x7d, 0x83, 0x87, 0x7e,
0x78, 0x7e, 0x7d, 0x83, 0x7e, 0x81, 0x81, 0x80, 0x7f, 0x81, 0x81, 0x7c,
0x7e, 0x7a, 0x81, 0x82, 0x81, 0x84, 0x82, 0x79, 0x78, 0x84, 0x86, 0x7d,
0x7b, 0x7e, 0x7f, 0x7c, 0x7d, 0x7d, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x85,
0x84, 0x7b, 0x75, 0x7c, 0x7d, 0x84, 0x88, 0x84, 0x7b, 0x7b, 0x7d, 0x7c,
0x88, 0x88, 0x7b, 0x78, 0x78, 0x78, 0x88, 0x8d, 0x80, 0x78, 0x7f, 0x86,
0x86, 0x83, 0x7c, 0x71, 0x76, 0x84, 0x97, 0x93, 0x70, 0x6d, 0x68, 0x78,
0xc5, 0xb6, 0x5f, 0x37, 0x2a, 0x69, 0xc1, 0xc9, 0xa0, 0x7a, 0x52, 0x50,
0x71, 0x8a, 0x9d, 0xa0, 0x8b, 0x69, 0x67, 0x68, 0x79, 0x94, 0x96, 0x87,
0x7b, 0x81, 0x84, 0x7e, 0x7d, 0x7e, 0x75, 0x72, 0x89, 0x8e, 0x88, 0x86,
0x6d, 0x6d, 0x7a, 0x82, 0x8d, 0x8e, 0x78, 0x76, 0x7f, 0x7d, 0x7e, 0x82,
0x80, 0x7b, 0x7d, 0x7a, 0x7b, 0x86, 0x89, 0x80, 0x7b, 0x75, 0x77, 0x7f,
0x83, 0x84, 0x86, 0x81, 0x81, 0x7e, 0x73, 0x7c, 0x83, 0x7f, 0x85, 0x82,
0x7d, 0x83, 0x7d, 0x7d, 0x80, 0x7b, 0x7c, 0x86, 0x85, 0x7e, 0x7b, 0x74,
0x7d, 0x86, 0x85, 0x8b, 0x81, 0x76, 0x78, 0x78, 0x7e, 0x89, 0x83, 0x7e,
0x80, 0x78, 0x7f, 0x84, 0x81, 0x84, 0x7a, 0x77, 0x7f, 0x81, 0x84, 0x81,
0x78, 0x7a, 0x7e, 0x84, 0x8e, 0x81, 0x72, 0x75, 0x77, 0x83, 0x8b, 0x84,
0x84, 0x7b, 0x72, 0x7a, 0x83, 0x84, 0x85, 0x7e, 0x78, 0x7e, 0x7d, 0x7f,
0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x81, 0x7e, 0x7b, 0x80, 0x85, 0x84, 0x82,
0x7d, 0x7a, 0x7d, 0x7f, 0x84, 0x84, 0x7f, 0x79, 0x7b, 0x82, 0x80, 0x80,
0x81, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x79, 0x79, 0x81, 0x86, 0x85, 0x82,
0x7d, 0x77, 0x7a, 0x7e, 0x86, 0x8b, 0x84, 0x7a, 0x7a, 0x7d, 0x7e, 0x83,
0x83, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7e,
0x7f, 0x80, 0x7f, 0x7c, 0x80, 0x7d, 0x7e, 0x85, 0x81, 0x7c, 0x7d, 0x7b,
0x7c, 0x81, 0x80, 0x7d, 0x7f, 0x80, 0x7d, 0x82, 0x84, 0x7e, 0x7a, 0x7e,
0x7e, 0x7f, 0x82, 0x7d, 0x7e, 0x81, 0x7f, 0x7d, 0x7e, 0x81, 0x83, 0x83,
0x80, 0x79, 0x77, 0x7c, 0x83, 0x87, 0x86, 0x7f, 0x75, 0x79, 0x7e, 0x85,
0x86, 0x80, 0x7a, 0x78, 0x7c, 0x7f, 0x83, 0x81, 0x82, 0x7d, 0x7a, 0x7f,
0x81, 0x80, 0x80, 0x7c, 0x7b, 0x80, 0x7e, 0x80, 0x85, 0x84, 0x7d, 0x7b,
0x7a, 0x7f, 0x83, 0x82, 0x80, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x7f, 0x7f,
0x7e, 0x7f, 0x82, 0x7f, 0x7c, 0x7b, 0x7b, 0x82, 0x84, 0x83, 0x7e, 0x7c,
0x7b, 0x7e, 0x83, 0x81, 0x7f, 0x7d, 0x7e, 0x7f, 0x83, 0x81, 0x7e, 0x7d,
0x7b, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7f, 0x80, 0x7f, 0x80,
0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x80, 0x7d, 0x7f, 0x81,
0x80, 0x7f, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f,
0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7e, 0x7c, 0x7f, 0x81, 0x80, 0x80,
0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7d,
0x7c, 0x7f, 0x80, 0x83, 0x81, 0x7c, 0x7b, 0x7c, 0x7f, 0x82, 0x82, 0x7f,
0x7d, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x80, 0x82,
0x7f, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x82, 0x7f, 0x7f, 0x7a, 0x7d, 0x80,
0x81, 0x81, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7f, 0x80, 0x7f, 0x80,
0x7f, 0x7e, 0x7d, 0x7f, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e,
0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7f, 0x82,
0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7f,
0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d,
0x81, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x7f, 0x80, 0x80, 0x7f,
0x7f, 0x7d, 0x7f, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7e, 0x4c,
0x49, 0x53, 0x54, 0x48, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x46, 0x4f, 0x49,
0x43, 0x52, 0x44, 0x12, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x36, 0x2d,
0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32, 0x37, 0x00,
0x00, 0x49, 0x53, 0x46, 0x54, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x20, 0x28,
0x6c, 0x69, 0x62, 0x73, 0x6e, 0x64, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x31,
0x2e, 0x30, 0x2e, 0x32, 0x34, 0x29, 0x00, 0x69, 0x64, 0x33, 0x20, 0x46,
0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x54, 0x58, 0x58, 0x58, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x4c, 0x61, 0x76,
0x66, 0x35, 0x37, 0x2e, 0x37, 0x32, 0x2e, 0x31, 0x30, 0x31, 0x54, 0x44,
0x52, 0x43, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31,
0x36, 0x2d, 0x31, 0x30, 0x2d, 0x31, 0x37, 0x20, 0x31, 0x37, 0x3a, 0x32,
0x37
};
const long switchResampled_len = 1045;
1 votos
Esa es probablemente la tasa fundamental PWM, en la que está modificando el CICLO DE TRABAJO pero no la tasa de repetición.
3 votos
1045 muestras a 15,625 kHz son sólo 67 segundos de datos. Cómo vas a oír algo en sólo 67mSeg?
0 votos
Por cierto, en lugar de utilizar PWM, existen microcontroladores baratos y accesibles con salidas analógicas reales (por ejemplo, de 12 bits de resolución).
0 votos
@analogsystemsrf ¿Qué quiere decir con "tasa de repetición"?
0 votos
@brhans El archivo original dura 67 ms... o al menos según audacity. Son archivos de efectos de sonido, así que no bromeaba cuando decía que son clips de sonido cortos.