PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Töne/Musik durch D/A-Wandler?



Killer
29.12.2007, 23:41
Tja, meine Fragen häufen sich :-b

Also wo ich eure Einschätzung brauche ist, ob es erstmal generell möglich ist mit einem D/A-Wandler Töne oder sogar Musik zu erzeugen?
Wenn das gehen würde, bekäme man mit einem 8Bit Wandler schon etwas hin, was sich hören lassen würde und nicht unerträglich klingt, da es "immerhin" 255 Tonstufen wären oder wäre gleich ein 16Bit Wandler besser?

MfG Killer

deSilva
29.12.2007, 23:56
Ich arbeite zwar mit etwas leistungsfähigeren Controllern, aber auch die AVRs sollten mit PWM (oder besser nich mit PDM) einen Tiefpass zum "klingen" bringen können :-) Vergiss R-2R Netze oder integrierte Chips...

Eine 8-Bit WAV Datei ist genauso aufgebaut, dass Du die (8-bit) Wert für die Pulslänge der PWM verwenden kannst. Die Periode wird so bemessen, dass alles noch rein passt; sollte natürlich schon wenigstens 11kHz sein. Der Tiefpass stellt ein gewisses Problem dar, weil Du den Träger abschneiden musst. Ein Filter 2. Ordnung sollte es aber tun.

Sehr viel robuster verhält sich da PDM, wo du eine feste Pulslänge hast und die Periode veränderst.

Grundsätzlich geht es also darum, einen Kondensator aufzuladen, sodass an ihm die gewünschte Amplitude als Spannung abgreifbar ist.

radbruch
29.12.2007, 23:59
Hallo killer

Für Töne oder Musik brauchst du nicht unbedingt einen AD-Wandler. Ein normaler Port reicht vollkommen. Der Lautsprecher verschleift das Rechteck der ausgebenen Signale sowieso. Hier ein Beispiel mit dem asuro, als "Lautsprecher" werden dabei die Motoren verwendet:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=32782

Das muss auch nicht zwingend mit PWM gemacht werden...

Gruß

mic

deSilva
30.12.2007, 00:10
Das muss auch nicht zwingend mit PWM gemacht werden...
Das IST PWM und ein Lautsprecher IST ein Tiefpass....
Man sollte das Ganze eben nur etwas kontrollierter machen :-)

Killer
30.12.2007, 00:17
Meine Vorstellung war, dass ich per A/D-Wandler des AVRs ein richtiges Lied z.B. vom PC aus aufnehme (bzw. ein (sehr) kleines Stück) und die Werte die ich erhalte erstmal ins Ram lege und dannach abspielen will und das ganze soll beim abspielen über den AVR einigermaßen klingen!! Ist dieses Vorhaben mit einem Mega8 (16MHz) zu bewältigen?

MfG Killer

radbruch
30.12.2007, 00:35
Hallo

Ich meinte oben natürlich einen D/A-Wandler zur Ausgabe.

Aufnehmen und Abspielen kann man auch nur mit einem normalen digitalen Port. Das funktionierte früher beim c64/zx81/spectrum/schneider mit Datasette auch recht gut. Ich hatte mal für meinen SchneiderCPC (Computer-Steinzeit) ein Progrämmchen geschrieben das komplette Songs von einem Cassettenrecorder über einen Pin eingelesen und gespeichert hat. Vielleicht kann ich das Wiederbeleben. Das ist ein Projekt, dass ich schon lange mal mit einem AVR umsetzen wollte. Mal schauen, ob ich das nochmal hinbekomme. Bestimmt kennt google eine Lösung...

Gruß

mic

mx3
30.12.2007, 10:02
Hallo killer!

Schau dir mal diese Seite an
www.karlsaam.de/karlsaam_cms/node/37

WAV Dateien mit dem AVR abspielen.
Hat das vieleicht schon mal wer ausprobiert?

Hab mal ein paar WAV's umgewandelt aber in den Mega 8 geht
nicht viel rein(zu wenig Speicher),außer ein paar Töne.

