capturando sonido con Atmega328
Página 1 de 1.
capturando sonido con Atmega328
Esto es una prueba de captura de sonido con la plaquita Metaboard con un chip Atmega328.
Esta placa es muy sencilla y barata, inspirada en las arduino, se programa por usb sin necesidad de programador (una vez grabado el bootloader) y tiene una pequeña area de prototipado.
Para capturar sonido con una calidad mínima el tema es cofigurar el ADC para que vaya lo más rápido posible: a 8 bits y en modo "free running" el adc se dispara sólo y hace una lectura cada 13 uS (reloj a 16 Mhz) sin tener que llamarlo por software. Esto sólo vale para leer un solo canal continuamente.
el programita de abajo crea una tarea que se ejecuta cada 52 uS , lee el registro adc, le aplica algunos efectos sencillos y el resultado lo saca por PWM.
Aqui hay dos efectos:
Reverb, que consiste en una especie de "eco" muy rápido, osea mezclar la lectura actual con una anterior.
Pitch, que aplica una onda sinoidal a la señal pra lograr un efecto de más grave o agudo.
La onda sinoidal no se calcula sino que está grabada en una tabla, así que sólo hay que leer los valores consecutivamente.
Con algún control exterior tipo pulsador se podrían ir cambiando los efectos, pero eso no esta incluido en este programita (gcbasic):
Esta placa es muy sencilla y barata, inspirada en las arduino, se programa por usb sin necesidad de programador (una vez grabado el bootloader) y tiene una pequeña area de prototipado.
Para capturar sonido con una calidad mínima el tema es cofigurar el ADC para que vaya lo más rápido posible: a 8 bits y en modo "free running" el adc se dispara sólo y hace una lectura cada 13 uS (reloj a 16 Mhz) sin tener que llamarlo por software. Esto sólo vale para leer un solo canal continuamente.
el programita de abajo crea una tarea que se ejecuta cada 52 uS , lee el registro adc, le aplica algunos efectos sencillos y el resultado lo saca por PWM.
Aqui hay dos efectos:
Reverb, que consiste en una especie de "eco" muy rápido, osea mezclar la lectura actual con una anterior.
Pitch, que aplica una onda sinoidal a la señal pra lograr un efecto de más grave o agudo.
La onda sinoidal no se calcula sino que está grabada en una tabla, así que sólo hay que leer los valores consecutivamente.
Con algún control exterior tipo pulsador se podrían ir cambiando los efectos, pero eso no esta incluido en este programita (gcbasic):
' Implementar adc rapido, captura sonido y aplica reverb y pitch
' Timer2 prescalers: 1-7: 1,8,32,64,128,256,1024
' presc KHz(aprox) Fosc: 16 MHz.
' 1 : 62.5
' 8 : 8
' 32 : 2
' 64 : 0.5
' 128 : 0.125
#chip mega328p, 16 'MHz
#include "sin_tab.h"
'Multitasking __________________________________________________________________
#include <multitasking.h>
#define base_time 52 'us
#define Task1 Sample
#define Task1_us base_time
'_______________________________________________________________________________
#define pwmPin PORTB.3 'OC2A
dir portb.5 OUT
portb.5 = 1 ' TO AREF
dir PORTD.0 out
PORTD.0 = 0
dir pwmPin out
dir PORTB.4 out
PORTB.4 = 0
dir PORTC out
dir PORTC.0 in
dim tempoint as integer
' Array ________________________________________________________________________
#define size 1000
dim buffer(size)
dim write as word ' array index to write data
dim read as word ' array index to read data
dim offset as word
read = 1
offset = 900 '46800/base_time
write = read + offset
'_______________________________________________________________________________
dim pitch as word
counter = 0
initpwm
initadc
Do
Do_Task1
Loop
'Subroutines ___________________________________________________________________
Sub initpwm ' Timer 2, 1 KHz 50% fosc: 16 MHz
OCR2A = 0 ' Duty 0%
' PWM Phase Correct, duty = OCR2X
TCCR2A = b'10000001' ' bits 6:7 output-A; bits 4:5 output-B
' Prescaler = 2 => presc 8
TCCR2B = b'00000001' ' Period = 2* 256 * 8/16 = 256 uS, Frec = 1/256e-6 = 3906,25 Hz
' Prescaler = 3 => presc 32
End Sub ' Period = 2* 256 * 32/16 = 1024 uS, Frec = 1/1024e-6 = 976,5 Hz
Sub initadc
ADMUX = b'01100000' ' Channel 0, Left justified, Vref = Avcc
ADCSRA = b'11100100' ' Enabled, Auto-Trigger, presc = 16
ADCSRB = 0
End Sub
Sub Sample
write += 1
if write > size then write = 1
read += 1
if read > size then read = 1
' Read sin table
if counter = 255 then
counter = 0
sin = 0
else
if counter = 0 then
sin = 0
else
ReadTable Sin_Tab, counter, sin
end if
counter += 1
end if
' Read actual adc value
value = ADCH
' Substract dc
tempoint = [integer]value - [integer]127
' Save actual reading
buffer(write) = value
' Aply Reverb ( add actual and buffered values)
tempoint = tempoint + [integer]buffer(read) - [integer]127
tempoint = tempoint / 2
' Aply sin wave to signal (pitch)
tempoint = ([integer]sin*tempoint)/[integer]255
' Output signal to pwm
OCR2A = tempoint + 127
End Sub
Página 1 de 1.
Permisos de este foro:
No puedes responder a temas en este foro.