mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tonfrequenzen (Noten) erzeugen mit tiny45 in C


Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte eine Melodie abspielen, aber ich verstehe nicht, wie ich die 
Töne genau erzeugen kann.
Ich bin soweit dass ein Sinus mit dem schnellen PWM Modus von einem 
tiny45 @ 8MHz (als DAC) mit 64 Schritten erzeugt wird.
Dann müssen die Sinuswerte mit dem 64fachen der Tonfrequenz in das PWM 
Register geladen werden.

Wenn der Tonbereich von A3-A5 also 220-880Hz gehen soll, heisst das für 
den Interrupt 14080Hz (71.02µs) bis 56320Hz (17.75µs).
In dem Bereich liegen 15 Noten mit einer Auflösung von 0.01Hz.
Wenn der Timer mit 1MHz betrieben wird reicht es nicht (1µs), mit 8MHz 
läuft er bei 32µs über.

Wie macht man das?

Autor: Christoph Kessler (db1uq) (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es passt nicht genau zur Frage, aber hier gabs mal einen Thread zum 
Thema Noten in Halbtonschritten berechnen:
Beitrag "Hochzahlen?"

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant, danke.

Autor: Jack Braun (jackbraun)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist dieses Programm für Dich interessant:

http://elm-chan.org/works/mxb/report_e.html

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da steckt anscheinend genau drin, was ich brauche! Leider kann ich nicht 
richtig nachvollziehen, wie es gemacht wird, da ich praktisch keine 
Asm-Erfahrung habe.

Anscheinend verwendet er einen 32kHz Interrupt, um die Frequenzen zu 
erzeugen . Aber wie kommt er bei 16MHz Takt und einem Compare-Wert von 
62 auf 32kHz?

Wie er die Töne erzeugt, verstehe ich leider auch nicht:
;--------------------------------------------------------------------;
; Pitch number to angular speed conversion table
;--------------------------------------------------------------------;
;Since sustain area of wave table, a cycle of fundamental frequency, is sampled
;in 128 points, the base frequency becomes 32000/128 = 250 Hz. The wave table
;lookup pointer, 16.8 fraction, is increased every sample by these 8.8 fractional
;angular speed values.

tbl_pitch: ;  A     B     H     C    Cis    D    Dis    E     F    Fis    G    Gis 
  .dw  225,  239,  253,  268,  284,  301,  319,  338,  358,  379,  401,  425 ; 220Hz..
  .dw  451,  477,  506,  536,  568,  601,  637,  675,  715,  758,  803,  851 ; 440Hz..
  .dw  901,  955, 1011, 1072, 1135, 1203, 1274, 1350, 1430, 1515, 1606, 1701 ; 880Hz..
  .dw 1802, 1909, 2023, 2143, 2271, 2406, 2549, 2700, 2861, 3031, 3211, 3402 ; 1760Hz..
  .dw 3604, 3818, 4046, 4286, 4542, 4812, 5098, 5400         ; 3520Hz

In meinem Fall bräuchte ich ja nur den Sustain-Table mit (hier: 128) 
Sinus-Werten.
Aber wie macht er es - springt er durch die Tabelle (läßt Werte aus), 
oder spielt er sie unterschiedlich schnell ab?

Ich vermute, da er mit 32kHz Sampling Frequenz auskommt, und anscheinend 
3kHz erzeugen kann, muss er wohl Werte auslassen.
Leidet da nicht das Signal drunter? Ich dachte, man spielt immer alle 
Werte ab, und das mit einer variablen Geschwindigkeit..

Kann mir das jemand erklären bitte?

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen "Streit" zum Thema Interruptfrequenz vs. Schrittweite 
gefunden: Beitrag "erzeugen eines sinus mit variabler frequenz"

Ich kann mir aber immer noch nicht vorstellen, wie beim Springen durch 
die Tabelle genaue Frequenzen erzeugt werden können, es sind ja keine 
halben Schritte möglich. Sollten dann die umliegenden Werte gemittelt 
werden?

Speicherintensiv ist die Methode, für jeden Ton eine eigene Sinustabelle 
zu verwenden.

Aber eigentlich brauche ich ja nur jemanden, der mit elm-chans prinzip 
kurz erläutert...

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier vielleicht die Erklärung:

Beitrag "Re: Tonausgabe Attiny26?"

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@jochen

die ganze geschichte beruht auf dem dds. es wird einfach in 
regelmässigen abständen (samplerate) ein bestimmter wert auf eine 
variable addiert und der überlauf (also das kippen des höchstwertigen 
bits) gibt deine grundfrequenz an.
durch abschneiden mehrerer Bits erhälst du eine "position" innerhalb der 
wellenform (sozusagen skaliert auf die anzahl der bits die du 
abgeschnitten hast). diese kannst du nun auf eine sius oder sonstwelche 
tabelle "mappen" und erhälst einen wert den man per pwm (sollte 
sinnigerweise in einem vielfachen der samplerate liegen) "analog" 
ausgibt.
das eigentlich interessante an dds ist das der vorgegebene inkrement 
linear der freuenz entspricht (bis zur hälfte der wiedergabefrequenz 
bzw. samplerate).

die tabelle ist jetzt (so wie ich es verstanden habe) nur der 
inkrement-wert (passend zur jeweiligen note).


du selbst hüpfst nur noch in der tabelle herum um deine melodie zu 
erzeugen :-)