mfg,MX3

robocat
30.12.2007, 10:22
der DAC sieht seltsam aus. sicherlich kommen irgendwelche geräusche aus dem lautsprecher, aber ich kenne die eher so wie hier:
http://www.elby-designs.com/avrsynth/documents/avrsyn-dac.pdf (übrigens gefunden auf http://www.elby-designs.com/avrsynth/avrsyn-about.htm)

gruesse

shaun
30.12.2007, 11:13
Naja, "Dein" DAC ist eine R-2R-Konfiguration, der vorgenannte besteht aus gewichteten Widerständen. Mäßig linear, weil die Gewichtung zwischen den Stufen etwas weit von 1:2 entfernt ist, aber für die Anwendung wird's wohl reichen. Mir wäre es mit Verstärkerstufe auch lieber, 20R gegen Masse ist etwas heftig für den armen AVR.

Besserwessi
30.12.2007, 12:19
Der PWM Ausgang mit filter dahinter sollte schon reichen für die Tonausgabe. Mehr als 8 Bit machen auch nicht so richtig viel Sinn, denn der speicher ist ohnehin schon knapp, wenn man Samples wiedergeben will. Für längere Melodien müßte man einen externen Speicher (z.B. SD Karte oder Data-flash) anschließen oder halt einen einfachen MIDI Player (oder was ähnliches) programmieren.

wawa
30.12.2007, 12:47
@killer

zurueck zur ersten Frage: natuerlich
ein sehr einfacher Weg ist die Toene selbst als Noten abzulegen und den Takt dazu. Das ist sehr sparsam. Du must dann aber jeden Ton erzeugen, mit genuegend Abtaststellen, das verringert das Rauschen. Wichtig bei all diesen Vorgaengen ist die Mathematik. Du brauchst mindestens die doppelte Wiedergabefrequenz deiner hoechsten wiederzugebenden Frequenz. In diesem hatten einige Vorgaenger recht, wenn man digital ausgibt, muss man sich an das vorliegende Format halten. Wenn sehr hoch abgetastet wird - must du auch mit dieser Rate die Werte ausgeben. Macht aber das Filter dahinter sehr viel kleiner und einfacher.
Ich hoffe das hilft. Probier einfach mal einen Ton auszugeben mit 4 und dann mit 8 Stuetzstellen, ohne Filter. Du wirst es hoeren.
Du brauchst NUR den Sinus zu rechnen. Vorsicht aber bei dem DAC, wenn er nur positive Spannung erzeugt, musst du einen Offset dazurechnen und mit einem genuegend grossen C auskoppeln.

Killer
30.12.2007, 13:12
Angenommen ich würde mit dem AVR eine winzige Liedstelle aufnehmen und dann per PWM wiedergeben (alles 8Bit und andere Hürden aussen vor), klänge das Wiedergegebene noch nach dem eingespeistem Lied oder nach "rumgepipse"?

MfG Killer

radbruch
30.12.2007, 13:48
Hallo

http://img.youtube.com/vi/Yw3iHIym58k/2.jpg (http://www.youtube.com/watch?v=Yw3iHIym58k)
http://www.youtube.com/watch?v=Yw3iHIym58k

Die Hardware:

- Aktivlautsprecherboxen mit PC oder MP3-Player
- PC-Speaker aus einem alten PC (8Ohm)
- Chinch-Servo-Adapter
- Servo-XBus-Adapter
- ein RP6 mit 8MHz-ATMega32

Die Software:


// RP6 als Tonband 1.Versuch 30.12.2007 mic

#include "RP6RobotBaseLib.h"

int main(void)
{
initRobotBase();
extIntOFF();
DDRC |= 1;

cli();

while(1)
{
if (PINA & E_INT1)
{
setLEDs(1);
PORTC |= 1;
}
else
{
setLEDs(0);
PORTC &= ~1;
}
}

return(0);
}

