Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

Re: [AVR-Chat] ATtiny2313 audio

Re: [AVR-Chat] ATtiny2313 audio

2009-12-27 by Leon Heller

----- Original Message ----- 
Show quoted textHide quoted text
From: "Marc R.J. Brevoort" <mrjb@dnd.utwente.nl>
To: <AVR-Chat@yahoogroups.com>
Sent: Sunday, December 27, 2009 2:56 PM
Subject: [AVR-Chat] ATtiny2313 audio


> Hello all,
>
> I've been programming the ATtiny2313 to generate
> monophonic, square wave beeps (you could call it
> 'music' with a bit of imagination). The code was
> based mostly around the delay function.
>
> I'd like to try polyphonic audio now- still using
> simple square waves. As the time needed per
> calculation is now variable and/or the wave forms
> more complex, I can no longer count on the delay
> function. So instead, I wanted to make the code
> interrupt-driven.
>
> However, I don't seem to manage to get even nearly
> enough interrupts per second to generate audio.
> I would need about 16000 interrupts per second.
> The ATtiny2313 is running at 8 MHz. Is the 2313
> simply too slow for the task? Surely if a lowly
> 286 could feed audio to a DAC, the ATtiny2313
> should be able to handle the load as well?

I've generated sine waves using a software DDS up to 200 kHz or so, with a 
12 MHz Tiny2313.

Leon

ATtiny2313 audio

2009-12-27 by Marc R.J. Brevoort

Hello all,

I've been programming the ATtiny2313 to generate
monophonic, square wave beeps (you could call it
'music' with a bit of imagination). The code was
based mostly around the delay function.

I'd like to try polyphonic audio now- still using
simple square waves. As the time needed per
calculation is now variable and/or the wave forms
more complex, I can no longer count on the delay
function. So instead, I wanted to make the code
interrupt-driven.

However, I don't seem to manage to get even nearly
enough interrupts per second to generate audio.
I would need about 16000 interrupts per second.
The ATtiny2313 is running at 8 MHz. Is the 2313
simply too slow for the task? Surely if a lowly
286 could feed audio to a DAC, the ATtiny2313
should be able to handle the load as well?

Best,
Marc

Re: [AVR-Chat] ATtiny2313 audio

2009-12-27 by wg0z@aol.com

you'll probably have to change your approach to the problem; use the PWM channel(s) to generate your waveforms. 
Show quoted textHide quoted text
-----Original Message-----
From: Marc R.J. Brevoort <mrjb@dnd.utwente.nl>
To: AVR-Chat@yahoogroups.com
Sent: Sun, Dec 27, 2009 7:56 am
Subject: [AVR-Chat] ATtiny2313 audio