gruß
rene

ps. hoffe ich habe die problematik richtig verstanden :-)

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen vielen Dank für die Erklärung, jetzt komme ich garantiert weiter!

weitere Links:

http://de.wikipedia.org/wiki/Direct_Digital_Synthesis

"Re: Tonausgabe Attiny26?"
Beitrag "Re: Tonausgabe Attiny26?"

"direkte digitale Synthese"
Beitrag "direkte digitale Synthese (DDS, NCO)"

Unter "3.1.1. Funktionsberechnung" auf Seite 6 der Projektbeschreibung 
von 
http://www.mikrocontroller.net/wiki/Projekt_Digita... 
wird man weiterhin fündig.

"A Technical Tutorial on Digital Signal Synthesis" Analog Devices (PDF)
http://www.analog.com/UploadedFiles/Tutorials/4509...

Precision Sine-Wave Tone Synthesis Using 8-Bit MCUs
http://www.freescale.com/files/microcontrollers/do...

"AN1222: Arithmetic Waveform Synthesis with the HC05/08 MCUs" Freescale 
(PDF)
http://www.freescale.com/files/microcontrollers/do...

Autor: Christoph H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein paar Erkenntnisse zu ELM-CHANs Umsetzung:

16MHz PLL Clock
Timer0 im CTC Mode, clk_IO/8
Comparewert von OCR0A, 62 -> 32258.0645 Hz
128 Werte für die Dauerton-Wellenform (sustain)

> Der Clou ist: eine Sinus-Tabelle z.B. mit 256 Einträgen.
> Der Zugriff auf  diese Tabelle geschieht mit einem Pointer, der ein
> Vorkomma- und ein Nachkomma-Byte hat.
> Wir wollen z.B. 440 Hz erzeugen, die Samplefrequenz sei 10 kHz, also
> habe ich 10000 / 440 = 22,7272 Samples für eine Sinusvollwelle.
> also addiere ich in das Nachkommabyte jedesmal 256*0,7272=186,1632 ->
> 186  und dann mit Carry die 22 in das Vorkommabyte, das dann als Index
> in die Tabelle zeigt.
> Die genaue Frequenz ist 10000/(22+186/256)=440,01375 Hz.

Ich habe jetzt versucht, das mal umzusetzen:

8MHz / 8 OCR0A=31

440 Hz / 32.258kHz/128 =  1.74592 -> 1
0.74592 * 256 = 190.95 -> 191

Das entspricht etwa dem 16.8 Wert für A4 in tbl_pitch (mg.asm:267)
ISR(TIM0_COMPA_vect)
{
  static uint8_t i,f;
  
      if(f+191 >=255)
      {
        i++;
      }
      f+=191;
  
        if ((i + 1) >= WTS)
      {
        i = i + 1 - WTS;
      }
      else
      {
        i = i + 1;
      }
      
  OCR1A = sine[i];

}

Mit der nur begrenzt vorhandenen Messtechnik stelle ich einen Fehler von 
5% zu 440Hz fest, und es gibt leichte Schwankungen der Frequenz.

Mit OSCCAL läßt sich der interne Oszillator etwas justieren, aber nur 
verhältnismässig grob.  Also evtl. lieber einen Quarz benutzen.

Um also Teilschritte in der Wellentabelle zu gehen, obwohl nur 
Integer-Werte möglich sind, wird stattdessen gelegentlich ein 
zusätzlicher Schritt eingefügt.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Um also Teilschritte in der Wellentabelle zu gehen, obwohl nur
> Integer-Werte möglich sind, wird stattdessen gelegentlich ein
> zusätzlicher Schritt eingefügt.
Korrektur: ... gelegentlich die Schrittweite vergrößert!

Könnte mir jemand sagen, in welchem Format die Melodie gespeichert ist 
und wie das Abspiel-Timing funktioniert?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmals ein interessantes, überschaubares und gut strukturiertes 
Projekt zum Thema Musik und Töne...

http://www.microsyl.com/doorbell/doorbell.html

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, er benutzt ja auch DDS.

Welche Rolle spielt bloß bei Chan der kontinuierlich erhöhte 2. Wert aus 
einem Datensatz der score-tabelle? Ich nehme an, dass der erste die 
Tondauer bestimmt.

Autor: Jochen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quatsch! -> Beitrag "Sequencer Prinzip ELM - Wavetable Melody Generator (ASM)"

Microsyl verwendet anscheinend nur ganzzahlige Schrittweiten ohne 
Korrektur.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.