Das analoge Lautsprechersignal liegt an PortA.4, der Speaker an PortC.0. Was an PA4 erkannt wird, wird direkt an PC0 wieder ausgegeben und zur Kontrolle an der LED angezeigt. Lautstärke wird langsam aufgedreht bis die LED flackert und der Speaker piept. Fehlt noch das Speichern und die Wiedergabe.

Gruß

mic

oberallgeier
30.12.2007, 13:57
Also ich wollte immer schon mal ein lustiges Pfeiffen aus dem µC bringen. Ok, ok, der Tiefpass war noch nie richtig ausgelegt und der Piezo ist auch nicht wirklich geeignet. Aber was denkt Ihr - hab ich da überhaupt ne Chance. Ich denk an Töne wie beim R2D2 - oder beim Wasserkocher mit Pfeiffe :)

Killer
30.12.2007, 14:26
Für solche kleinen Töne gibt es ja beispielsweise unter Bascom einen Befehl wie "Sound" wodurch man an jedem beliebigen I/O Pin einen Ton bzw. Piepsen erzeugen kann.

MfG Killer

Besserwessi
30.12.2007, 14:38
Solange die Töne ungefähr gleich laut sind macht das mit den 8 Bit keine Probleme. Ein piepsiger Ton kommt eher durch einen kleinen Lautprecher, nicht durch 8 Bit daten. Es könnten eventuell die Höhen fehlen, weil man die Abtastrate nicht so hoch wählen will. Das wird am ehesten mit dem Telefon vergleichbar. Zum Ausprobieren kann man ja man am PC mit den Datenformaten (8 Bit Wav) spielen. Das wird vom AVR auch nicht schlechter klingen, wenn die Lautsprecher stimmen.