Hello all,
I've been programming the ATtiny2313 to generate
onophonic, square wave beeps (you could call it
music' with a bit of imagination). The code was
ased mostly around the delay function.
I'd like to try polyphonic audio now- still using
imple square waves. As the time needed per
alculation is now variable and/or the wave forms
ore complex, I can no longer count on the delay
unction. So instead, I wanted to make the code
nterrupt-driven.
However, I don't seem to manage to get even nearly
nough interrupts per second to generate audio.
 would need about 16000 interrupts per second.
he ATtiny2313 is running at 8 MHz. Is the 2313
imply too slow for the task? Surely if a lowly
86 could feed audio to a DAC, the ATtiny2313
hould be able to handle the load as well?
Best,
arc

------------------------------------
Yahoo! Groups Links
   Individual Email | Traditional
   http://docs.yahoo.com/info/terms/



[Non-text portions of this message have been removed]

Re: [AVR-Chat] ATtiny2313 audio

2009-12-27 by enkitec@gmail.com

Marc R.J. Brevoort wrote:
> I would need about 16000 interrupts per second.
> The ATtiny2313 is running at 8 MHz. Is the 2313
> simply too slow for the task?
>   

    16000 interrupts at 8Mhz means the processor can run ~500 single 
cycle instructions between interrupts. Isn't that enough?

    Mark Jordan

Re: [AVR-Chat] ATtiny2313 audio

2009-12-28 by Marc R.J. Brevoort

On Sun, 27 Dec 2009, Leon Heller wrote:

>> I'd like to try polyphonic audio now- still using
>> simple square waves. Is the 2313 simply too slow
>> for the task?

> I've generated sine waves using a software DDS up
> to 200 kHz or so, with a 12 MHz Tiny2313.

All right, that pretty much answered the question
('The ATtiny2313 should be able to cope just fine').
Apparently I had selected the wrong prescaler value.

I had set the prescaler to 256, assuming this would
result in a timer of 8MHz/256=31250 Hz, and set
TCNT0 to 254 (one overflow every 2 ticks, or roughly
15625 times per second) which would give me approx.
512 cycles to calculate the wave.

Right now, I've set:

TCCR0B to 0<<CS02|0<<CS01|1<<CS00 (no prescaling)
and
TCNT0 to 255 (overflow on next tick)
and
TIMSK=(1<<TOIE) (enable counter overflow int).

This does give me a high enough sample rate,
and I'm managing to get polyphonic sound -
BUT it also implies that my understanding of the
prescaler and timers is still wrong, as by my
understanding this would mean to have an interrupt
roughly every clock cycle (which would leave
absolutely no time for any calculations).

If anyone could clue me in about what am I missing,
I'd be very grateful!

Best,
Marc

Re: [AVR-Chat] ATtiny2313 audio

2009-12-28 by enkitec@gmail.com

Marc R.J. Brevoort wrote:
> I had set the prescaler to 256, assuming this would
> result in a timer of 8MHz/256=31250 Hz, and set
> TCNT0 to 254 (one overflow every 2 ticks, or roughly
> 15625 times per second) which would give me approx.
> 512 cycles to calculate the wave.
>
> Right now, I've set:
>
> TCCR0B to 0<<CS02|0<<CS01|1<<CS00 (no prescaling)
> and
> TCNT0 to 255 (overflow on next tick)
> and
> TIMSK=(1<<TOIE) (enable counter overflow int).

    For one interrupt every 1/31250Hz, I'd use:

    TCCR0A = 1<<WGM1  (CTC mode)
    TCCR0B = 1<<CS01   (8MHz/8)
    OCR0A = ((8MHz/8)/31250Hz)-1 = 32-1
    TIMSK = 1<<OC1E0A
    TCNT0 = don't care

    Mark Jordan

Re: [AVR-Chat] ATtiny2313 audio

2009-12-28 by Marc R.J. Brevoort

>> Right now, I've set:
>> TCCR0B = 0<<CS02|0<<CS01|1<<CS00 (no prescaling)
>> TCNT0 = 255 (overflow on next tick)
>> TIMSK=(1<<TOIE) (enable counter overflow int).

>    For one interrupt every 1/31250Hz, I'd use:
>    TCCR0A = 1<<WGM1  (CTC mode)
>    TCCR0B = 1<<CS01   (8MHz/8)
>    OCR0A = ((8MHz/8)/31250Hz)-1 = 32-1
>    TIMSK = 1<<OC1E0A
>    TCNT0 = don't care

I assume you mean 1<<WGM01 for TCCR0A (CTC mode, TOP=OCR0A).
I also changed ISR (SIG_OVERFLOW0) to ISR (TIMER0_COMPA_vect).
This works, more or less. That is, the interrupt routine gets 
called, but by the pitch I get it seems to be at a quarter of
the rate that it should be.

Strangely, altering OCR0A does not seem to influence
the pitch at all, which makes me think something else is
amiss which makes the ATtiny ignore the value in OCR0A.

Any ideas?

Best,
Marc

Re: [AVR-Chat] ATtiny2313 audio

2009-12-28 by enkitec@gmail.com

Marc R.J. Brevoort wrote:
>>> Right now, I've set:
>>> TCCR0B = 0<<CS02|0<<CS01|1<<CS00 (no prescaling)
>>> TCNT0 = 255 (overflow on next tick)
>>> TIMSK=(1<<TOIE) (enable counter overflow int).
>>>       
>
>   
>>    For one interrupt every 1/31250Hz, I'd use:
>>    TCCR0A = 1<<WGM1  (CTC mode)
>>    TCCR0B = 1<<CS01   (8MHz/8)
>>    OCR0A = ((8MHz/8)/31250Hz)-1 = 32-1
>>    TIMSK = 1<<OC1E0A
>>    TCNT0 = don't care
>>     
>
> I assume you mean 1<<WGM01 for TCCR0A (CTC mode, TOP=OCR0A).
> I also changed ISR (SIG_OVERFLOW0) to ISR (TIMER0_COMPA_vect).
> This works, more or less. That is, the interrupt routine gets 
> called, but by the pitch I get it seems to be at a quarter of
> the rate that it should be.
>
> Strangely, altering OCR0A does not seem to influence
> the pitch at all, which makes me think something else is
> amiss which makes the ATtiny ignore the value in OCR0A.
>
> Any ideas?
>
> Best,
> Marc
>   

    Please verify if the clock source fuses are set up to cristal 
oscillator.
    Check CKSEL0 to CKSEL3 and CKDIV8.

    Mark Jordan

Re: [AVR-Chat] ATtiny2313 audio- w/source

2009-12-28 by Marc R.J. Brevoort

On Mon, 28 Dec 2009, enkitec@gmail.com wrote:

> Please verify if the clock source fuses are set up to cristal
> oscillator.

My fuses are (Low, Extended, High): 0xee, 0xff, 0xdf.

I've come one step further as I noticed changing OCR0A
*did* make a difference when I increased its value far
enough. Actually, more accurately, this more or less
means we're more or less "back to square one", except
I think I understand a bit better what I'm doing now.

Perhaps I need to give a bit more detail.

Here are the relevant code snippets:

#define TIMERFREQ 7812
#define HALFWAVE 3906
void setup_timer(void)
{
   TCCR0A=(0<<WGM02)|(1<<WGM01)|(0<<WGM00); // CTC mode
   TCCR0B=(1<<CS01)|(1<<CS00); // 8 mhz/64
   OCR0A=15; // 8 mhz/64/(15+1)= 7812.5
   TIMSK=(1<<OCIE0A); // Enable Counter Overflow Interrupt
   sei();
}

ISR (TIMER0_COMPA_vect)
{
   // calculate polyphonic square wave (individual
   // amplitudes)
   int stat=0;
   w1=(w1+f1)%TIMERFREQ;
   w2=(w2+f2)%TIMERFREQ;
   w3=(w3+f3)%TIMERFREQ;
   if (w1<HALFWAVE) stat+=amplitude1;
   if (w2<HALFWAVE) stat+=amplitude2;
   if (w3<HALFWAVE) stat+=amplitude3;
   PORTB=stat;
}

(Full code is here:
http://ringbreak.dnd.utwente.nl/~mrjb/electro/polyphonic.c )

This works and gives notes at the right pitch.
However, if I set OCR0A to 7, this should
cause 15625 interrupts per second, right?

When I do this and

#define TIMERFREQ 15625
#define HALFWAVE 7812

the pitch actually drops. When lowering OCR0A
further, pitch remains constant, which seems
to indicate the ATtiny2313 is simply working
as hard as it can but simply cannot keep up.

So this brings me to my original question:
Is the 2313 simply too slow for the task,
or should I use assembly instead of C?
What special voodoo magic have you people
been using to generate 200kHz sine waves?

Best,
Marc

Re: ATtiny2313 audio- w/source

2009-12-29 by Donald H

> Marc
>

I think this may help you.
http://www.avr-asm-tutorial.net/avr_en/AVR_DAC.html

Please understand the basics of what you want to do, then code.

don

Re: ATtiny2313 audio- w/source

2009-12-29 by Donald H

--- In AVR-Chat@yahoogroups.com, "Donald H" <donhamilton2002@...> wrote:
>
> > Marc
> >
> 
> I think this may help you.
> http://www.avr-asm-tutorial.net/avr_en/AVR_DAC.html
> 
> Please understand the basics of what you want to do, then code.
> 
> don
>
Oh, yea

Google is your friend:
http://www.google.com/search?q=AVR+DAC+out

Re: [AVR-Chat] Re: ATtiny2313 audio- w/source

2009-12-29 by Leon Heller

----- Original Message ----- 
Show quoted textHide quoted text
From: "Marc R.J. Brevoort" <mrjb@dnd.utwente.nl>
To: <AVR-Chat@yahoogroups.com>
Sent: Tuesday, December 29, 2009 9:02 PM
Subject: Re: [AVR-Chat] Re: ATtiny2313 audio- w/source


> Hi Donald,
>
>> Please understand the basics of what you want to do, then code.
>> I think this may help you.
>> http://www.avr-asm-tutorial.net/avr_en/AVR_DAC.html
>
> Thanks for the link. Unfortunately it has little to do with my main
> issue, which was about how to write timer-based, interrupt-driven
> code for the AVR in C. The actual signal generation (as described
> in the above article) is the easy part!
>
> I find it interesting, however, that the code on the page you mentioned
> seems to have limits similar to the ones I have been running into:
> 1800Hz for a 256-sample sine wave at a 4MHz clock speed translates to
> roughly 61 cycles per sample, which does not leave a lot of room for
> anything else. (In an interrupt-driven solution, a few more cycles are
> burnt to preserve machine state).
>
> It does leave me curious about how Leon managed to generate 200kHz
> sine waves on a 12 MHz AVR- that would seem to only leave 30 cycles
> per sample (and at that point the signal would really be a square wave
> rather than a sine wave).
>
> Unless there was some other hardware-assisted trick at work there.
> The question is if that 'trick' would be of any help for polyphonic
> audio.
>
> Leon, care to comment?

The code is here:

http://webspace.webring.com/people/jl/leon_heller/dds.html

I've got a similar program that is interrupt-driven, avoiding glitches when 
the frequency is changed.

Leon

Re: [AVR-Chat] Re: ATtiny2313 audio- w/source

2009-12-29 by Marc R.J. Brevoort

Hi Donald,

> Please understand the basics of what you want to do, then code.
> I think this may help you.
> http://www.avr-asm-tutorial.net/avr_en/AVR_DAC.html

Thanks for the link. Unfortunately it has little to do with my main
issue, which was about how to write timer-based, interrupt-driven
code for the AVR in C. The actual signal generation (as described
in the above article) is the easy part!

I find it interesting, however, that the code on the page you mentioned 
seems to have limits similar to the ones I have been running into:
1800Hz for a 256-sample sine wave at a 4MHz clock speed translates to
roughly 61 cycles per sample, which does not leave a lot of room for
anything else. (In an interrupt-driven solution, a few more cycles are
burnt to preserve machine state).

It does leave me curious about how Leon managed to generate 200kHz
sine waves on a 12 MHz AVR- that would seem to only leave 30 cycles
per sample (and at that point the signal would really be a square wave 
rather than a sine wave).

Unless there was some other hardware-assisted trick at work there.
The question is if that 'trick' would be of any help for polyphonic
audio.

Leon, care to comment?

Best,
Marc

Re: [AVR-Chat] Re: ATtiny2313 audio- w/source

2009-12-29 by BobGardner@aol.com

Hi Donald. I also have written avr c programs to play sine waves and other 'arbitrary' waveforms from a table and usually there is plenty of cpu left to even generate samples at 2 or 3 frequencies (3 part harmony?) and arithmetically add the samples together and stuff it into the OCR register to play thru the pwm out and an RC filter. The trick to playing that one cycle of arbitrary waveform back at different freqencies is: dont change the clock frequency or the sample frequency to speed it up and slow it down... (this is the obvious method of course), but you advance a pointer through the waveform table by a non integer step size. How to do that wasnt obvious either. Its easy to see that if you play every other sample, you get to the end of the table twice as fast, so the waveform is looping one octave higher. Playing the next sample, then skip a sample is like playing every 1.5 samples, which is about a 5th higher. The trick is have a 'frequency increment' that has an integer part and a fractional part. This increment is added to the waveform pointer and the sample that the integer part is pointing to is played. As the freq gets higher, the waveform looks blocky-er, and it should sound terrible, but the output lowpass filter just lets the basic waveform thru. This is described in Hal Chamberlin's book 'Musical Applications of Microprocessors'. Some folks call it the 'phase accumulator' waveform generation technique. The Fairlight synthesizer used this (back in the 80s?!?) and used 6800s, so an avr running running way faster ought to be able to do it too.







[Non-text portions of this message have been removed]

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.