oberallgeier
30.12.2007, 16:04
Für solche kleinen Töne ... Bascom einen Befehl ...Ach je, schade, ich spreche nur Assembler und C (und C noch dazu recht schlecht [-o< )

Killer
30.12.2007, 16:15
Dann teste ih es demnächst mal.
Habe ich es bezüglich dem PWM Signal richtig verstanden, dass beide Signalleitungen (in diesem Fall für den Lautsprecher + und - ) vom µC ausgehen?

MfG Killer

radbruch
30.12.2007, 20:46
Hallo

Auch wenn das Interesse eher gering ist, habe es noch weiter versucht. Hier nun eine Lösung ohne ADC und ohne PWM. Es ist blechern und kurz, aber mit etwas Phantasie kann man es erkennen:
http://img.youtube.com/vi/-XpAL3PlMAw/3.jpg (http://www.youtube.com/watch?v=-XpAL3PlMAw)
http://www.youtube.com/watch?v=-XpAL3PlMAw

Das unkomfortable Progamm (888Bytes) löscht nach dem Start den Speicher, liest die Daten ein bis der Speicher voll ist und spielt dann endlos:

// RP6 als Tonband mit Aufnehmen und Abspielen 30.12.2007 mic

#include "rblib.h" // bindet u.a io.h und stdlib.h ein
#include "rblib.c" // und dient vorrangig dem Debuggen
#define speichergroesse 1536 // der Mega32 hat nur 2kb sram

int main(void)
{
uint8_t speicher[speichergroesse], temp, bit_nr; // Speicherplatz bereitstellen
uint16_t byte_nr, i, dummy; // und ein paar Hilfsvariablen

rblib_init(); // ein paar Initialisierungen
setMotorPWM(0,0); // PWM=0 sperrt den Interrupt
PORTA &= ~(1 << PINA4); // PINA4 liest die Daten ein
DDRA &= ~(1 << PINA4);
DDRC |= (1 << PINC0); // an PINC0 hängt der Speaker
byte_nr=0; // Zähler für die Bytes
bit_nr=8; // Zähler für die Bits
for(i=0;i<speichergroesse;i++) speicher[i]=0; // Speicher löschen
while(0) // Zum Einstellen des Pegels
{ // wird nicht verwendet
if (PINA & (1 << PINA4))
{
setLEDs(1);
PORTC |= (1 << PINC0);
}
else
{
setLEDs(0);
PORTC &= ~(1 << PINC0);
}
for(i=0;i<150;i++) dummy+=i;
}

cli(); // Keine Störung zulassen, wir lesen ein
do // Schleife der Datenbytes
{
do // Schleife der Bits
{
if (PINA & (1 << PINA4)) // Pegel als High erkannt?
{
setLEDs(1); // Ja, LED an
PORTC |= (1 << PINC0); // Speaker an
speicher[byte_nr] += 1; // und Bit0 im Datenbyte setzen
}
else
{
setLEDs(0); // Nein, LED aus
PORTC &= ~(1 << PINC0); // Speaker aus
speicher[byte_nr] += 0; // für's Timing Bit0 nicht setzen
}
speicher[byte_nr] *= 2; // Speicherbyte nach links shiften
for(i=0;i<300;i++) dummy+=i; // kurze Verzögerung, wir samplen mit 8MHz!
}
while(--bit_nr); // nächstes Bit einlesen
bit_nr=8; // acht Bit komplett
}
while(byte_nr++ < speichergroesse); // nächstes Byte bis Speicher voll
sei(); // eigentlich nicht nötig

while(1) // und nun endlos abspielen
{
byte_nr=0; // erstes Byte
bit_nr=8; // jeweils 8 Bits
cli(); // wieder keine Störungen zulassen
do // Schleife der Bytes
{
temp = speicher[byte_nr]; // Byte zwischenspeichern
do // Schleife der Bits
{
if (temp > 127) // Bit 7 gesetzt?
{
setLEDs(1); // Ja, LED an
PORTC |= (1 << PINC0); // Speaker an
}
else
{
setLEDs(0); // Nein, LED aus
PORTC &= ~(1 << PINC0); // Speaker aus
}
temp *= 2; // Byte nach links shiften
for(i=0;i<300;i++) dummy+=i; // wieder kurz warten (speichern fehlt!)
}
while(--bit_nr); // nächstes Bit
bit_nr=8; // acht Bits fertig
}
while(byte_nr++ < speichergroesse); // nächstes Byte bis Speicherende
sei();
}
return(0); // das war's. Einfach und blechern
}

Leider hat der Mega32 nur 2kb SRam, vielleicht geht's auch mit dem Flash...

Gruß

mic

robocat
30.12.2007, 22:18
hi radbruch,
da hast du mal wieder was umgesetzt, während noch diskutiert wird, ob es umsetzbar ist ;)
ich bin sicher, deine grundlagenforschung wird noch gewürdigt werden, und dein code verwendung finden. könntest du mal ein bisschen sprache "samplen"? wäre sicher interessant, wie das klingt.

gruesse

EDIT:
an shaun hätte ich noch fragen: beeinflusst der lautsprecher den gewichteten DAC nicht? und fliesst der strom nicht teilweise über den 12ohm widerstand wieder über den µC, wenn dessen pin low ist?

EDIT2 @ oberallgeier: wie ein teekessel oder so wie r2d2 wird es anfangs nicht pfeifen können, aber wenn du ein rechtecksignal mit verschiedenen frequenzen über einen vorwiderstand (oder ideal mit einem transistor als verstärker.. oder noch idealer mit einem kleinen audio verstärker wie dem tba820) an einen lautsprecher gibst, sollte immerhin schon etwas zu hören sein. das hier http://www.elby-designs.com/avrsynth/8535-3.wav klingt ja schon ganz ordentlich für einen avr.

deSilva
30.12.2007, 23:08
Was SCHAUN da ausgegraben hat ist eine Strom DAC, die impedanzmäßig an die 8 Ohm des Lautsprechers angepasst wurde. Klar ist das nicht besonders sauber,eine Spule ist schon etwas komplizierter :-) Die Nichtlinearitäten sind aber absolut unwesentlich.

RADBRUCH hat einen 1-Bit ADC und einen 1-Bit ADC verwendet, d.h. das Signal wird sozusagen gnadenlos übersteuert.

Eine ganz einfache Verbesserung ist ein Delta-Sigma Modulator (2 Kondensatoren, 2 Widerstände ) und die PDM Ausgabe über einen Tiefpass...

Die Abtastrate steigt dann natürlich stark an. Ich weiß nicht, wie viel ein ATmega da leisten kann.. Bei 8 Bit Auflösung @ 10kHz Abtastrate müsste der Feedback-Ausgang mit etwa 2MHz versorgt werden... sonst sollte man auf 4 Bit gehen, das ist auch ganz ausreichend (und Platz sparend). Immerhin immer noch 5k Bytes/ Sekunde.

Es empfielt sich dann doch eher eine "synthetische" Ausgabe ala MOOG Synthesizer :-)

shaun
31.12.2007, 10:19
Ich hab das Ding nicht ausgegraben, ich habe es nur kommentiert. Natürlich wird der D/A durch die LS-Impedanz beeinflusst, aber das ist ja berücksichtigt, zumindest im Reellen, und auch da nur ansatzweise. Eigentlich hätten die Widerstände 12R, 32R, 72R usw. sein müssen, damit bei angenommener gleicher Spannung an den Ports mit jedem abnehmenden Bit jeweils der halbe Strom des vorigen durch Widerstand+LS-Spule fliesst. Passt aber nicht, weil die Spannung über dem LS natürlich nicht konstant ist und die LS-Impedanz alles andere als reell ist.
Dass Strom in die Ausgänge zurückfliesst kann je nach Schaltung gewollt sein oder man stellt es dadurch ab, dass man den PORTx.n immer 1 lässt und mit DDRx.n schaltet (wenn der Pullup nicht stört)

oberallgeier
31.12.2007, 12:59
Hallo, deSilva,


... Es empfielt sich dann doch eher eine "synthetische" Ausgabe ala MOOG Synthesizer :-)... ich hab in Wikipedia nachgeguckt (als Verfahrenstechniker versteh ich nur einzelne, minimalste Grundlagen von Audio) - da gabs von Moog nur Keyboards mit Elektronik - unter Sengspiel (http://www.sengpielaudio.com/) habe ich auch nix Passendes gefunden, obwohl der ja SEHR viel veröffentlicht...

Könntest Du bitte einen Hinweis geben, wo man/ich Näheres zu diesem Synthesizer finde(t) ?

Danke - und einen guten Rutsch

robocat
31.12.2007, 15:05
hier http://de.wikipedia.org/wiki/Moog-Synthesizer steht bissl was, aber das hier http://www.till.com/articles/moog/patents.html dürfte interessanter sein.

gruesse

EDIT: danke an shaun für die erklärung zu dem "einfachen" DAC. wieder was dazugelernt.

hunni
31.03.2008, 16:55
Hallo Leute,
wisst ihr das was da gerade eben einer gesacht hat, mit dem SchneiderCPC Computer. So könnte man ganz einfach Programme auf Kassette speichern. Dann hat man nicht mehr das Probmlem mit dem FlashRom oder mit den UAfeichnen von Programmen. Ich habe hier immer noch einen C64 Zuhause stehen und der macht das genauso.( ich bin totaler C64 Fan auch wenn ich erst 15 Jahre alt bin). Wenn man gut ist, könnten wir uns sogar ein eigenes Roboternetz aufbauen, ich meine über Telefon (damals mit Akkustikkoppler und Modem). Dann könnten wir ein großes Netz aufbauen und wir regieren die Welt :lol: :lol: :lol: .
Ach bin ich heute wieder Kreativ. Aber jetzt mal wieder auf den Boen der Tatsachen. Ich könnte mir vorstellen soetwas zu proggen, muss mich aber erst reinfinde und gucken, wie das der C64 macht.
Hunni ](*,)