Forum: Projekte & Code AVR Synthesizer mit ATxmega128A1


von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Ihr Lieben..

Ich entwickel zur Zeit einen Synthesizer auf Basis eines ATxmega128A1
Prozessors. Falls euch mein Projekt interessiert schaut mal unter
http://www.cczwei-forum.de/cc2/thread.php?threadid=5878 vorbei. Da gibts
jede Menge an Informationen Rund um die Musikelektronik und auch
Programmier-Tips in C, um einen eigenen Synthesizer zu bauen.



Viel Spaß beim stöbern wünscht euch Rolf

: Verschoben durch Admin
von Rene B. (themason) Benutzerseite


Lesenswert?

Hallo Rolf,

erstmal möchte ich bekunden das du sehr schöne Erklärungen auf der CC2 
Seite zu dem Thema gemacht hast. Die anderen Links sind auch sehr 
schick. Find das immer wieder erstaunlich was man klangtechnisch aus nem 
AVR holen kann. Dafür das das "nur" nen popeliger 8-bitter ist :-)
Werd deinen Beitrag weiterhin verfolgen und bin mal gespannt was du aus 
dem Xmega rauskitzeln kannst. Ich selbst bin bei meinem Synthesizer 
(schau mal hier im Forum unter Audio-DSP mit Spartan 3) einen anderen 
weg gegangen. Da mache ich die Klangerzeugung/Bearbeitung/Filterung in 
einem FPGA, und gesteuert wird das ganze von einem AVR. In dem Artikel 
sind auch noch Links zu You-Tube Videos. Das ganze ist allerdings schon 
was länger existent und liegt momentan auch was rum. Aber evtl 
überarbeite ich den Synth mal mit einem neueren Spartan. Insgesamt hat 
man mit der Platform (wenn sie mal fertig bzw dokumentiert wäre) recht 
viele Möglichkeiten, da ich von vornherein auf der Verarbeitungsebene 
modular bin.

Weiterhin viel Spaß beim Synth-DIYing :-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Ich habe jetzt die ersten Sounds von meinem Synthi ins Netz gestellt. 
Kann man sich auf SoundCload unter 
http://soundcloud.com/rolfdegen/sets/testsounds-avr-synthesizer/ 
anhören. Die Sound sind zwar nix Besonderes, weil der Synthi zur Zeit 
nur ein Oszillator und ein Hüllkurvengenerator besitzt. Aber ich bin 
gerade dabei, das ganze auf drei Oszilatoren und 3 Hüllkurvengeneratoren 
auszubauen.

In Bezug auf dein Audio-Projekt: Ich habe mir schon vor längerer Zeit 
dein "Audio-DSP mit Spartan 3"  hier auf mikrocontroller.net angesehen 
bzw angehört und bin von der Soundqualität einfach begeistert. Ist schon 
eine ganz andere Liga :)

Ich habe mir jetzt bei Watterott ein STM32F4 Discovery Board bestellt 
und bin schon gespannt was das Bord im Audiobereich so alles kann. Die 
Eckdaten sind vielversprechend zB. 168MHz CPU-Takt, 1 MB Flash, 192 KB 
RAM, FPU und 24Bit DA-Wandler Chip onBoard. Werde das Board ausführlich 
testen und vielleicht wird ja ein Wave-2 daraus werden. Schaun wir mal..

Gruß Rolf

von Maik M. (myco)


Lesenswert?

Hallo Synthbastler :)

Ich habe mir auch schon einen Synth mit einem AVR gebastelt, allerdings 
habe ich dann sehr bald aufgegeben weil mir der Sound nicht gefallen 
hat. Ich bin halt besseres gewohnt, da ich aus der VST-DSP Ecke komme.

Habe mir dann mal ein paar Dev-Boards für schnellere Controller gesucht 
(PIC32, dsPIC, AVR32...), allerdings bin ich da nicht sonderlich weit 
gekommen. Der dsPIC ist recht simpel und billig, und man kommt schnell 
zum DSP-Teil des Projekts, allerings ist er nicht sonderlich schnell. 
AVR32 ist irgendwie sehr kompliziert, dafür ist er einigermaßen schnell. 
Gleiches gilt für den PIC32.

Rene´s Projekt find ich recht interessant, und ich hatte schon lange vor 
mal mit FPGAs zu arbeiten, weil damit geht man den Großteil der 
Geschwindigkeits-Probleme aus dem Weg.

Jetzt habe ich wieder etwas mehr Zeit, und wollte das mal angehen. Habe 
mich schon etwas informiert, und nach Dev-Boards umgesehen. Evtl. werde 
ich mir ein CycloneII-Board holen, ist zwar nicht mehr der aktuellste, 
aber das Board hat alles drauf was ich brauche, und eine 
Synthesizer-Demo wird gleich mitgeliefert. Das einzige was mir da noch 
etwas Sorgen macht ist: bei der freien Version von Quartus steht 
"Windows 32bit only", und meine 32-bit Kisten habe ich alle ausgemustert 
:)

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Also die Sounds klingen schon recht witzig. Old-School-8-Bit-Style :-)
Bin mal gespannt auf weitere Demos. Wie willst das denn mit den Filtern 
machen ? Analoge Filter die digital gesteuert werden ? Oder direkt 
digitale Filter ?

Und danke noch für das Lob :-))

@Maik

was würde denn gegen Xilinx sprechen ?
Also den Spartan 6 zu routen war sehr angenehm. Mein (noch nicht 
phsyisch vorhandenes, aber schon teilgeroutetes Test-Board) schaut schon 
ganz gut aus und hat neben nem Codec, nem AVR noch 16MB SDRAM an dem 
FPGA angeklebt bekommen. Aus dem Teil ne Platform zu machen ist 
mittlerweile nen Klacks.
Würde das Audio-Projekt ja gerne nochmal reaktiveren (fürs Forum) aber 
bei der "alten" Version war die Resonanz schon nicht so groß. Wobei das 
Board als solches vllt noch für den einen oder anderen Interessant sein 
könnte. Ist auch "relativ" einfach zu Löten (144'er QFP und 0603 SMD auf 
ner doppelseitigen Platine). Na ja .. mal schauen. Vllt starte ich das 
Projekt erneut.

von Rolf D. (rolfdegen)


Lesenswert?

Rene B. schrieb:
> Also die Sounds klingen schon recht witzig. Old-School-8-Bit-Style :-)

Hallo Rene. Wenn schon.. denn schon. Es sind 12Bit Sounds :) Gerechnet 
wird intern mit 16Bit und das Ergebnis wird dann für den Xmega-DAC auf 
12Bit reduziert.

Eine Filtertechnik habe ich im Moment noch nicht integriert. Es läuft 
aber mit Sicherheit auf analoge Filter-Bausteine hinaus, weil der Xmega 
einfach zu wenig Rechengeschwindigkeit besitzt. Der ist schon voll mit 
der Soundausgabe, Hüllkurve, Midi und Grafischen Touch-Display 
beschäftigt, da bleibt keine Zeit mehr für eine Filterberechnungen. 
Allerdings weis ich noch nicht, was ich für Filter-Chips nehmen soll. 
Hatte Anfang der 90er Jahre mit dem Bau meines 1.Synthesizers von der 
Firma Doepfer (http://www.doepfer.de/home_d.htm) begonnen und dafür ein 
paar Curtis IC bestellt. Aber ich war "jung" und habe den Synthi nie 
fertig gebaut. Und nach den vielen Umzügen sind die Bauteile einfach 
verschwunden.

Hallo Maik. Ich habe mir die Beschreibung des Cyclone II Board mal 
angesehen. Kann man sich hier herunterladen: 
http://www.altera.com/products/devkits/altera/kit-cyc2-2C20N.html#note2
Das Board ist ja ganz schön groß und teuer im Verhältnis zum STM32F4 
Discovery Board, hat aber alles was man so brauch für einen Synthi. Für 
den Anfang bleibe ich erst einmal bei einem kleinen und preisgünstigen 
Board um damit Erfahrungen zu sammeln. Später trau ich mich dann an die 
größeren Boards wzB das EVK1104 evaluation Board von Atmel: 
http://www.atmel.com/tools/EVK1104.aspx und als Entwicklungs-Tool AVR 
Studio das ich jetzt schon für den Xmega benutze.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf und Maik

was vllt auch noch als Platform sehr interessant wäre ist der Raspberry 
PI. Der hat ja nen 700MHz ARM am werkeln. Das sollte für digitale 
Synthies dicke reichen. Jedenfalls werd ich mich mit der Platform 
auchmal auseinandersetzen, selbst wenns eben nichts zum nachbauen ist.

@Rolf

Die Curtis-Chips hätte ich gerne mal in den Fingern. Aber die sind so 
schwer zu bekommen. Ich glaube da würd ich eher ein diskretes Design 
(State-variable-Filter, oder den klassischen Moog-Filter) nehmen.
Hab damals auch mal nen "klassischen" Filter analog aufgebaut. Aber das 
ganze ist dann irgendwann liegen geblieben.
Würde gerne aber bei meinem Audio-Projekt noch analoge Filter 
integrieren und mit jeweils nem eigenen Codec versehen. Dann hätte ich 
die Möglichkeit Signale zu mischen und beliebig zu routen (und eben auch 
durch den Filter). Wäre für nen Mischpult mit Effektgerät ganz nützlich, 
oder eben für nen Synthie (selbst wenn der dann nur max x-stimmig werden 
kann wobei x dann die Anzahl analoger Filter ist).
Aber reizvoll sind analoge Synthies allemale. Egal ob mit oder ohne 
digitale Komponenten.

von Rolf D. (rolfdegen)


Lesenswert?

Das "RasPi"-Board hat leider keinen eigenen DA-Wandler onBoard. Der 
Sound wird per PWM im Prozessor erzeugt und über einen einfachen 
RC-Filter nach außen geführt. Hier ist der Schaltplan: 
http://www.raspberrypi.org/wp-content/uploads/2012/04/Raspberry-Pi-Schematics-R1.0.pdf

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Na und ?

Der hat doch USB-Schnittstellen. Und ne Soundkarte ist doch schnell da 
dran gekorkt :-)
Wobei es mich mal interessieren würde wie schwer bzw unmöglich es ist 
bzw wäre das Board ohne Linux zu betreiben. Also quasi die gesamte 
Rechenleistung mit allem drum und dran für sich ganz alleine zu haben 
:-)
Und ich denke von den Schnittstellen her ist es bestimmt möglich auch 
nen guten Wandler noch dranzuflanschen. Notfalls per FPGA-Daughter Board 
:-)

von Rolf D. (rolfdegen)


Lesenswert?

Hinweis zum "Raspberry Pi". Der Erik Bartmann ist gerade dabei, ein Buch 
über den RasPi mit dem Titel "Raspberry Pi für Frühaufsteher" zu 
schreiben.

CC2-Link: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76123#post76123

Gruß Rolf

von Maik M. (myco)


Lesenswert?

@Rolf: Ja das Board ist recht teuer im Vergleich zu den 
Controller-Dev-Boards. Das relativiert sich aber in dem Moment, wo man 
es mit anderen FPGA-Dev-Boards vergleicht. Auch kostet der FPGA auf dem 
Board alleine schon mehr als 50 Euro :)

Ich habe das EVK1105, ansich ist das nicht schlecht, nur hat das einen 
PCB-Fehler, was es extrem schwer macht das Teil zu programmieren. Und 
DFU wird in Atmel Studio 6 nicht mehr unterstützt, deswegen benötigt man 
ab da auch noch einen JTAG-Programmer.

@Rene: Ich habe mir ein paar Xilinx-Boards angeschaut, das günstigste 
mit Codec was ich gefunden habe ist das Digilent Atlys, was aber schon 
doppelt soviel kostet wie das CycloneII

Dein eigenes Layout ware natürlich optimal, weil das quasi das nötigste 
enthält. Ich würde gern eins nehmen, allerdings benötige ich es fertig 
aufgebaut. Da ich am Anfang meine "Lötfehler" als "mögliche 
Fehlerquelle" ausschließen möchte.

Das Pi kommt für mich nicht in Frage. Mein Ziel ist es ein 
Synthesizer/Effektgerät zu bauen, dh. später möchte ich eine eigene 
Platine fertigen können.

von Sam .. (sam1994)


Lesenswert?

Auf einem AVR ist schon einiges möglich - C, viele Kanäle und komplexe 
Sounds passen da aber nicht mehr zusammen. Das größte Problem ist die 
Rechenleistung für die vielen Kanäle. Wenn man 8 Kanäle realisieren 
möchte hat man bei 44100 Hz @32Mhz

32Mhz : 44100 : 8 = 90 Takte pro Kanal Zeit.

In meinem Synthesizerprojekt konnte ich die Takte/Kanal auf ~15 
reduzieren, dafür waren keine komplexen Sounds mehr möglich.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Samuel

Hast du mal nen Link zu deinem Projekt ?
Würd mich mal interessieren. Im Prinzip ist mit den AVRs ja 
soundtechnisch schon einiges machbar wenn man Kompromisse bei der 
Samplingrate macht.
Aber Filter-Operationen sind halt bei der begrenzten Rechenleistung 
schwierig. Oder sehr Tricky :-)

von Sam .. (sam1994)


Lesenswert?

http://www.mikrocontroller.net/articles/AVR-Synthesizer
1
  add freqcnt1, hrfreq1      ;16-bit Zähler
2
  adc freqcnt2, hrfreq2
3
  brcs 1f
4
4:
5
  ;Tonerzeugung
6
  ;Im Register ueber freqcnt2 liegt der Index zur richtigen Soundtabelle  
7
  movw ZL, freqcnt2 
8
  lpm temp, Z
9
10
  ;Lautstärke
11
  mulsu temp, volsum1
12
13
        ;mischen
14
  add sample, 0
15
  adc sample2, 1

Ich habe die Hauptroutine nochmal herausgekramt:
Für einen Kanal sind es hier 11 Takte, allerdings kommt noch ein 
bisschen dazu für Register laden etc.
Wenn man so viel optimiert wird irgendwann der Ram zum Flaschenhals mit 
2 Zyklen pro Zugriff. Also werden alle Daten von bis zu drei Kanälen 
geladen und die nächsten 64 Samples werden berechnet.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo zusammen

Zufällig habe ich auf einer japanischen Website ein interessante FM 
Sound Programm für das ST32F4 Discovery Board entdeckt. So wie es 
verstanden habe (mein Japanisch ist nicht besonders gut :), ist das 
Soundmodul 16stimmig polyphon, Samplingrate 48KHz und Midi fähig. Ich 
habe die Firmware über ST-Link Utility direkt mal ins Discovery geflasht 
. Nach dem Reset läuft sofort eine Sounddemo ab. Klingt nicht schlecht 
wenn ihr mich fragt..

Link: http://d.hatena.ne.jp/pcm1723/20120418/1334746384
Download: http://www.geocities.jp/pcm1723/html2/download.htm

MfG Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Hast du vllt mal das Sound-Demo als MP3 oder nen Link wo man sich dieses 
Demo anhören kann ?
Ich hab leider keinen STM zur Hand um das mal ausprobieren zu können. 
Würde mich aber dennoch mal interessieren wie das klingt. FM-Synthese 
ist ja klanglich schon recht mächtig bzw bietet viele Möglichkeiten. Vor 
allem wenn man FM-Synthese als Klangquelle nutzt und mit einem 
nachgeschalteten analogen oder digitalen Filter "verfeinert" :-)
Das ist auch eins der Dinge die ich meinem Audio-Projekt gerne noch 
beibringen würde. Aber bisher hab ich mich mit der FM noch nicht weiter 
beschäftigt (also das ich das aufm PC mal "durchrechne" und einfach mal 
was rumspielen kann). Von daher danke schonmal für die Links. Vllt kann 
ich mir da was für aufn PC mal selbststricken.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Ich werde die Demo Heute in soundcloud.com bereitstellen und dich hier 
informieren. Ferner versuch ich Heute einen Optokopler an das Discovery 
Board "anzukleben", um  die Demosounds anzuspielen. Mal schaun obs 
funktioniert..

Hab noch eine interessante Projekt-Seite im INet gefunden. Nennt sich 
"Jo-Midi-FM". Ist eine japanische Website. Mit Google-Translate in 
Deutsch kann man es uebersetzen lassen.

Link: http://www.geocities.jp/pcm1723/

MfG Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Rene

Im Anhang findest du eine c.File aus dem FM Sound Projekt fuer das 
Discovery Board. Vielleicht hilft es dir.

Gruss Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo zusammen..

Ich habe an das Discovery-Board jetzt einen Midi-Anschluss gelötet, 
damit ich die Demo Sound des FM Sound Generator über ein Midi-Keyboard 
abspielen kann.

Schaltplan gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76348#post76348

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Ich habe den Demo-Sound des STM32F4 Discovery Boards mal ins Netz 
gestellt. Kann man sich als MP3 hier auf soundcloud.com anhören oder 
downloaden: http://soundcloud.com/rolfdegen/st32mf4-demo-02

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Hallo Rolf,

erstmal danke für das Demo. Hört sich ja recht schnuckelig an. (Hatte 
mir schon irgendwie gedacht das das so sanft und soft klingt, irgendwie 
haben die Japaner glaub ich einen Faible dafür :-))
Aber klingt sehr sauber das ganze. Ich glaub ich werd mich auch mal mit 
FM Synthese beschäftigen. Vllt bringe ich meinem FPGA sowas auch noch 
bei :-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Naja.. Im Vergleich zu den Demo-Sound von deinem Spartan3 Board klingen 
die Sounds das Discovery sehr bescheiden.

Ich habe noch ein MP3-File mit einzelnen Klängen vom Discovery Board 
erzeugt und auf soundcloud.com hochgeladen. Hier der Link: 
http://soundcloud.com/rolfdegen/st32mf4-demo-03

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Ich werde jetzt erst einmal weiter an meinem 12Bit AVR-Synthi basteln 
und ein GUI mit einem Tochdisplay integrieren. Die Programmierung mit 
dem AVR ist auf jeden Fall leichter und unkomplizierter im Vergleich zum 
Cortex M4 Prozessor.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Na ja ... aber im Endeffekt ist es nur ne Frage der Software. Das was in 
meinem Audio-Projekt abläuft lässt sich mit recht wenig aufwand 
sicherlich auch auf nem Discovery Board laufen lassen.
Die Filter die ich verwende sind ganz normale IIR-Biquads. Und die 
Berechnung der Koeffizienten erfolgt in einem AVR :-) Also alles im 
Prinzip kein Hexenwerk. Daher fänd ich das ja so interessant die FM mal 
so aufzuschnibbeln das ich das mit in meinem Synth reinbekäme :-)

von Rene B. (themason) Benutzerseite


Lesenswert?

Hab mir gerade mal die Sounds angehört. Sehr schöne Demos. Ideal als 
Oszillator. Dahinter noch nen schönen Resonanzfilter mit Hüllkurve und 
LFOs ... Yammy :-)

von Rolf D. (rolfdegen)


Lesenswert?

Der Hall bzw. die Echos in den Sounds kommen auch vom Discovery. Ich 
habe die Sounds über den Line-Out vom Discovery übers Mischpult und ohne 
Effekte aufgenommen.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Ach ja ... der Hall in dem Demo. Wäre auch mal ein Interessanter 
"Opcode" für mein Audio-Projekt. Hab dir übrigens ne PN geschickt.
Die Demos waren vom TGFM oder von dem Jo-MIDI FM ?

von Rolf D. (rolfdegen)


Lesenswert?

Von Jo-MIDI FM Version 1.2

von Maik M. (myco)


Lesenswert?

Hab jetzt mein Altera-Board, leider wurde da nur ein Ami-Netzteil 
mitgeliefert, was mir hier natürlich nicht hilft. Hab es mal an mein 
Labornetzteil gehangen, und es scheint zu gehen. Mehr kann ich da aber 
nicht machen, weil ich in meiner Bastelecke keine Anschlussmöglichkeiten 
habe.

Der Code der mitgeliefert wird, ist in Verilog, was ein herber 
Rückschlag ist, da ich mich auf VHDL eingerichtet habe. Dennoch ist er 
recht überschaubar, und ich begreif wenigstens wie sie zum Ziel kommen. 
Es sind einige Audio-Demos dabei. Die Synthesizer-Demo nutzt 
Wavetable-Synthese (vom FPGA Ram), was auch keine Überraschung ist, da 
man damit schnell zum Ziel kommt.

Zum Thema FM: Ich habe nie verstanden, weshalb das immernoch so gefragt 
ist. Mit den Sounds kann ich irgendwie nichts anfangen. Vom techn. her, 
ist es auch nichts anderes als dass man den Ausgang eines Osc an den 
Frequenzeingang eines anderen Osc hängt.

Beim Hall wird es schon interessanter, ab einer gewissen Dichte wird 
dann auch einem M4 die Luft ausgehen. Bei meinem letzten Reverb den ich 
gebaut habe, brauchte ich alleine 74 Filter:
1 Lowpass
1 Highpass
8 Allpass
64 Comb

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Maik

Welches Altera-Board hast du genau ?

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik

FM als alleiniger Sound ist auch recht langweilig. Aber FM als 
Oszillator mit schönen "dicken" Resonanz-Filtern dahinter macht schon 
was her.
Wenn ich mir den FM7 von NI z.b. anhöre. Ok, da ist die FM-Synthese ein 
büüschen aufgebohrt, aber gerade das zeigt ja eigentlich das man mit ein 
bissl Spielerei doch noch recht brauchbare Sounds rausholen kann.
Und es ist ja auch immer eine Frage wie komplex die Anordnung ist. Mit 
zwei/drei Sinusoszillatoren gewinnt man auch keinen Blumentopf. Aber bei 
6-8 Operatoren, entsprechenden Wellenformen, Filtern und Effekten klingt 
das durchaus mehr als brauchbar.

Zum Thema selbstgebautes FPGA-Board. Falls ich mein Redesign für mein 
Board mache und Interesse besteht kann ich dir (und auch dir Rolf) auch 
gerne eins zusammenlöten und testen.

von Maik M. (myco)


Lesenswert?

Rolf Degen schrieb:
> Welches Altera-Board hast du genau ?

Der komplette Name lautet: DK-DE2-2C35N/UNIV
Es ist dieses:
http://www.altera.com/education/univ/materials/boards/de2/unv-de2-board.html

Im Prinzip tut es auch das DE1, aber ich wollte ein Board, wo ich ohne 
zu basteln alles drauf habe (LCD fehlt beim DE1). Und der Vorteil bei 
Dev-Boards ist ja, dass für alles was darauf ist, auch Demos vorhanden 
sind, und ich lerne am funktionierenden Code einfach schneller :)

Rene B. schrieb:
> Zum Thema selbstgebautes FPGA-Board. Falls ich mein Redesign für mein
> Board mache und Interesse besteht kann ich dir (und auch dir Rolf) auch
> gerne eins zusammenlöten und testen.

Ja, Interesse ist immernoch da. Ein simples FPGA-Audio Modul wäre eine 
feine Sache, sowas findet man leider nirgends (--> Marktlücke :))

von Rolf D. (rolfdegen)


Lesenswert?

Dem kann ich nur zustimmen. Hätte auch Interesse an einem Sound-Board 
von Rene. Zumal man dann auch ein Ansprechpartner bei Problemen und 
Ideen hat.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Na ja.

Ich hab damals schon nach "mitstreitern" gesucht und auch vereinzelt 
gefunden. Aber das Problem ist eben immer der Preis. Der hängt eben 
stark davon ab wieviele Leute sich finden. Zumal der "Löwenanteil" des 
Preises in erster Linie durch die Platine bestimmt wird. Ein Einzelstück 
(nur die Platine) kostet dann gerne 60-70 Euro. Bei 10 Leuten sinds dann 
nur noch ca 15 Euro (oder so).
Die restlichen Bauteile liegen dann so im Bereich 50-60 Euro.

Also ich geb mal die Eckdaten was ich mir Vorstelle an Hardware bzw was 
ich Schaltplan und Layoutmäßig schon fertig habe :

- Spartan 6 FPGA (LX9) nebst SPI-Flash
- 8/16/32MB SDRAM (je nach Beschaffbarkeit)
- Audio-Codec (TLV320AIC23B) mit Line In/Out, Kopfhöreranschluß, 
Mikrofoneingang (aber nur der Kopfhörerausgang hat ne Klinkenbuchse)
- µSD-Karten-Slot
- AVR ATMega644P/1284P
- FTDI FT232 um mit dem AVR quatschen zu können und gleichzeitig die 5V 
für die Platine
- 8 Analogeingänge (über einen Multiplexer)
- Stiftleisten für den FPGA
- Stfitleisten für den AVR

Was ich noch am überlegen bin da drauf zu flanschen ist :
- MIDI-Interface (je nach Platz)
- einfaches R-Netzwerk um VGA-Signale auf eine Stiftleiste zu geben


Ich schau mal das ich heute Abend den Schaltplan so wie er momentan ist 
hier mal reinstelle.
Vllt schaffe ich es beim dritten Anlauf ja mal genug Leute für so ein 
Projekt zusammenzutrommeln.

@Maik

Wenn das wirklich so ne Marktlücke ist würde ich diese gerne Ausfüllen. 
Aber alleine bekomm ich das nicht hin (Vertrieb, Gewerbe, WEEE oder wie 
das heißt usw). Tät mir gerne damit was dazuverdienen :-)

von Maik M. (myco)


Lesenswert?

Ich helfe, soweit es mir möglich ist. Mit FPGAs fang ich "praktisch" 
gerade erst an, "theoretisch" bin ich schon weiter.

Auf das Board würde ich nur das nötigste packen, alles das womit ein 
einfacher µC-User bisher nichts zu tun hatte. Also im groben:

- das Board hat nur eine einzige Eingangsspannung (5V oder 3,3V)
- daraus folgt: alle Spannungsregler onboard
- FPGA + Config-Rom/Flash
- RAM
- Codec (ggf. mit Amp)

Mehr müsste da nicht drauf sein. Aber es gibt noch ein paar Dinge wo ich 
mir nicht sicher bin. zB. man könnte die Klinkenbuchsen draufbauen, aber 
was ist wenn man das Board nur als "Kern" einsetzt, und das Trägerboard 
die eigentlichen externen Anschlüsse trägt?
Weiß nicht, wie es beim Programmieren vom Spartan ist, beim Cyclone 
braucht man JTAG+AS und natürlich den passenden Programmieradapter 
(Original: 200 Euro).

Den µC würde ich keinesfalls mit auf das Board nehmen, weil jeder 
bevorzugt ja einen anderen. Auch kann man den zur Not auf ein Breadboard 
setzen. Gleiches gilt für Midi. Man könnte den Midi-Anschluss ja an den 
FPGA hängen oder halt an den µC. Das sollte dem User überlassen werden.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Ich werde das Soundmodul später in mein kleines Midi-Keyboard einbauen 
und über ein Grafisches Display mit Touch-Panal-Funktion ansteuern. Ich 
hab mal eine Fotomotage im Anhang gemacht. So solls später aussehen. Im 
Midi-Keyboard ist Platz genug für zwei Eurokarten voll Elektronik.

@Rene. Hab auf der CC2-Website mal ein wenig Werbung für dein Projekt 
gemacht. Vielleicht meldet sich ja noch der Eine oder Andere bei dir.

LG Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik

Die Platine wird mit 5V versorgt (über USB) und hat die LDOs für 3.3V 
und 1.2V drauf.
Den uC möchte ich mir nur ungern "klemmen" da mich schon bei den 
früheren Platinen genervt hat das ich immer nen uC separat drankorken 
musste.
Und der AVR kann ja auch anfangs die Programmierung des SPI-Datenflashs 
übernehmen. Ist ja nicht zwingend erforderlich das du den nutzt um den 
FPGA zu "bespaßen" :-)
Und außerdem kann man ja über die Stiftleisten noch nen anderen uC an 
den FPGA drankorken.

@Rolf
Vielen dank für die Werbung :-)
Und dein "Preview" zum AVR WAVE 1 im Keyboard sieht recht schnuckelig 
aus :-)
Wollte das mit meiner Platform auch machen. Bin aber noch nicht dazu 
gekommen.

von Rene B. (themason) Benutzerseite


Angehängte Dateien:

Lesenswert?

So ... hier mal Schaltplan und die Bauteilplatzierung von dem neuen 
Board so wie es ist.

von Maik M. (myco)


Lesenswert?

Schaut recht kompakt aus. Wieviel Layer sind das?

Wie gesagt, würde ich das unnötige weglassen. Wenn das Board so klein 
ist, könnte man das sogar als Arduino-Shield auslegen... damit hätte man 
eine wesentlich größere Reichweite. In diesem Fall könnte man den 
restlichen Platz für die 2 freien Audio-I/O nutzen und sogar Midi noch 
mit draufbauen.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik

Es sind genau 2 Layer :-)

Die Idee das Teil zu nem Arduino Shield umzubauen wäre evtl noch ne 
Idee.
Nur sollte man dann die großen Arduino nehmen. Mit 32K kommt man u.u. 
nicht so weit. Und es müssten noch einige Levelshifter platziert werden, 
um die 5V Signale des Arduinos kompatibel mit den 3.3V Signalen des 
FPGAs zu machen. Und man müsste sich überlegen wie man das macht wenn 
das Board an einen 3.3V uC statt eines 5V uCs angekorkt wird (obwohl es 
da u.u. reicht die Spgsversorgung für die Levelshifter Jumperbar zu 
machen.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich habe diese Tage ein wenig an der Soundquallität meines Synthis 
gefeilt und die Auflösung von 8Bit auf 12Bit geändert. Zusätzlich habe 
ich die 12Bit Sinustabelle von 256 Tabellenwerten auf 4096 Werte erhöht. 
Die Soundausgabe klingt jetzt rauschärmer und erzeugt bei der Wiedergabe 
von hohen Tönen weniger Verzerrungen.

Sinuston (12Bit und 8Bit) auf einem ATxmega128A1 mit internem 12Bit DAC
http://soundcloud.com/rolfdegen/sinus_12bit_8bit

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich möchte die benötigte Zeit für die Soundaugabe von zwei 
Sinus-Oszillatoren in meinem C-Code verringern (siehe Anhang), um einen 
dritten Oszillator zu implementieren . Die Interrupt-Routine benötigt 
für die Ausgabe von zwei Sinustönen auf einen DAC-Kanal schon über 
17µsec. Für einen dritter Oszillator reicht die Zeit nicht mehr aus.

Hat jemand von euch vielleicht eine Idee, was ich an meinem Code 
verbessern könnte ? Jeder Ratschlag ist willkommen. Ich dachte auch 
schon daran, die DAC-Ausgabe in Assembler zu schreiben und in den C-Code 
mit einzubinden. Aber ich habe keine Ahnung, wie ich das in Atmel Studio 
6.0 machen könnte.

Ich bedanke mich schon im Voraus für eure Tips.

LG Rolf

von Maik M. (myco)


Lesenswert?

schrittweite_temp kannst du weglassen, und direkt mit 
schrittweite1/schrittweite2 rechnen. Spart Ram und mind. 4 Zyklen.

Die Accus kannst du Global auch als Register definieren, dann dürftest 
du einiges an Zyklen sparen.

Kannst auch mal hier schauen:
http://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung

Aber so etwas Zyklenkritisches würde ich eh komplett in Assembler 
angehen. Dann hat man eine genaue Kontrolle.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Maik

Danke für deinen Tip. Das Ändern des Phasenaccus auf eine globale 
Register-Variable mit "register32_t"  hat leider nicht viel gebracht. 
Ich habe testweise die Bit-Breite des Phasenaccus von 32Bit auf 16Bit 
reduziert und komme jetzt auf eine Berechnungszeit von 2µsec pro 
Oszillator. Ingesammt benötigt die Interrupt-Routine jetzt etwas weniger 
als 9µsec (vorher 17µsec).

Durch die Änderung des Phasenaccus von 32Bit auf 16Bit reduziert leider 
auch die Frequenzauflösung auf ca. 1,34 Hz pro Schritt. Als nächstes 
werde ich versuchen, die Interrupt-Routine in Assembler zu schreiben und 
in meinen C-Code mit einzubinden. Mal schaun obs funktioniert..

Gruß Rolf

von klaus (Gast)


Lesenswert?

Hallo,

wie berechnest Du die Hüllkurve bzw. die Variable adsr_1?

Kannst Du den C code mal einstellen?

Gruß

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Klaus

Ja gerne, ist kein Geheimnis. Die Routine läuft über einen 
Timer-Interrupt und wird alle 1msec aufgerufen. Der berechnete 
Hüllkurvenwert für den DAC hat eine Auflösung von 12Bit. Die Routine ist 
alledings noch nicht ganz fertig, funktioniert aber in groben Zügen 
schon.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

@Maik

Hallo

Ich konnte die Ausführungszeit meiner Sound-Routine nochmals von 9µsec 
auf 6.5µsec reduzieren, indem ich die Compiler-Optimierung in Atmel 
Studio 6 von "Os" auf "O2" geändert habe.

Mehr Infos zum Thema gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76427#post76427

Gruß Rolf

von Musikus (Gast)


Lesenswert?

Hallo ihr Musikbegeisterten,

habe selbst mit einem 80MHz-16Bit-DSP Musik in C erzeugt, dort geht 
alles eleganter: z.B. 16x16-Mul in 25ns.
Finde es jedoch umso beachtlicher, dass es auch mit 8Bit und 20 MHz 
akzeptabel klingt.

Wenn man den Asm-Code anschaut, merkt man, wo noch gespart werden kann:
Die häufigst verwendeten Variablen sollen in festen Registern stehen.
Ich weiß nicht aus dem Stegreif, wie man das dem GCC beibringt.

Die im oberen Link genannte Anote AVR200 ist völlig ungeeignet, da sie 
für kleine AVRs ohne MUL-Befehl gedacht ist.

Auf jeden Fall lesenswert sind folgende Beiträge:
Beitrag "DDS normal ?"
Beitrag "DDS Sinus erzeugung"
Beitrag "Rechnen mit AVR"

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich versuch mich gerade mal mit Assembler. Ich möchte die komplette 
Soundausgabe über eine Assembler-Routine in meinem C-Programm machen.

Sie dazu den Beitrag im CC2-Forum: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76548#post76548

Gruß Rolf

von Alessandro R. (alessandro_r)


Lesenswert?

Hallo an alle,

Wenn es von Ihrem Interesse ist, schauen Sie bitte auf
http://www.youtube.com/watch?v=4JkhzH57Je4
und geben Sie mir Ihre Meinung. Jeder Vorschlag wird zu schätzen wissen 
!!

von Rolf D. (rolfdegen)


Lesenswert?

Hallo. My name is Rolf Degen from germany.
It is a very good project. I'm I also currently developing a synthesizer 
on an AVR 8-bit processor basis.

My Link: http://www.cczwei-forum.de/cc2/thread.php?threadid=5878

I'm German and all information on this site is in german. Sorry
Greetings from germany

I can't writen a link on your youtube-site. Why ???

Greetings Rolf

von alessandro_r (Gast)


Lesenswert?

Hello Rolf,

This is a YouTube restriction. I see that you have avoided the obstacle 
!
I suggest you to open a parallel english page (for example on EmbDev.net 
) to give more visibility at your project.
I also have developed some project in my native language, but due to the 
poor quality of the various translator utility, I get only local 
audience.

Best regards, Alessandro.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Rolf Degen schrieb:
> Ich versuch mich gerade mal mit Assembler. Ich möchte die komplette
> Soundausgabe über eine Assembler-Routine in meinem C-Programm machen.

Zum Programm: Der Assembler-Code beinhaltet jetzt die komplette Timer1 
Interrupt-Routine für die Soundausgabe der zwei DCO's inklusive der 
Hüllkurve. Die Laufzeit beträgt insgesammt 5,53 µsec. Der Aufruf der 
Interrupt Routine erfolgt alle 25 µsec durch die Interrupt-Freigabe im 
Hauptprogramm (C-Code).

Mehr Info gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76539#post76539

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Dank großartiger Unterstützung von Wolfgang aus dem CC2-Forum 
(http://www.cczwei-forum.de/cc2/), konnte ich die Assembler-Routine für 
meinen AVR-Synthi noch etwas verbessern. Hinzugekommen ist die 
Möglichkeit, außer einer Sinus-Wellenform auch eine Sägezahn-Wellenform 
auszuwählen. Der Parameter dafür wird als 8Bit Volatile Variable aus dem 
C-Programm (Main-Programm) übergeben.

Wolfgangs Website: http://www.wiesolator.de/

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Gibt noch ein paar neue Sounds vom AVR-Synthi.

SAW-Sounds mit zwei Oszillatoren:
http://soundcloud.com/rolfdegen/saw-oszillator

FM-Sounds (1 Operator):
http://soundcloud.com/rolfdegen/fm-01

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

In meinem Code ist noch eine einfache FM-Sound Erweiterung 
hinzugekommen.

LG Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich bin gerade dabei, die Hüllkurvenansteuerung in meinem AVR-Synthi zu 
verbessern. Problematisch war die Release-Phase, da sie nur einen 
geraden Verlauf hatte. Aber was wäre ich ohne die Unterstützung von 
Wolfgang (ein Genie wenn ihr mich fragt). Er hatte mich auf die Idee 
gebracht, die Release-Phase mit Hilfe einer kleinen Umrechnung in eine 
angeglichene e-Funktion umzusetzen (siehe Bild).

Hier die Berechnung für die Release-Phase:

ADSR_Hoehe = 65535
Release_Time = 2- 65535

if (ADSR_Hoehe > 0)
  {
    ADSR_Hoehe = ADSR_Hoehe - ((ADSR_Hoehe / Release_Time)+1);
  }

Der Übergabewert für ADSR-Steuerung in meiner Assembler-Routine muss auf 
12Bit reduziert werden: adsr_1 = ADSR_Hoehe >>4


Bild-Anhang: Neue Release-Phase im AVR-Synthi

Mehr zum Thema hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76736#post76736

Gruß Rolf

von Sam .. (sam1994)


Lesenswert?

Ich würde mir überlegen, ob du das ganze wirklich so genau brauchst. In 
meinem Synthesizer ist der Akkumulator 16bit groß (In meinem Quelltext 
steht davon nichts, da ich beim Programmieren nicht mal DDS kannte, 
sondern selbst überlegt habe wie ich verschiedene Frequenzen erzeuge). 
Die Hüllkurve ist nur 8bit groß, zusätzlich gibt es eine 
Lautstärkeregelung für jeden Kanal (8bit).
Ich würde in die Tonerzeugung nicht einfach mal so eine 16bit Division 
reinhauen. Bei mir hat es quadratisch schon ziemlich gut funktioniert. 
Pseudo-Code:
1
counter = 255;
2
...
3
if(counter < release_time)
4
   Relase_volume = 0;
5
else
6
{
7
   counter -= release_time;
8
   Release_volume = counter * counter >> 8; 
9
}

Das lässt sich in Assembler in wenigen Takten schreiben.

Eine Optimierung, die ich dir dringend empfehle ist einen Puffer 
anzulegen, in den du die Samples berechnest. Das kannst du dann in der 
Hauptschleife machen, während DMA die Daten ausgibt. Wichtig ist, dass 
die Erzeugung immernoch in Assembler geschrieben wird. Allerdings werden 
immer zuerst die Register mit den Werten geladen, dann z.B 64 Samples am 
Stück berechnet und schließlich die Register zurückgeschrieben. Dadurch 
fallen alle Schreibzugriffe auf das SRAM während der Tonerzeugung weg. 
In meinem Synth werden alle Register während der Tonerzeugung genutzt: 
Dadurch ist es möglich 3 Kanäle gleichzeitig zu berechnen und zu 
mischen.

PS: Die Ideen zur Sounderzeugung in deinem Forum sind wirklich gut. Mein 
Synthesizer spielt zurzeit zwischen um die 35 Kanäle gleichzeitig bei 
25Mhz (44,1kHz). Allerdings sind die Sound relativ einfach, da sie nur 
aus 512Byte-Tabellen geladen werden. Vielleicht werde ich versuchen auf 
Kosten der Kanäle die Sounds zu verbessern.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Samuel

Erst einmal Danke für dein Interesse an meinem Synthi-Projekt. Die Idee 
mit einem Sample-Buffer ist schon interessant. Ich frag mich nur, wie 
ich andere Dinge wzB den Midi-Buffer, Touch-Panel und Grafik-Display 
noch ansteuern bzw auswerten kann, wenn der Prozessor im Main-Programm 
mit der Berechnung  von Sample-Daten beschäftigt ist.

Meine Konstruktion sieht so aus, das ich die komplette Berechnung und 
Ausgabe der 12Bit-Sounds in einer Timer Interrupt-Routine alle 25µsec 
durchführe (Samplerate: 40Khz). Die Laufzeit der Interrupt-Routine 
beträgt insgesamt je nach Syntheseart (SUB,FM) und Wellenform (Sinus, 
Sägezahn) zwischen 5.4µsec und 5.9µsec für zwei Oszillatoren 
gleichzeitig. Dadurch bleibt noch genügend Reserve übrig, um 
Grafik-Display, Touch-Panel und Midi-Daten zu verarbeiten.

Später soll am DAC-Ausgang auch noch ein Analoger Filterbaustein wzB. 
SSM2044 oder FM10 hinzu kommen. Dieser wird dann über die Hüllkuvendaten 
in der Assembler-Routine gesteuert.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Wenn ich das richtig verstanden habe macht die Blockweise berechnung nur 
dann wirklich Sinn wenn man DMA nutzt.
Einzig der Overhead der durch das Wegspeichern und Wiederherstellen der 
Prozessor-Register pro Sample ansteht wird minimiert. Die Berechnung 
selbst wird ja nicht unbedingt kürzer. Ok, es hängt noch vom Algorithmus 
ab, ob man beispielsweise vorher noch was "größeres" berechnen muss 
bevor die eigentliche Audio-Verarbeitung losgeht. Aber im Prinzip spielt 
das bei den "kleinen" Prozessoren keine Rolle. Gravierender wird das 
wenn (wie beim PC) Cache ins Spiel kommt. Dann macht das u.u. erheblich 
was aus einen Buffer vorzuberechnen, da dann der "Kontext-Wechel" nicht 
bei jedem Sample neu gemacht werden muß, bzw benötigte Variablen nicht 
erst mühsam bzw u.u. zeitaufwendig aus einem anderen Speicherbereich 
geholt werden müssen.
Aber im Prinzip spricht nichts dagegen direkt Blockweise zu arbeiten. 
Man muß sich nur je nach Blockgröße klarmachen das dadurch eben auch 
eine Latenz entsteht (ok das Problem hat man eher auf einem PC), bzw bei 
Blöcken die größer als 10ms sind die zeitliche Zuordnung der 
MIDI-Signale auch nicht ganz unproblematisch ist. Aber wer berechnet 
denn schon 480 Samples im voraus :-)
Ich hätte vllt auch noch einen Ansatz für die Hüllkurvengeschichte. Ist 
aber auch was aufwendiger.
Ich habe die einzelnen Phasen anders definiert. Und zwar wird auf ein 
Register immer der jeweilige Attack/Decay/Release Wert aufaddiert. Der 
Akku ist quasi eine Skalierung für eine Tabelle (beispielsweise 0-255). 
In dieser Tabelle steht dann linear/exponentiell/umgekehrt exponentiell 
der Lautstärke Verlauf (von 0-1). Die nächste Phase beginnt dann wenn 
der Akku überläuft. In der Sustain Phase wird der Akku immer genullt.
Man kann dann somit für jede steigende/fallende Phase unterschiedliche 
Charakteristika definieren. Bei der Lautstärke macht sich das vllt nicht 
so bemerkbar, aber wenn die Hüllkurve z.b. einen Filter langsam steuert 
hört sich das dann schon unterschiedlich an. Außerdem kann man mit 
dieser Phasen/Zeit-Unterteilung auch andere Hüllkurven leichter 
realisieren. z.b. eine AHDSR, HADSHR oder die mehrphasigen Hüllkurven 
von z.b. Roland Synthies recht einfach implementieren, ohne jedesmal den 
Code umzuschreiben. Mal so als Anregung für deinen FM-Synthie :-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Ich werde erst einmal bei meinem Konzept bleiben und langsam mein 
Touch-Panel und Grafik-Display für Benutzereingaben programmieren. 
Dadurch spare ich mir die ständige Neuprogrammierung des 
Xmega-Prozessors für diverse Sound- und Hüllkurven-Test.

Deine Idee für die Hüllkurvensteuerung finde ich sehr interessant und 
werde es Später mal ausprobieren.

Hab gerade mal nach dem Filter IC "SSM2044P" gegooglet. Bei 
http://darisusgmbh.de/shop/index.php gibts das IC für nur 14,28 Euro. 
Lieferzeit zwei Wochen.

Gruß Rolf

von Sam .. (sam1994)


Lesenswert?

Der Puffer bringt schon ziemlich viel: Ich hab dein Asm-Programm mal 
überflogen, da sind > 50 Ramzugriffe drin -> mehr als 100 Takte werden 
für das Laden/Speichern/Sichern verbraucht.

Wenn man 64 Samples am Stück rechnet ist es nur noch 1/64 der Zeit.

Wenn du noch etwas optimieren willst, dann ist der Puffer wahrscheinlich 
die beste Variante.

@Rene

Selbst ohne DMA macht es Sinn. Bei mir hat diese Optimierung das 
Programm mehr als doppelt so schnell gemacht (Atmega328 hat leider kein 
DMA).

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe die Hüllkurvensteuerung für den AVR-Synthi noch einmal 
überarbeitet (siehe C-Code im Anhang). Die Parameter habe ich auf 16Bit 
Breite belassen, weil dadurch auch außergewöhnlich lange Attack- und 
Release-Phasen für spezielle Soundeffekte möglich sind. Im Anhang ein 
Bild vom neuen Hüllkurvenverlauf im AVR-Synthi.

@Samuel
Ich werde auf jeden Fall deine Idee mit dem Sample-Buffer im Sinn 
behalten und es Später versuchen umzusetzen. Zur Zeit arbeite ich noch 
an vielen Baustellen im Synthi und die Optimierungen stehn da noch ganz 
hinten an.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Fortsetzung:

Ich glaube das Wolfgang aus dem CC2-Forum ein ähnliche Buffer-Funktion 
in seinem Synthi-Projekt realisiert hat (Link: 
http://www.wiesolator.de/index.php?area=Musik&topic=AVR-PolySynth).

Gruß Rolf

von Klaus (Gast)


Lesenswert?

Hallo,

kannst Du bitte mal den kompletten code posten?
Ich möchte das auf einem AVR32 testen.



Viele Grüße

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Klaus

Im Anhang findes du meinen gepackten Quellcode. Es sind zwei Dateien. 
Das Main-Programm in C und die Assembler-Routine, die per 
Timer-Interrupt im Main-Programm aufgerufen wird. Ich arbeite unter 
Atmel Studio 6 mit GCC 4.7.1.

LG Rolf

von Klaus (Gast)


Lesenswert?

Hallo Rolf,

vielen Dank, ich versuche mich jetzt daran den code auf dem AVR32 zum 
laufen zu kriegen.

Viele Grüße

von Rolf D. (rolfdegen)


Lesenswert?

Hallo liebe Musikliebhaber auf mikrocontroller.net

Es gibt mal wieder was auf die Ohren von meinem Synthi. Aus purer Freude 
an den Klängen aus meinem Synthi und weil es irren Spass macht, damit 
rum zuspielen, habe ich im Synthi einen kleinen Live-Sequenzer 
programmiert. Das Ergebnis könnt ihr euch auf SoundCloud anhören. 
Allerdings hege ich keinen Anspruch auf kompositorische Fähigkeiten :-)

Link SoundCloud: http://soundcloud.com/rolfdegen

Aber Vorsicht, die Demo-Sequenzen sind von mir live gespielt und nur für 
Ohren gedacht, die Elektronischen Musik wzB von Klaus Schulze, 
Kraftwerk, Stockhausen und Co lieben :)

Wünsch euch viel Spass beim hören.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe die Attack-Phase in der Hüllkurvensteuerung meines AVR-Synthis 
etwas verbessert. Die neue Hüllkurve kommt einem analogen Synthesizer 
schon sehr nahe. Mehr Infos gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=76877#post76877

LG Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo liebe Synthi-Fans

Es gibt mal wieder was auf die Ohren. Dieses mal habe ich ein paar 
Demo-Sounds durch den spannungsgesteuerten LowPass-Filter (CEM3320) im 
AVR-Synthi gejagt. Die Filterfrequenz wird durch einen eigenen 
ADSR-Generator gesteuert. Die Filterresonanz manuell über einen Regler 
am Keyboard. Was leider noch fehlt, ist die Modulation durch einen LFO 
(LowFrequenzOszillator).


AVR-Synthi Demo-Sounds mit LP-Filter:
http://soundcloud.com/rolfdegen/filter-wave-01


Die Steuerung der Filterfrequenz- und Resonaz erfolgt über zwei 
PWM-Ausgänge am Xmega-Prozessor.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Es gibt wieder etwas neues im AVR-Synthi. Ich habe jetzt drei LFO's für 
die Modulation des Oszilators, Filter und DAC implementiert.

Mehr Infos gibts hier: 
http://www.cczwei-forum.de/cc2/thread.php?postid=77145#post77145

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe einen Digitalen Noise-Generator (nach einer Idee von Wolfgang 
aus dem CC2-Forum) in den AVR-Synthi implementiert (siehe 
Klangbeispiel). Zusätzlich habe ich ein aktuelles Prinzipschaltbild mit 
den Funktionsblöcken gezeichnet.

Klangbeispiel "Noise": http://soundcloud.com/rolfdegen/avr-synthi-noise

Im Anhang das Prinzipschaltbild und mein Programm. Das ganze ist leider 
noch eine Baustelle und soll euch nur eine Stütze für eigene Ideen für 
euer Projekt sein.

Gruß Rolf

von Sascha W. (arno_nyhm)


Lesenswert?

Hallo Rolf,

ich möchte Deinen Thread nicht hijacken, aber gestatte eine kurze 
OT-Frage:
Das scheint ein (Xplain?) Experimentierboard mit einem ATxmega128A1 + 
S(D)RAM zu sein - genau das könnte ich für ein eigenes Projekt zur Zeit 
gut gebrauchen...
Könntest Du mir sagen wie sich das Board nennt und ggf. woher man es 
bekommen kann?

Grüße
Sascha

von Jörg (Gast)


Lesenswert?

Sascha W. schrieb:
> Das scheint ein (Xplain?) Experimentierboard mit einem ATxmega128A1 +
> S(D)RAM zu sein - genau das könnte ich für ein eigenes Projekt zur Zeit
> gut gebrauchen...
> Könntest Du mir sagen wie sich das Board nennt und ggf. woher man es
> bekommen kann?


http://www.cczwei-forum.de/cc2/thread.php?postid=72107#post72107

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Sascha

Es handelt sich um das  Atmel XMEGA-A1 Xplained Evaluation-Kit. Ich habe 
es bei Reichelt gekauft (siehe Link).

Link Reichelt: 
http://www.reichelt.de/Programmer-Entwicklungstools/AT-AVR-XPLAIN/3/index.html?;ACTION=3;LA=2;ARTICLE=96802;GROUPID=2969;artnr=AT+AVR+XPLAIN;SID=10T4MPon8AAAIAADLU5TM70bd5d4d8cb84aecb656096e17edfa00

Gruß Rolf

von Sascha W. (arno_nyhm)


Lesenswert?

Super - Danke Euch für die Hinweise! Ist zur Abwechslung ja auch mal 
einfach zu bekommen, nicht nur direkt aus Hongkong ;)

Grüße
Sascha

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Es gibt wieder was neues über die Stromversorgung des AVR-Synthis. 
Näheres auf: 
http://www.cczwei-forum.de/cc2/thread.php?postid=77648#post77648

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo und guten Morgen

Ich habe einen Schaltplan für den AVR-Synthi gezeichnet. Auf 
http://www.cczwei-forum.de/cc2/thread.php?postid=78070#post78070 kann 
man sich jetzt den Schaltplan ansehen.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe jetzt das Bedienschema fuer das Touch Panal Display fertig 
gestellt. Die Systemeinstellungen fuer den Synthesizer werden ueber 
mehrere Menue-Seiten aufgerufen und koennen dort veraendert und 
abgespeichert werden. Das Aufrufen der einzelnen Menue-Seiten erfolgt 
ueber die Tabreiter (siehe Youtube-Video).

Bild: Touch Panal Menue AVR-Synthi

Youtube-Video: 
http://www.youtube.com/watch?v=KFm-GHSx_5o&feature=youtu.be


Im Moment sind die Menue-Seiten noch leer. Ich werde mir jetzt Gedanken 
darueber machen muessen, wie ich die Synthesizer-Funktionen in den 
Menue-Seiten sinnvoll gestalte.


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Habe Heute das 1.Menü für den Audio-Filter im Synthesizer entwickelt 
(siehe Bild). Die Fader sind groß genug und lassen sich auch leicht mit 
einem Finger bedienen. Leichter und feinfühliger gehts natürlich auch 
mit einem Tabstift. Ich benutze zum Beispiel einen alten Kugelschreiber 
mit einer Kunststoffspitze. Funktioniert damit prima und hat nix 
gekostet.

Bild: VCF1-Menü auf dem Touch Panel des AVR-Synthis

Durch die Anregung von verschiedenen Usern, habe ich mich dazu 
entschieden, für die Parameter-Eingaben zusätzlich einen Drehencoder mit 
Rast- und Tasterfunktion zu verwenden. Damit werden die Parametereingabe 
noch leichter und komfortabler.


Gruß Rolf

von Rolf D. (rolfdegen)



Lesenswert?

Hallo zusammen

Ich habe Probleme mit Phasen-Jitter in meinem Synthi-Projekt. Der
Phasen-Jitter entsteht, wenn der Wert des Phasenaccus mit dem Wert für
die Schrittweite nicht gerade teilbar ist. In meinem Fall beträgt der
Jitterwert max 25µsec = 40KHz und das ist genau die Sample-Frequenz für
die Tonausgabe (siehe Bild 1+2). Wenn ich für die Schrittweite eine Wert
nehme, mit dem der Phasenaccu (24Bit) gerade teilbar ist, sind keine
Störungen warnehmbar und auf dem Oszilloskop ist eine saubere
Saw-Wellenform zu sehen (Bild 3+4).

Phasenaccu 24Bit
Schrittweite 24Bit
Samplerate 25usec (40KHz)

Bild 1: SAW-Wellenform ca. 2031Hz mit Phasen-Jitter (max. 25usec / Div.
100µsec)

Bild 2: SAW-Wellenform ca. 2031Hz mit Phasen-Jitter (max. 25usec / Div.
2msec)

Bild 3: Saw-Wellenform ca. 2038Hz ohne Phasen-Jitter (Div. 100µsec)

Bild 4: Saw-Wellenform ca. 2038Hz ohne Phasen-Jitter (Div. 2msec)



Das Problem lässt sich nach meiner Meinung nur durch ein Zurücksetzen
des Phasenaccus auf 0 beheben, wenn die Wellenform neu beginnt . Dadurch
wird der Phasenaccu mit der Wellenformerzeugung synchronisiert und es
ensteht kein Jitter mehr. Allerdings ist dann keine genau
Frequenzeinstellung mehr möglich. Versuche mit Erhöhung der Bitbreite
des Phasenaccus waren nicht erfolgreich. Der Phasen-Jitter reduzierte
sich dadurch nicht..

Zur Information habe ich noch eine Infoseite gefunden, die das
Phasen-Jitter Problem bei der DDS Synthese sehr anschaulich beschreibt:
http://www.elektronik-labor.de/AVR/DDSGenerator.htm

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo
Stundenlagens Grübeln und die Notizen beim Schalfen unters Kopfkissen 
haben leider nicht geholfen
Ich finde einfach keinen Lösungsansatz für mein Jitter-Problem. Würde 
man die Soundausgabe über einen Timer steuern, könnte man die 
DDS-Problematik vielleicht vergessen. Einen Lösungsweg wie es Olivier 
Gillet bei seinem Shruthi-Synth macht (Soundausgabe über PWM und ext. 
VCF+VCA) will ich nicht nachbauen. Ich möchte mein eigenes Hardware 
Konzept beibehalten.

Link Shruthi Synth: http://mutable-instruments.net/shruthi1

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich habe hier einmal den relevanten Programmteil der für die Erzeugung 
der Sinus und Saw-Wellenform verantwortlich ist dargestellt. Die 
gesammte Sound-Routine (hier nicht abgebildet) wird in einem 
Timer-Interrupt alle 25µsec im Main-Programm (C-Code) aufgerufen.

Wellenformspeicher für Sinus (4096 Werte 12Bit)
12Bit DAC-Wandlung im Xmega-Prozessor 1MHz-Wandlerate

1
//===============================================================
2
// SUBTRAKTIVE KLANGSYSYNTHESE
3
//===============================================================
4
5
SubSynthese:
6
7
//---------------------------------------------------------------
8
// DCO-1 
9
//   * 24-Bit Akku-Breite
10
//   * 24-Bit Phasen-Delta (2,384185mHz/Unit)
11
//   * 12-Bit Sample
12
// ( 38 Takte = 1,188 µsec)
13
//---------------------------------------------------------------
14
15
  // Phasen-Akku 1 incrementieren
16
  // ----------------------------
17
DCO1Calc:
18
  LDS   delta0, schrittweite1+0  ; 2   Phasen-Delta aus SRAM laden
19
  LDS   delta1, schrittweite1+1  ; 2
20
  LDS   delta2, schrittweite1+2  ; 2
21
22
  LDS   phakku0, phaccu1+0       ; 2   Phasen-Akku aus SRAM laden
23
  LDS   phakku1, phaccu1+1       ; 2
24
  LDS   phakku2, phaccu1+2       ; 2
25
26
  SUB   phakku0, delta0          ; 1   Phasen-Akku + Phasen-Delta
27
  SBC   phakku1, delta1          ; 1
28
  SBC   phakku2, delta2          ; 1
29
30
  STS   phaccu1+0, phakku0       ; 2   Phasen-Akku in SRAM zurückschreiben
31
  STS   phaccu1+1, phakku1       ; 2
32
  STS   phaccu1+2, phakku2       ; 2
33
34
  // Die oberen 12Bit des Phasen-Akkus extrahieren
35
  // ---------------------------------------------
36
  ANDI  phakku1, 0xF0            ; 1   Lower Nibble in Byte 0 abnullen
37
  LSR   phakku2                  ; 1   Division durch 8 (16-Bit)
38
  ROR   phakku1                  ; 1
39
  LSR   phakku2                  ; 1
40
  ROR   phakku1                  ; 1
41
  LSR   phakku2                  ; 1
42
  ROR   phakku1                  ; 1
43
44
  // Waveform-Selektion
45
  // ------------------
46
  LDS   dcowave, DcoWaveForm     ; 2   Wellenform-Selektion laden
47
  SBRS  dcowave, 0               ; 1/2 
48
  RJMP  DCO1Sine                 ; 2   Sinus bestimmen
49
50
  // Saw über 1:1 Phase ausgeben
51
  // ---------------------------
52
DCO1Saw:
53
  LSR   phakku2                  ; 1   Phasen-Akku / 2
54
  ROR   phakku1                  ; 1
55
  MOV   dcomix0, phakku1         ; 1   Phase umladen
56
  MOV   dcomix1, phakku2         ; 1
57
  RJMP  DCO1End                  ; 2   Fertig
58
59
  // Sample über aktive Phase aus Wavetable laden
60
  // --------------------------------------------
61
DCO1Sine:
62
  LDI   R30, 0xFC                ; 1   Basis-Adresse Sinus-Tabelle (Low-Byte)
63
  LDI   R31, 0x03                ; 1                               (High-Byte)
64
  ADD   R30, phakku1             ; 1   Phasen-Pointer addieren
65
  ADC   R31, phakku2             ; 1
66
  LPM   dcomix0, Z+              ; 3   Sample aus Wavetable laden (16-Bit)
67
  LPM   dcomix1, Z               ; 3   => in MixerSumme als Initialwert
68
69
DCO1End:


Die Zwischentöne, die der Phasen-Jitter verursacht, kann man sehr 
deutlich ab einer Frequenz von 1KHz warnehmen. Hier ein Soundbeispiel 
mit einer SAW-Wellenform. Start 100Hz, Ende 5000Hz: 
http://soundcloud.com/rolfdegen/saw-sweeb

Gruß Rolf

von Maik M. (myco)


Lesenswert?

1
// Die oberen 12Bit des Phasen-Akkus extrahieren
2
  // ---------------------------------------------
3
  ANDI  phakku1, 0xF0            ; 1   Lower Nibble in Byte 0 abnullen
4
  LSR   phakku2                  ; 1   Division durch 8 (16-Bit)
5
  ROR   phakku1                  ; 1
6
  LSR   phakku2                  ; 1
7
  ROR   phakku1                  ; 1
8
  LSR   phakku2                  ; 1
9
  ROR   phakku1                  ; 1

Der KOMMENTAR ist falsch... extrahiert werden die 13Bit, wobei das 
unterste Bit immer 0 ist.
Ich betone KOMMENTAR, weil der Code ansich richtig ist, aber auf den 
ersten Blick schwer zu durchschauen, weil der Kommentar falsch ist. Du 
brauchst sicher die 13Bit-Adressierung für den Sinus, wegen der 16Bit 
Wortlänge im Programmspeicher.

Den Jitter kann man vermeiden durch Reduzierung der Akkumulator-Breite 
(nicht beim Akkumulieren, sondern beim Ausgeben der Saw, bzw. beim 
Adressieren des Wavetables) ab bestimmten Frequenzen. Also im Prinzip 
kann man es so machen, dass man zB. ab 500Hz immer das LSB nullt, ab 
1000Hz nullt man dann das LSB und das nächst höhere, usw. Diese 
Grenz-Frequenzen kann man anhand des Phasen-Deltas setzen.
Diese Methode ist im Prinzip immer ein Abrunden, was dazu führt, das der 
geringfügige Jitter wegbleibt, weil er weggerundet wird. Das hat aber 
auch Nachteile:
1. Man verliert bei höheren Frequenzen die Auflösung
2. Höhere Frequenzen werden leiser
3. Man erzeugt automatisch ein DC-Offset, was man berücksichtigen 
sollte, oder besser noch, gleich im Oscillator kompensiert.

Software-Instrumente nutzen, um diese Problem generell zu umgehen 
größere Wavetable, so hat man zB. für niedrigere Frequenzen ein besser 
aufgelöste Wave als bei höheren. Im Schnitt teilt man diesen Wavetable 
in 8 Frequenzbereiche. Für so einen kleinen µC ist das aber undenkbar.

von Rolf D. (rolfdegen)


Lesenswert?

Maik M. schrieb:
> Den Jitter kann man vermeiden durch Reduzierung der Akkumulator-Breite
> (nicht beim Akkumulieren, sondern beim Ausgeben der Saw, bzw. beim
> Adressieren des Wavetables) ab bestimmten Frequenzen.

Hallo Maik,
das ist ein guter Tip. Werde ich Morgen gleich mal testen. Besten Dank.

In Bezug auf den Kommentar: Der Phasenaccu hat eine Auflösung von 24Bit 
und ich benötige die oberen 12Bit für den Zugriff auf die 4KByte große 
Sinus-Tabelle im Speicher des Xmegas.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Maik
Hat leider nicht funktioniert. Der Phasen-Jitter bleibt unverändert. 
Aber vielleicht mach ich was falsch ???

Meinen Programmcode habe ich wegen der Übersicht etwas vereinfacht. Die 
markierte Zeile "ANDI phakku1,0b11111110" soll das Phasen-Jitter 
eliminieren indem sie das LSB im Low-Byte der Tabellenadresse löscht. 
Leider ohne Erfolg. Ich habe es auch mit anderen Werten versucht, aber 
ohne Erfolg. Der Phasen-Jitter bleibt.
1
//**************************************************************
2
// ATMEL Studio 6 Inline Assembler-Routine 
3
// Soudausgabe auf DACA Chanal 0
4
// TimeR1 Interruptroutine: alle 25usec = 40.0 KHz Samplerate
5
//      
6
//      (Laufzeit: ?,??? µsec = ??? Takte bei 32MHz)
7
// 
8
// 
9
//           (c) 06.10.2012  Version 1.0 
10
//**************************************************************
11
12
  #include "avr/io.h"
13
14
  .extern sound_out               // Name der Assembler-Funktion
15
  .global TCC1_OVF_vect           // Timer1 Interrupt-Vektor
16
17
 //---------------------------------------------------------------
18
// Benutzte Prozessor-Register (Definition als Namen)
19
//---------------------------------------------------------------
20
  dcoout0   = 16      ; R16  DCO-Out      Byte 0
21
  dcoout1   = 17      ; R17               Byte 1
22
23
  phakku0   = 18      ; R18  Phasen-Akku  Byte 0
24
  phakku1   = 19      ; R19               Byte 1
25
  phakku2   = 20      ; R20               Byte 2
26
27
  delta0    = 21      ; R21  Phasen-Delta Byte 0
28
  delta1    = 22      ; R22               Byte 1
29
  delta2    = 23      ; R23               Byte 2
30
31
  
32
33
//---------------------------------------------------------------
34
// Prozessor-Register inkl. Status-Register sichern
35
// Interrupt-Routine Timer1-Overflow (40.000Hz)
36
//---------------------------------------------------------------
37
38
TCC1_OVF_vect:           
39
  PUSH  R0                       ; 2   R0  auf Stack schieben
40
  IN    R0, SREG                 ; 1   Status-Register über bereits gesichertes
41
  PUSH  R0                       ; 2     R0 auf Stack schieben
42
  PUSH  R1                       ; 2   R1  auf Stack schieben
43
  PUSH  R16                      ; 2   R16 auf Stack schieben 
44
  PUSH  R17                      ; 2   R17 auf Stack schieben
45
  PUSH  R18                      ; 2   R18 auf Stack schieben
46
  PUSH  R19                      ; 2   R19 auf Stack schieben
47
  PUSH  R20                      ; 2   R20 auf Stack schieben
48
  PUSH  R21                      ; 2   R21 auf Stack schieben
49
  PUSH  R22                      ; 2   R22 auf Stack schieben
50
  PUSH  R23                      ; 2   R23 auf Stack schieben
51
  PUSH  R30                      ; 2   R30 auf Stack schieben (ZL)
52
  PUSH  R31                      ; 2   R31 auf Stack schieben (ZH)
53
54
55
//===============================================================
56
// SUBTRAKTIVE KLANGSYSYNTHESE
57
//===============================================================
58
59
SubSynthese:
60
61
//---------------------------------------------------------------
62
// DCO-1 
63
//   * 24-Bit Akku-Breite
64
//   * 24-Bit Phasen-Delta (2,384185mHz/Unit)
65
//   * 12-Bit Sample
66
//---------------------------------------------------------------
67
68
  // Phasen-Akku 1 incrementieren
69
  // ----------------------------
70
71
  LDS   delta0, schrittweite1+0  ; 2   Phasen-Delta aus SRAM laden
72
  LDS   delta1, schrittweite1+1  ; 2
73
  LDS   delta2, schrittweite1+2  ; 2
74
75
  LDS   phakku0, phaccu1+0       ; 2   Phasen-Akku aus SRAM laden
76
  LDS   phakku1, phaccu1+1       ; 2
77
  LDS   phakku2, phaccu1+2       ; 2
78
79
  ADD   phakku0, delta0          ; 1   Phasen-Akku + Phasen-Delta
80
  ADC   phakku1, delta1          ; 1
81
  ADC   phakku2, delta2          ; 1
82
    
83
  STS   phaccu1+0, phakku0       ; 2   Phasen-Akku in SRAM zurückschreiben
84
  STS   phaccu1+1, phakku1       ; 2
85
  STS   phaccu1+2, phakku2       ; 2
86
 
87
  // Die oberen 12Bit des Phasen-Akkus extrahieren
88
  // ---------------------------------------------
89
  ANDI  phakku1, 0xF0            ; 1   Lower Nibble in Byte 0 abnullen
90
  LSR   phakku2                  ; 1   Division durch 8 (16-Bit)
91
  ROR   phakku1                  ; 1
92
  LSR   phakku2                  ; 1
93
  ROR   phakku1                  ; 1
94
  LSR   phakku2                  ; 1
95
  ROR   phakku1                  ; 1
96
    
97
  // SAW-Sample über aktive Phase aus Wavetable laden
98
  // -------------------------------------------------
99
  LDI   R30, 0xFC                ; 1   Basis-Adresse Saw-Tabelle (Low-Byte)
100
  LDI   R31, 0x03                ; 1                             (High-Byte)
101
  //********************************************************************************
102
  ANDI  phakku1,0b11111110     ;     Phasen-Jitter eliminieren 
103
  //********************************************************************************
104
  ADD   R30, phakku1             ; 1   Phasen-Pointer addieren
105
  ADC   R31, phakku2             ; 1
106
  LPM   dcoout0, Z+              ; 3   Sample aus Wavetable laden (12-Bit)
107
  LPM   dcoout1, Z               ; 3   
108
109
 // --------------------------------------------------------------
110
 // Ausgabe am DAC-Converter (DACA Chanal 0)
111
 // --------------------------------------------------------------
112
  STS   0x0318, dcoout0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
113
  STS   0x0319, dcoout1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)
114
    
115
// --------------------------------------------------------------
116
// Prozessor-Register inkl. Status-Register wiederherstellen
117
// --------------------------------------------------------------
118
  
119
  POP   R31                      ; 2   R31 von Stack wiederherstellen (ZH)
120
  POP   R30                      ; 2   R30 von Stack wiederherstellen (ZL)
121
  POP   R23                      ; 2   R23 von Stack wiederherstellen
122
  POP   R22                      ; 2   R22 von Stack wiederherstellen
123
  POP   R21                      ; 2   R21 von Stack wiederherstellen
124
  POP   R20                      ; 2   R20 von Stack wiederherstellen
125
  POP   R19                      ; 2   R19 von Stack wiederherstellen
126
  POP   R18                      ; 2   R18 von Stack wiederherstellen
127
  POP   R17                      ; 2   R17 von Stack wiederherstellen
128
  POP   R16                      ; 2   R16 von Stack wiederherstellen
129
  POP   R1                       ; 2   R1  von Stack wiederherstellen
130
  POP   R0                       ; 2   Status-Register über R0 wieder
131
  OUT   SREG, R0                 ; 1     herstellen
132
  POP   R0                       ; 2   R0  von Stack wiederherstellen
133
  RETI                           ; 4   Return Interrupt und I-Flag quittieren
134
135
// --------------------------------------------------------------
136
  .end
137
//

von Maik M. (myco)


Lesenswert?

1
ANDI  phakku1,0b11111110     ;     Phasen-Jitter eliminieren

Das bringt nichts, das unterste Bit ist bei deiner Addressierung immer 
0, da du mit 13 Bit adressierst, nicht mit 12Bit. Jetzt bist du genau 
auf den falschen Kommentar("Die oberen 12Bit des Phasen-Akkus 
extrahieren") reingefallen, den ich dir mit dem letzen Post zeigen 
wollte ;)

Diese Andrundungs-Maske ist etwas schwer zu bestimmen, aber evtl. gibt's 
eine andere Lösung. Probier mal das:
1
//**************************************************************
2
// ATMEL Studio 6 Inline Assembler-Routine 
3
// Soudausgabe auf DACA Chanal 0
4
// TimeR1 Interruptroutine: alle 25usec = 40.0 KHz Samplerate
5
//      
6
//      (Laufzeit: ?,??? µsec = ??? Takte bei 32MHz)
7
// 
8
// 
9
//           (c) 06.10.2012  Version 1.0 
10
//**************************************************************
11
12
  #include "avr/io.h"
13
14
  .extern sound_out               // Name der Assembler-Funktion
15
  .global TCC1_OVF_vect           // Timer1 Interrupt-Vektor
16
17
 //---------------------------------------------------------------
18
// Benutzte Prozessor-Register (Definition als Namen)
19
//---------------------------------------------------------------
20
  dcoout0   = 16      ; R16  DCO-Out      Byte 0
21
  dcoout1   = 17      ; R17               Byte 1
22
23
  phakku0   = 18      ; R18  Phasen-Akku  Byte 0
24
  phakku1   = 19      ; R19               Byte 1
25
  phakku2   = 20      ; R20               Byte 2
26
27
  delta0    = 21      ; R21  Phasen-Delta Byte 0
28
  delta1    = 22      ; R22               Byte 1
29
  delta2    = 23      ; R23               Byte 2
30
31
  
32
33
//---------------------------------------------------------------
34
// Prozessor-Register inkl. Status-Register sichern
35
// Interrupt-Routine Timer1-Overflow (40.000Hz)
36
//---------------------------------------------------------------
37
38
TCC1_OVF_vect:           
39
  PUSH  R0                       ; 2   R0  auf Stack schieben
40
  IN    R0, SREG                 ; 1   Status-Register über bereits gesichertes
41
  PUSH  R0                       ; 2     R0 auf Stack schieben
42
  PUSH  R1                       ; 2   R1  auf Stack schieben
43
  PUSH  R16                      ; 2   R16 auf Stack schieben 
44
  PUSH  R17                      ; 2   R17 auf Stack schieben
45
  PUSH  R18                      ; 2   R18 auf Stack schieben
46
  PUSH  R19                      ; 2   R19 auf Stack schieben
47
  PUSH  R20                      ; 2   R20 auf Stack schieben
48
  PUSH  R21                      ; 2   R21 auf Stack schieben
49
  PUSH  R22                      ; 2   R22 auf Stack schieben
50
  PUSH  R23                      ; 2   R23 auf Stack schieben
51
  PUSH  R30                      ; 2   R30 auf Stack schieben (ZL)
52
  PUSH  R31                      ; 2   R31 auf Stack schieben (ZH)
53
54
55
//===============================================================
56
// SUBTRAKTIVE KLANGSYSYNTHESE
57
//===============================================================
58
59
SubSynthese:
60
61
//---------------------------------------------------------------
62
// DCO-1 
63
//   * 24-Bit Akku-Breite
64
//   * 24-Bit Phasen-Delta (2,384185mHz/Unit)
65
//   * 12-Bit Sample
66
//---------------------------------------------------------------
67
68
  // Phasen-Akku 1 incrementieren
69
  // ----------------------------
70
71
  LDS   delta0, schrittweite1+0  ; 2   Phasen-Delta aus SRAM laden
72
  LDS   delta1, schrittweite1+1  ; 2
73
  LDS   delta2, schrittweite1+2  ; 2
74
75
  LDS   phakku0, phaccu1+0       ; 2   Phasen-Akku aus SRAM laden
76
  LDS   phakku1, phaccu1+1       ; 2
77
  LDS   phakku2, phaccu1+2       ; 2
78
79
  ADD   phakku0, delta0          ; 1   Phasen-Akku + Phasen-Delta
80
  ADC   phakku1, delta1          ; 1
81
  ADC   phakku2, delta2          ; 1
82
    
83
  STS   phaccu1+0, phakku0       ; 2   Phasen-Akku in SRAM zurückschreiben
84
  STS   phaccu1+1, phakku1       ; 2
85
  STS   phaccu1+2, phakku2       ; 2
86
 
87
  // MyCo
88
  // hohes Delta-Wort durch 2 teilen
89
  LSR   delta2                   ; 1
90
  ROR   delta1                   ; 1
91
  
92
  // MyCo
93
  // 1/2 Delta von der Adressierung abziehen
94
  SUB   phakku1, delta1          ; 1
95
  SBC   phakku2, delta2          ; 1
96
97
  // Die oberen 12Bit des Phasen-Akkus extrahieren
98
  // ---------------------------------------------
99
  ANDI  phakku1, 0xF0            ; 1   Lower Nibble in Byte 0 abnullen
100
  LSR   phakku2                  ; 1   Division durch 8 (16-Bit)
101
  ROR   phakku1                  ; 1
102
  LSR   phakku2                  ; 1
103
  ROR   phakku1                  ; 1
104
  LSR   phakku2                  ; 1
105
  ROR   phakku1                  ; 1
106
    
107
  // SAW-Sample über aktive Phase aus Wavetable laden
108
  // -------------------------------------------------
109
  LDI   R30, 0xFC                ; 1   Basis-Adresse Saw-Tabelle (Low-Byte)
110
  LDI   R31, 0x03                ; 1                             (High-Byte)
111
112
  ADD   R30, phakku1             ; 1   Phasen-Pointer addieren
113
  ADC   R31, phakku2             ; 1
114
  LPM   dcoout0, Z+              ; 3   Sample aus Wavetable laden (12-Bit)
115
  LPM   dcoout1, Z               ; 3   
116
117
 // --------------------------------------------------------------
118
 // Ausgabe am DAC-Converter (DACA Chanal 0)
119
 // --------------------------------------------------------------
120
  STS   0x0318, dcoout0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
121
  STS   0x0319, dcoout1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)
122
    
123
// --------------------------------------------------------------
124
// Prozessor-Register inkl. Status-Register wiederherstellen
125
// --------------------------------------------------------------
126
  
127
  POP   R31                      ; 2   R31 von Stack wiederherstellen (ZH)
128
  POP   R30                      ; 2   R30 von Stack wiederherstellen (ZL)
129
  POP   R23                      ; 2   R23 von Stack wiederherstellen
130
  POP   R22                      ; 2   R22 von Stack wiederherstellen
131
  POP   R21                      ; 2   R21 von Stack wiederherstellen
132
  POP   R20                      ; 2   R20 von Stack wiederherstellen
133
  POP   R19                      ; 2   R19 von Stack wiederherstellen
134
  POP   R18                      ; 2   R18 von Stack wiederherstellen
135
  POP   R17                      ; 2   R17 von Stack wiederherstellen
136
  POP   R16                      ; 2   R16 von Stack wiederherstellen
137
  POP   R1                       ; 2   R1  von Stack wiederherstellen
138
  POP   R0                       ; 2   Status-Register über R0 wieder
139
  OUT   SREG, R0                 ; 1     herstellen
140
  POP   R0                       ; 2   R0  von Stack wiederherstellen
141
  RETI                           ; 4   Return Interrupt und I-Flag quittieren
142
143
// --------------------------------------------------------------
144
  .end
145
//

Ist halt nur eine Idee, keine Ahnung ob das genau das macht, was ich 
meine.

von Rolf D. (rolfdegen)


Lesenswert?

Mein Fazit: Das Jitter von 25µsec (Taktzyklus für den Zähler des 
Phasenaccus) werde ich prinzipiell nicht los. Beim Sinus ist das auch 
kein großes Problem. Dieser wird sauber und störungsfrei wiedergegeben . 
Aber für die anderen Wellenformen wzB. Sägezahn, Puls oder Rechteck ist 
die Softwaregenerierte DDS-Synthese bei einer Taktrate von 25µsec nicht 
zu gebrauchen.

Muss mir also was anderes überlegen. Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Der Ansatz den Rolf meinte von wegen den Phasenakku zu nullen nach einem 
Wellenformdurchgang ist doch im Prinzip richtig. Man darf den Akku an 
sich aber nicht nullen. Man muß, sobald ein Neustart der Wellenform 
erfolgt sich den aktuellen Phasenakku sichern und ihn als Offset zum 
eigentlichen Phasenakku betrachten. Wenn der Phasenakku (gerade bei 
höheren Frequenzen) eben nicht mit dem Index 0 auf den Wavetable bzw 
Saw-Erzeugung liegt verschiebt man diesen für den Durchlauf der 
Wellenform. Man hat dann aber dennoch das Problem das die Wellenform 
eben nicht voll "ausgefahren" wird.

Die einzige Lösung die mir vllt einfallen würde wäre die Samplefrequenz 
soweit zu erhöhen das der Jitter nicht mehr auftritt und dann per 
Down-Sampling auf die Ausgabefrequenz zu shiften, aber das heißt dann 
auch den Wavetable entsprechend aufzubohren.

von Rene B. (themason) Benutzerseite


Lesenswert?

Ich habe gerade nochmal gestöbert.

http://musicdsp.org/archive.php?classid=1#90

Vllt hilft das weiter. Ist zwar eher für Software-Synthies und DSP, aber 
ich denke das ein oder andere könnte evtl nützlich sein.

von Maik M. (myco)


Lesenswert?

Dieser Jitter wird immer auftreten, sobald
1
Wiedergabefrequenz > Samplerate/Wavetable_Länge

Bei ihm ist's 40.000 / 4096, also ab ca. 10Hz wird der Jitter 
auftauchen. Der ist zwar ab dieser Frequenz noch sehr gering, wird aber 
größer, je höher die Frequenz ist. Das kann man aber umgehen, indem man 
bei höheren Frequenzen einen kleinere Wavetable verwendet. Oder man 
adressiert bei höheren Frequenzen einfach mit geringerer Auflösung 
(nullen der niedrigen Bits).
Den Drift/Jitter kann man sich in etwa errechnen:
1
Drift in Prozent = (Wiedergabefrequenz*Wavetable_Länge)/(Samplerate*DAC_Auflösung)*100

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Danke an alle.

Zum Vorschlag von Maik:
1
// MyCo
2
  // hohes Delta-Wort durch 2 teilen
3
  LSR   delta2                   ; 1
4
  ROR   delta1                   ; 1
5
  
6
  // MyCo
7
  // 1/2 Delta von der Adressierung abziehen
8
  SUB   phakku1, delta1          ; 1
9
  SBC   phakku2, delta2          ; 1

Die Code-Änderungen hat leider nichts gebracht. Der Phasen-Jitter 
bleibt.
Ich werde es wohl mit der Idee von Maik, bei höheren Frequenzen kleinere 
Wavetables zu verwenden, versuchen.


Zum Hinweis von Rene "Bandlimited sawtooth synthesis":
Ich hab Gestern mit Oliver Gillert, dem Entwickler des genialen Shruthi 
Synth (http://mutable-instruments.net/shruthi1) gemailt. Ich habe ih 
gefragt, wie er das so mit der Sounderzeugung im Shruthi macht und eine 
Antwort erhalten, die ich hier mit Hilfe von Google übersetzt habe:


"Für die klassischer analoger Wellenformen auf dem Shruthi (Saw, 
Rechteck, Dreieck),
verwende ich bandbegrenzten Wavetables .
(Anmerkung von mir: Wolfgang hat es oben in einen der letzten Beiträge 
schon vorhergesagt hat).

Die Wavetables werden durch integrierte bandbegrenzte Impulse 
(sinc-Funktionen) für verschiedene f0 / fs-Verhältnis
Abstand mit 2 ** (16 / 12,0) Verhältnisse. Als Ergebnis gibt es ein
Wavetable für jede Gruppe von 16 Noten. Um zu vermeiden, grobe Übergänge 
I
Interpolieren zwischen jeder Wavetable. Für die höheren Töne, die 
Wellenform
nähert sich einer sinusförmigen - von der erwartet wird, weil einer 
quadratischen
Welle bei 8 kHz auf 44 kHz abgetastet ist in der Tat eine Sinuswelle 
(die dritte
Oberwelle bei 24kHz oberhalb Nyquist-Frequenz).

Hier ist eine Kurve der Wellenformen aus der Shruthi bei 
unterschiedlichen
Frequenzen (50, 125, 320, 800, 2k, 5k, 12k):
http://i.imgur.com/nZmMx.png

Die quadratischen und Sägezahnwellen gefärbt sind - ich denke, diese 
Wellenformen
sind viel interessanter als die "reinen" Sägezahn und "pure" eckig
Welle.

Die PWM-Wellenform wird durch Summieren von zwei bandbegrenzten Sägezahn 
erhalten
mit einer Phasendifferenz - die Phasendifferenz steuert die 
PWM-Verhältnis.

Ich habe versucht mit minBLEP und es verwendet, 70% der CPU. Auf der 
Shruthi-1 ist
war keine Option, aber in Ihrem Projekt, das Sie mit einem XMega bei 32
MHz, so dass es machbar sein, um minBLEP verwenden. Ich würde empfehlen, 
diese Option wählen,
da es klingt sehr gut und kann tun hardsync! minBLEP nicht tun können
Dreiecke, aber Sie können bandbegrenzte Wavetables für diese Verwendung.

Die Shruthi-1-Code ist Open Source und finden Sie Antworten auf Ihre zu 
finden
Fragen Sie sich den Code:
https://github.com/pichenettes/shruthi-1/";




Auf http://www.experimentalscene.com/articles/minbleps.php habe ich eine 
kleine Anleitung (C++ Quellcode) für einen "minBLEP"-Oszilator gefunden. 
Mal schaun wie ich das für einen Xmega nutzen kann.


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich wollte mal wissen wie sich so ein Square-Sound mit Bandbegrenzung 
(eng. band-limited square)
auf meinem Synthi so anhört und habe mir die Mühe gemacht zwei 
Hörbeispiele
aufzunehmen. Die Aufnahmen wurden am LowPass-Filterausgang bei offenem
Filter gemacht.
Die 8Bit Square-Sounds werden aus einer 256 Byte großen Waveform-Tabelle 
mit 40KHz Sampling-Frequenz an den DAC Ausgang gesendet.


Bild 1: 1KHz Square-Sound 8Bit (Rechteck) ohne Bandbegrenzung auf dem 
AVR-Synthi
Link soundcloud.com: http://soundcloud.com/rolfdegen/square-0

Bild 2: 1KHz Square-Sound (aus dem Shruthi-Synth gestohlen   ) mit 
Bandbegrenzung auf dem AVR-Synthi.
Link soundcloud.com: 
http://soundcloud.com/rolfdegen/bandlimited-square-0


Wie man hört, ist der Square-Sound mit Bandbegrenzung viel sauberer und 
ohne Nebengeräusche.

Mal schaun wie ich als "Nicht Studierter" so einen minBlep-Oszillator 
auf meinen Xmega implementieren kann.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich habe mich dazu entschieden, fertige Bandbegrenzte Wavefiles zu 
benutzen und diese in den Flash-Speicher des Xmegas zu schreiben. 
Dadurch spar ich mir das ganze Rumrechnen mit Sinus und Cosinus und 
haste nicht gesehen zur Laufzeit. Die Bandbegrenzten Wavefiles liegen 
mir als bin.Datei vor und ich möchte diese als ext. Datei in meinen 
Quellcode mit einbinden. Leider weis ich nicht wie das in Atmel Studio 
funktioniert. Ich habe mir ersteinmal damit geholfen, das ich die 
Wave-Datei über einen Hexeditor als Hexadezimal-Tabelle exportiere und 
in meinen C-Quellcode kopiere. Das funktioniert problemlos. Dadurch wird 
aber der Quellcode sehr lang und unübersichtlich. Ein Tip wär nicht 
schlecht. Danke euch.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Angehängte Dateien:

Lesenswert?

@Rolf

Ich hab gestern mal mit bandlimited waveforms auf dem PC 
rumexperimentiert.
Ich habe dabei einen Oszillator programmiert der 64 einzelne Sinüsse 
zusammenrechnet und deren Frequenz-Anteile (also 64 Koeffizienten) 
vorgegeben werden können.
Den Sinus selbst hole ich über eine Tabelle. Ich habe mal deine 
Erkenntnis darin verwurstet das der Sinus auch bei "ungenauen" 
Frequenzen keine "Sprünge" macht und somit eine "ganz normale" DDS 
genutzt. Also das Ergebnis klingt doch schon ganz gut, selbst wenn man 
bei tiefen Frequenzen eine Art Tiefpass mit raushört, das aber eben 
daran liegt das ich "nur" 64 Anteile berechne, die Wellenform aber noch 
hörere Frequenzen beinhalten würde. (wenn meine Grundfrequenz 
beispielsweise 100Hz ist, wäre der letzte Frequenzanteil bei 6,4kHz).
Das Ergebnis klingt aber recht brauchbar, und ich werd da auch mal was 
weiter probieren. Das ganze ist somit quasi eine einfache Additive 
Synthese.
Das was für mich son bissl den Reiz dabei ausmacht ist das ich die 
Frequenzanteile zur Laufzeit ändern kann, und somit die 
ausgangswellenform schon dynamisch gestalten kann (z.b. zwischen 
Sägezahn und Rechteck "morphen") oder einer Wellenform einfach 
Oberwellen hinzufügen kann, die z.b. von einer Hüllkurve gesteuert 
werden.
Anbei mal die zusammengehackte Datei (ist noch viel Float drin, lässt 
sich aber problemlos durch integer ersetzen), in der allerdings der 
Sinus noch nicht drin ist (der ist bei mir in einer separaten Datei und 
hat den Sinus-Kurvenzug von 0 bis pi/2).

von Maik M. (myco)


Lesenswert?

@Rene:
Füge mal vor der Zeile:
1
rT = fOscGetSine (ulPhi);

diese eine:
1
if (ulPhi & 80000000)break;

Damit wird verhindert, das Frequenzen über der Nyquisit generiert 
werden.

Diese Zeile:
1
if (rFrq > 23000.0f) { rFrq = 20000.0f; }

ist wohl nur ein Provisorium, oder? Besser wäre es, bei einer hohen 
Basis-Frequenz, den Osc komplett zu umgehen.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik

>if (rFrq > 23000.0f) { rFrq = 20000.0f; }

Da war noch ein Fehler drin. Hatte das ganze ursprünglich für 48kHz 
ausgelegt, bis mir dann bei der Durchsicht eingefallen ist das meine 
Soundkarte auf 44,1kHz läuft :-S

>if (ulPhi & 0x80000000) break;

Stimmt. Gute Idee. Vor allem hätte ich dann auch einen anhaltspunkt 
wieviele Sinüsse ich bei hohen Frequenzen effektiv durchrechnen muß, 
damit die 64. Oberwelle noch unterhalb meiner Nyquist Frequenz liegt.

>ist wohl nur ein Provisorium, oder? Besser wäre es, bei einer hohen
>Basis-Frequenz, den Osc komplett zu umgehen.

Wie meinst das "komplett umgehen" ?

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Rene

Hab ein einfaches Programm namens "WinFilter" für die Filterberechnung 
gefunden. Vielleicht hilfts es dir :)

Bild: WinFilter


Download Link: http://www.winfilter.20m.com/

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Danke für den Link. Das Problem bei solchen Filter Tools ist das sie 
zwar Koeffizienten ausspucken, aber den Weg wie man diese dann selbst 
berechnen kann eben nicht. Und das wäre gerade für 
Synthesizer/Mischpulte/Effektgeräte wo sich die Filter ja in 
Frequenz/Güte/Typ/Charakteristik dynamisch ändern können interessant.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene

Dann schau mal hier: http://musicdsp.org/archive.php?classid=1

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Die musicdsp-Seite hab ich vor einiger Zeit schon entdeckt. Daher kam 
ich ja auf die bandlimited-Geschichte. Ich glaub das ich da auch die 
Neuüberarbeitung meiner Filter-klamotten her hab (Koeffizientenseitig).
Ist schon recht lesenswert die Seite.
Daher dachte ich das dir das vllt bei deinem Problemchen evtl hilfreich 
sein könnte.

von Rolf D. (rolfdegen)


Lesenswert?

Ich habe bei diesen Problemen wieder viel interessantes gelernt aber ich 
bin nicht so der Mathetyp und mich schreckt der ganze Berechnungskram 
eher ein wenig ab. Zumal der Xmega in meinem Projekt noch andere 
Aufgaben nebenbei erledigen soll wz. Midi-Daten empfangen, Daten zum 
Touch-Display senden und empfangen, Analoge Filter steuern uvm. Später 
soll es auch  eine Möglichkeit geben, die Soundbank von einer SD-Karte 
in den 8MB SDRAM Speicher des Xplained Board zu laden.

Zur Zeit arbeite ich an der Soundbank für meinen Synthi. Ich habe im 
Internet einige Bandlimited Wavetables gefunden, die ich in meine 
Soundbank integriert habe. Somit bleibt meinem Xmega-Prozessor die 
Berechnung wärend der Laufzeit erst einmal erspart.

Hier ein Code-Ausschnitt vom Shruthi Synth:
1
// ------- Band-limited PWM --------------------------------------------------
2
void Oscillator::RenderBandlimitedPwm(uint8_t* buffer) {
3
  uint8_t balance_index = U8Swap4(note_ - 12);
4
  uint8_t gain_2 = balance_index & 0xf0;
5
  uint8_t gain_1 = ~gain_2;
6
7
  uint8_t wave_index = balance_index & 0xf;
8
  const prog_uint8_t* wave_1 = waveform_table[
9
      WAV_RES_BANDLIMITED_SAW_1 + wave_index];
10
  wave_index = U8AddClip(wave_index, 1, kNumZonesHalfSampleRate);
11
  const prog_uint8_t* wave_2 = waveform_table[
12
      WAV_RES_BANDLIMITED_SAW_1 + wave_index];
13
  
14
  uint16_t shift = static_cast<uint16_t>(parameter_ + 128) << 8;
15
  // For higher pitched notes, simply use 128
16
  uint8_t scale = 192 - (parameter_ >> 1);
17
  if (note_ > 64) {
18
    scale = U8Mix(scale, 102, (note_ - 64) << 2);
19
    scale = U8Mix(scale, 102, (note_ - 64) << 2);
20
  }
21
  
22
  phase_increment_ = U24ShiftLeft(phase_increment_);
23
  
24
  BEGIN_SAMPLE_LOOP
25
    phase = U24AddC(phase, phase_increment_int);
26
    *sync_output_++ = phase.carry;
27
    *sync_output_++ = 0;
28
    if (sync_input_[0] || sync_input_[1]) {
29
      phase.integral = 0;
30
      phase.fractional = 0;
31
    }
32
    sync_input_ += 2;
33
    
34
    uint8_t a = InterpolateTwoTables(
35
        wave_1, wave_2,
36
        phase.integral, gain_1, gain_2);
37
    a = U8U8MulShift8(a, scale);
38
    uint8_t b = InterpolateTwoTables(
39
        wave_1, wave_2,
40
        phase.integral + shift, gain_1, gain_2);
41
    b = U8U8MulShift8(b, scale);
42
    a = a - b + 128;
43
    *buffer++ = a;
44
    *buffer++ = a;
45
    size--;
46
  END_SAMPLE_LOOP
47
}


Viele Ideen kann man sich auch auf der Website des Shruthi Synth 
abkucken. Olivier Gillert der Macher des Shruthi Synths hat seine 
Entwicklungsarbeit für jederman frei zugänglich gemacht. Das Ding ist 
einfach genial. Er arbeitet z.Zt. an einer mehrstimmigen Version des 
Shruthis.

Link zur Shruthi Website: http://mutable-instruments.net/

Gruß Rolf

von Maik M. (myco)


Lesenswert?

Rene B. schrieb:
>>ist wohl nur ein Provisorium, oder? Besser wäre es, bei einer hohen
>>Basis-Frequenz, den Osc komplett zu umgehen.
>
> Wie meinst das "komplett umgehen" ?

Das bezog sich auf diese Zeile:
1
if (rFrq > 23000.0f) { rFrq = 20000.0f; }

Die ja soviel macht wie: Bei einer zu hohen Frequenz, generiere eine 
völlig andere. Das ist ungünstig, weil der Osc. dann evtl. sinnlos eine 
disharmonie spielt.

Mit "Osc. umgehen" meine ich, das man ihn bei einer zu hohen Frequenz 
garnicht erst berechnet, sondern 0 (Stille) ausgibt.

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik

Achso meintest das. Ja, so gesehen ist das nen Proviorium. Und 
Frequenzanteile oberhalb von fS/2 zu Nullen wird noch eingebaut ...

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Bezüglich der Wave-Files habe von Humfrey aus dem CC2-Forum einen guten 
Vorschlag erhalten. Die Deklaration der Wave-Daten als Hexadezimal Werte 
in eine extra Quelltext-Datei schreiben und diese dann per #include in 
den normalen C-Quelltext mit einbinden. Funktioniert bestens.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich war mal wieder fleißig und habe die letzten Wochen am AVR-Synthi 
gebastelt bzw programmiert. Herausgekommen ist eine neu gestaltete 
Menü-Seite für die DCO Einstellung. Was eigentlich sehr einfach klingt, 
hat mir doch etwas Kopfzerbrechen bereitet. Die Einstellung der DCO's 
sollte übersichtlich und einfach zu bedienen sein.


Bild 1: DCO-Menü


Herausgekommen ist eine Wellenform Auswahl-Matrix für beide DCO's um 
ver-
schiedene Wellenformen zu kombinieren. Mit der internen 
Wellenform-Tabelle
(ca. 22KByte) bestehend aus den Bandlimited Waves (Square, Saw, 
Triangle)
und Synthezizer-Waves sind zur Zeit etwas mehr als 500 Wellenform Kombi-
nationen möglich. Soundbeispiele wirds hier später geben.

Ferne besteht die direkte Möglichkeit, mit dem Detune-Regler die DCO's 
gegeneinander zu verstimmen um einen Schwebungeffekt im Sound zu 
erreichen. Mit den Schaltern "Soft" und "Hard" kann man die Stärke des 
Reglers einstellen. Der "Sync"-Button synchronisiert beide DCO's wieder 
und stellt den Detune-Wert wieder auf null.


Bild 2: Auswahl der Synthesizer-Waves


Eine etwas schwierige Aufgabe war die Wellenform Auswahl für die 
Synthesizer- Waves. Das habe ich durch ein Untermenü bewerkstelligt. 
Klickt man auf den "WAV"-Button öffnet sich eine neue Menüseite für die 
Auswahl der Waves und der grafischen Ansicht der Wellenform.


Bild 3: Wellenform-Kombination einer Saw-Waveform und 
Synthesizer-Waveform


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hier noch ein paar Bilder von speziellen Wellenform-Kombinationen.

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Sieht ja recht schick aus. Bin mal gespannt auf die Sound-Beispiele.
Aber ich hab mal ne Frage zum Sync. Heißt Sync nicht das ein Oszillator 
beim Nulldurchgang den anderen Synchronisiert, also diesen dann 
ebenfalls neustartet ? Das macht im Falle das beide Detune = 0 haben in 
dem Sinne keinen Sinn, da beide dann ja exakt diesselbe Frequenz haben. 
Aber interessant wird das meine ich dann sobald der zu Synchronisierende 
Oszillator höher schwingt (egal ob mit einem Detune im Halbton bzw 
Cent-Halbton) Hauptsache höher als der erste Oszillator, denn sonst 
würde die Wellenform ja nicht voll ausschwingen können. Aber ich meine 
das gerade das Synchronisieren den Sound was fetter bzw 
charakteristischer macht. Was vllt auch noch ne schöne Variante für 
deinen Oszillator wäre (wenn du ohnehin schon 2 davon hast ;-)) wäre 
Ringmodulation. Also einfach die beiden Oszillator-Ausgänge miteinander 
multiplizieren. Das würde die 500 möglichen Kombinationen noch ein bissl 
aufstocken :-) Und wäre ne prima Klangquelle für nen analogen Filter. 
Ich weiß ja nicht wie es in deine Programmierung passt. Aber mal so als 
Vorschlag.

von Maik M. (myco)


Lesenswert?

Ich hab gerade mal in meinen AVR-Synth code geschaut, wie ich das so 
aufgebaut habe. Die Klangerzeugung lief bei mir über einen "morphable 
wavetable". Der Wavetable selbst hatte 8 Wellenformen, wobei man immer 
von einer Wellenform zur nächsten morphen kann. Das ging im Prinzip so:
1
Ausgang = (Wellenform[index][sample] * (255-morph) + Wellenform[(index+1)&0b111][sample] * morph)
2
3
morph = Byte (0..255)
4
index = Byte (0..7)
5
sample = Wavetable Akku

Multiplikation war bei mir eine spezielle Funktion, die Word mit Byte 
Multipliziert hat, und als Ergebnis kam Word raus (die untersten 8Bit 
des 24Bit Ergebnisses werden ignoriert)

Ich habe auch mit einem Filter experimentiert, der so auschaute:
1
v0 =  R*C*v0 + C*in - C*v1;
2
v1 =  R*C*v1 + C*v0;
3
output = v1;
4
5
C = Cutoff (0..255)
6
R = Resonance(255..0)

Hierbei habe ich die Multiplikation R*C in einem nebenherlaufenden, sehr 
langsamen Timer erledigt, weil es nicht so kritisch war. Soweit ich mich 
erinnern kann, war der Filter sehr gut, und dank dem 
Hardware-Multiplikator auch von den Zyklen her recht vertretbar.

von Rolf Degen (Gast)


Lesenswert?

Rene B. schrieb:
> Heißt Sync nicht das ein Oszillator
> beim Nulldurchgang den anderen Synchronisiert, also diesen dann
> ebenfalls neustartet ?

Hallo Rene. Ja das ist richtig. Ich sollte meine Sync Funktion wohl 
besser umbenennen, denn sie setzt lediglich beide Oszillator auf die 
gleiche  Frequenz und den gleichen Phasenwinkel zurueck. Ich bin mir 
allerdings nicht im klaren darueber, ob das musikalisch gesehen 
ueberhaupt sinnvoll ist.

Nemen wir mal an, das mit dem Einschalten des Synthis beide Oszillatoren 
mit gleicher Frequenz und Phase starten. Nun verstelle ich im DCO Menue 
den Detune Regler und dadurch schwingen beide Oszillatoren mit 
unterschiedlicher Frequenz und als Ergebnis ensteht am Ausgang eine 
gewollte Amplitdenmodulation. Mit dem alleinigen Zuruecksetzen des 
Detune Reglers auf null, schwingen zwar beide Oszillatoren wieder mit 
gleicher Frequenz aber nicht unbedingt synchron zueinander, was 
ebenfalls zu einer Amplitudenmodulaton am Ausgang fuehrt. Aus diesem 
Grund stelle ich mit dem Sync-Button auch die Phasen beider Oszillatoren 
zurueck.

Danke fuer den Tip mit der Ringmodulation. Werde ich Morgen gleich 
umsetzen :)

von Maik M. (myco)


Lesenswert?

Hab die Preview von damals wiedergefunden und raufgeladen:
http://soundcloud.com/maikmenz/avr-8bit-filter

Der Reverb stammt nicht vom Synth, den hab ich nachträglich 
draufgepackt. Der Filter in der Demo ist der den ich erwähnt habe. In 
der Demo hört mach auch das Wavetable morphing von Sägezahn zu Rechteck 
und zurück.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Irgendwie sieht bei mir die Ringmodulation auf dem Oszi (Bild 1) etwas 
merkwürdig aus.

Hier mein Code:
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  MUL   dco1out0, dco2out0    ; DCO1_out * DCO2_out
7
  MOVW  dco1out0, R0
8
  LSR   dco1out1        ; Ausgabewert auf 12Bit (div 4)
9
  ROR   dco1out0
10
  LSR   dco1out1
11
  ROR   dco1out0
12
  LSR   dco1out1
13
  ROR   dco1out0
14
  LSR   dco1out1
15
  ROR   dco1out0
16
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
17
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

Der Sound klingt aber wie eine Ringmodulation. Ich wunder mich halt über 
das Aussehen der Wellenform. Diese entspricht nicht der üblichen aus dem 
Lehrbuch wie zB in Bild 2.

Mach ich was flasch in meiner Berechnung oder ist das so korrekt. Mir 
scheint es so, als ob der Nullpunkt der Sinuskurve nach unten verschoben 
ist. Die Frequenz von Oszillator 1 (dco1) beträgt 200Hz und von 
Oszillator 2 (dco2) 6000Hz. Die beiden Sinuswerte stammen direkt aus 
einer 8Bit Sinus-Tabelle im Flash des ATxmegas.

Gruß Rolf

von Maik M. (myco)


Lesenswert?

Dein Code operiert nur im positivem Bereich, das ist generell schlecht 
für DSP.

von Rolf D. (rolfdegen)


Lesenswert?

Wie könnte ich das ändern ?

von Maik M. (myco)


Lesenswert?

du müsstest deinen Wavetable als Signed speichern, und von da an alle 
Unsigned-Operationen durch Signed-Operationen ersetzen. Dann am Ende, 
vor der Ausgabe konvertierst du dann erst wieder zurück auf Unsigned

von Rene B. (themason) Benutzerseite


Lesenswert?

Mach deine Wellenformen und die Multiplikation signed.
Wie Maik schon meinte : Nur unsigned (also positiv) ist eher schlecht, 
selbst wenns sich nach dem gewünschten Ergebnis anhört.
Du wirst dann tlw Probleme bekommen mit nem DC-Offset. Dadurch das der 
Nullpunkt dann ja eben irgendwo liegt, in Abhängigkeit von der 
Beschaffenheit deines Ausgangssignals.

von Rolf D. (rolfdegen)


Lesenswert?

Die Tabellen kann ich nicht ändern. Besteht nicht die Möglichkeit den 
ausgelesenen Tabellenwert als signed Byte zu konvertieren. Die Auflösung 
würde dadurch auf 7Bit reduziert.

von Maik M. (myco)


Lesenswert?

das kannst du machen, aber hast dann halt wieder einen Zyklus weniger.

Konvertieren von Signed nach Unsigned und umgekehrt geht relativ 
einfach:
1
subi register,0x80

Allerdings musst du bei Signed-Operationen bedenken, dass das 
höchstwertige Bit immer das Vorzeichen-Flag ist. Operationen wie lsl, 
lsr, ror, rol, usw. darfst du auf das höchstwertige Byte eines Signed 
nicht anwenden, weil sich sonst evtl. das Vorzeichen ändert. Für LSR 
gibt es allerdings schon ersatz: ASR. Für LSL hingegen gibt es keinen, 
aber da kannst du sowas machen:
1
bst reg,7
2
bld reg,6
3
lsl reg

Dabei bleibt das Vorzeichen erhalten. Auch musst du bei der 
Multiplikation aufpassen, schau dir dazu die Operationen MULS und MULSU 
an.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe es wie folgt gelöst:
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  subi  dco1out0,0x80      ; make signed Wave
7
  subi  dco2out0,0x80
8
  MULS  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
9
  MOVW  dco1out0, R0      ; save Result
10
  
11
  ldi   dco2out0,0x80      ; make unsigned Wave
12
  add   dco1out1,dco2out0
13
14
  LSR   dco1out1        ; DCO_out reduction to 12Bit (div 4)
15
  ROR   dco1out0
16
  LSR   dco1out1
17
  ROR   dco1out0
18
  LSR   dco1out1
19
  ROR   dco1out0
20
  LSR   dco1out1
21
  ROR   dco1out0
22
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
23
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

Das Ergebnis sieht jetzt richtig aus (Bild). Allerdings ist die 
Ausgangsspannung nur noch halb so groß wie vorher. Eine Division durch 
drei vor der DAC-Ausgabe funktioniert nicht. Dadurch entstehen wilde 
Bit-Muster.

Gruß Rolf

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

Das die Ausgangsspannug nur noch halb so groß ist, liegt daran das du 2 
Vorzeichenbits hast. Da aber durch die Multiplikation ja nur noch 1 
VZ-Bit übrigbleibt geht dir in der Dynamik ja ein Bit flöten. Du 
müsstest quasi eienn Shift nach links machen um die Ausgangsspannung 
wieder auf de vollen Bereich zu bringen.

von Rolf D. (rolfdegen)


Lesenswert?

Das funktioniert eben nicht. Egal wo ich es mache. Es ensteht am Ausgang 
ein Wildes Bit-Chaos.
1
...
2
  ldi   dco2out0,0x80      ; make unsigned Wave
3
  add   dco1out1,dco2out0
4
5
  LSR   dco1out1        ; DCO_out reduction to 12Bit (div 4)
6
  ROR   dco1out0
7
  LSR   dco1out1
8
  ROR   dco1out0
9
  LSR   dco1out1
10
  ROR   dco1out0
11
  LSR   dco1out1
12
  ROR   dco1out0
13
14
  LSL   dco1out0       ; Ausgabewert multi 2
15
  ROL   dco1out1
16
17
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
18
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

von Maik M. (myco)


Lesenswert?

Vorzeichenbehaftetes Multiplizieren ist etwas tricky, wie Rene schon 
schrieb, verliert man 1 Bit. Genauer:

S XXX XXXX * S XXX XXXX = SS YY YYYY YYYY YYYY

Wobei S das Vorzeichenbit ist, X und Y sind Wertebits.

Probier mal folgendes (bisher ungetestet):
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  subi  dco1out0,0x80      ; make signed Wave
7
  subi  dco2out0,0x80
8
  MULS  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
9
10
  ; Multiply signed word with 2
11
  bst r1,7
12
  bld r1,6
13
  lsl r0
14
  rol r1
15
16
  ; Make unsigned word
17
  subi r1,0x80
18
  
19
  ; save Result
20
  movw dco1out1:dco1out0, r1:R0      
21
  
22
  LSR   dco1out1        ; DCO_out reduction to 12Bit (div 4)
23
  ROR   dco1out0
24
  LSR   dco1out1
25
  ROR   dco1out0
26
  LSR   dco1out1
27
  ROR   dco1out0
28
  LSR   dco1out1
29
  ROR   dco1out0
30
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
31
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

wenn das überhaupt funktionieren sollte, dann müssen dco1out1:dco1out0 
Registerpaare sein, ansonsten würde MOVW generell fehlschlagen.

von Maik M. (myco)


Lesenswert?

hier nochmal was zum Testen... etwas abgekürzt:
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  subi  dco1out0,0x80      ; make signed Wave
7
  subi  dco2out0,0x80
8
  muls  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
9
10
  ; remove first sign bit
11
  andi  r1, 0x7F
12
  
13
  ; shift 3 times left
14
  lsr   r1
15
  ror   r0
16
  lsr   r1
17
  ror   r0
18
  lsr   r1
19
  ror   r0
20
  
21
  ; make unsigned 12bit
22
  subi  r1, 0x08
23
24
  ; save Result
25
  movw dco1out1:dco1out0, r1:r0      
26
  
27
  sts   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
28
  sts   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

von Rolf D. (rolfdegen)


Lesenswert?

Danke Maik. Es funktioniert. Ich musste es allerdings etwas anpassen.
1
Ringmod:
2
  subi  dco1out0,0x80      ; make signed Wave
3
  subi  dco2out0,0x80
4
  MULS  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
5
6
  ; Multiply signed word with 2
7
  bst r1,7
8
  bld r1,6
9
  lsl r0
10
  rol r1
11
12
  ; Make unsigned word
13
  //subi r1,0x80
14
  
15
  ; save Result
16
  //movw dco1out1:dco1out0, r1:R0 
17
  movw  dco1out0,r0     
18
  subi  dco1out1,0x80
19
20
  LSR   dco1out1        ; DCO_out reduction to 12Bit (div 4)
21
  ROR   dco1out0
22
  LSR   dco1out1
23
  ROR   dco1out0
24
  LSR   dco1out1
25
  ROR   dco1out0
26
  LSR   dco1out1
27
  ROR   dco1out0
28
29
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
30
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

von Maik M. (myco)


Lesenswert?

das mit dem abkürzen (2. Code-Beitrag von mir) wird wohl nicht 
funktionieren... jetzt bin ich mit dem Signed-Kram auch 
durcheinandergekommen.

von Maik M. (myco)


Lesenswert?

evtl. geht's so, vielleicht:
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  subi  dco1out0,0x80      ; make signed Wave
7
  subi  dco2out0,0x80
8
  muls  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
9
10
  ; shift 3 times left
11
  lsr   r1
12
  ror   r0
13
  lsr   r1
14
  ror   r0
15
  lsr   r1
16
  ror   r0
17
  
18
  ; make unsigned 12bit
19
  subi  r1, 0x88
20
21
  ; save Result
22
  movw dco1out1:dco1out0, r1:r0      
23
  
24
  sts   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
25
  sts   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

von Rolf D. (rolfdegen)


Lesenswert?

Der Compiler meckert immer bei "subi  r1, 0x88"

Meldung: Error  1  register number above 15 required

Dieser Befehl funktioniert nur mit den oberen 16 Registern.


Ich hab es jetzt so geschrieben:
1
Ringmod:
2
  subi  dco1out0,0x80      ; make signed Wave
3
  subi  dco2out0,0x80
4
  muls  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
5
6
  ; shift 3 times left
7
  lsr   r1
8
  ror   r0
9
  lsr   r1
10
  ror   r0
11
  lsr   r1
12
  ror   r0
13
  
14
  ; make unsigned 12bit
15
  //subi  r1, 0x88
16
17
  ; save Result
18
  //movw dco1out1:dco1out0, r1:r0      
19
  
20
  movw  dco1out0,r0
21
  subi  dco1out1,0x88
22
  sts   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
23
  sts   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

von Maik M. (myco)


Lesenswert?

aja... wohl weil das nicht auf dem Register erlaubt ist. Vielleicht so:
1
//-------------------------------------------------------------------
2
// Ringmodulation Sample1 (dco1out0 8Bit) * Sample2 (dco2out0 8Bit)
3
// Multiplikationsergebnis durch 16 teilen für 12Bit Ausgabe auf DAC
4
//-------------------------------------------------------------------
5
  Ringmod:
6
  subi  dco1out0,0x80      ; make signed Wave
7
  subi  dco2out0,0x80
8
  muls  dco1out0, dco2out0    ; Multipl signed DCO1_out * DCO2_out
9
10
  ; shift 3 times left
11
  lsr   r1
12
  ror   r0
13
  lsr   r1
14
  ror   r0
15
  lsr   r1
16
  ror   r0
17
  
18
  ; save Result
19
  movw dco1out1:dco1out0, r1:r0   
20
21
  ; make unsigned 12bit
22
  subi  dco1out1, 0x88   
23
  
24
  sts   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
25
  sts   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

Edit: ja, so wie du's jetzt ergänzt hast, ist's genau wie ich es hier 
vorgeschlagen habe.

von Rolf D. (rolfdegen)


Lesenswert?

Danke Maik für deine tolle Unterstützung. Ich sach mal Schüß bis zum 
nächsten Problem :) und schönen Sonntag noch.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich komme einfach nicht weiter in Bezug auf die Tune-Funktion des 
Oszillators in meinem AVR-Synthi.

Um die Midi-Note 1-127 in eine Tonfrequenz umzuwandeln greife ich auf 
eine 16Bit Tabelle mit 127 Frequenzwerten im Flash-Speicher des Xmegas 
zu. Wenn ich zB Oszillator2 eine Oktave tiefer stellen möchte, dann 
teile ich einfach den Frequenzwert der Midi-Note. Funktioniert auch 
problemlos und über alle Oktaven sehr genau. Aber wie kann ich den 
Oszillator um einen Halbton verstellen. Ich möchte später mit der 
Tune-Funktion den Oszillator um +-24 Halbtöne verstellen können. Alle 
meine Berechnungen liefern "Krumme Werte" so das eine genaue Einstellung 
nicht möglich ist.

1
//***********************************************
2
// Frequenz_Tune
3
// Wiedergabefrequenz mit Tune-Werten berechnen
4
// 
5
// noten_nr = Midi-Key_Nr.
6
//***********************************************
7
void frequency_tune()
8
{
9
     frequenz = pgm_read_word (&(midi_frequenz[noten_nr]));
10
     schrittweite1 = (__uint24) 411 * frequenz;  // Phasendelta für Oszillator1
11
     
12
     schrittweite2 = (__uint24) 411 * frequenz >> 1; Phasendelta für Oszillator2 (eine Oktave niedriger)



Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich hab das jetzt mal so gelöst:
1
//***********************************************
2
// Frequenz_Tune
3
// Wiedergabefrequenz mit Tune-Werten berechnen
4
//***********************************************
5
void frequency_tune()
6
{
7
     frequenz = pgm_read_word (&(midi_frequenz[noten_nr]));
8
     schrittweite1 = (__uint24) 411 * frequenz;
9
     print_16bit_number(frequenz,20,20,3);
10
  
11
  uint8_t halbton = 8;
12
  uint32_t temp_schrittweite2 = 0;   
13
     temp_schrittweite2 = (uint32_t)schrittweite1 >> 1;
14
     temp_schrittweite2 = (uint32_t)temp_schrittweite2 / 12;
15
     temp_schrittweite2 = (uint32_t)temp_schrittweite2 * halbton;
16
     schrittweite2 = (__uint24) schrittweite1 + temp_schrittweite2;

Um die Rundungen bei der Berechnung der Schrittweite2 (Phasendelta) für 
Oszillator2 so gering wie möglich zu halten, habe ich den Zahlenwert auf 
32Bit erhöht.

Gruß Rolf

von Maik M. (myco)


Lesenswert?

Du gehst die Sache sehr Ressourcenfressend an. Ich habe diesen Teil bei 
meinem Synth auch in Assembler gemacht. Es ist nicht kompliziert, und 
man kann mit der richtigen Technik auch sehr viel Ressourcen sparen. Bei 
mir schaut das ungefähr so aus:

Ich habe 1 Table, der enthält 14 Akkumulatoren-Deltas, nennen wir ihn 
mal "PitchTable". Der erste Wert ist das Delta für B-1, der 14. Wert ist 
für das C+1, dazwischen sind endsprechend die anderen Noten-Werte.

Eingänge sind: inNote(0..127), inSemi(-24..24), inFine(-128..127)
Ausgang ist outPitch
1
fNote = inNote + inSemi;
2
if (fNote & 0x80)fNote = 0;// <-- Überschlag vermeiden
3
fOctave = fNote / 12;      // <-- Ganzzahlig
4
fPitchIndex = fNote % 12;  // <-- Ganzzahlig
5
fPitch1 = PitchTable[fPitchIndex+1] << fOctave;
6
fPitch2 = PitchTable[fPitchIndex+(inFine>0) ? 2 : 0] << fOctave;
7
fFineByte = abs(inFine) << 1;
8
outPitch = ( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;

Das is Pseudocode. Aber die Voregehensweise ist im Groben: Oktave werden 
geschiftet, Semi einfach ganz am Anfang auf die Notennummer addiert, 
Fine wird linear zwischen zwei benachbarten Akkumulatoren-Werten 
interpoliert.

von Maik M. (myco)


Lesenswert?

Ah Käse, geht noch fixer:
1
fNote = inNote + inSemi;
2
if (fNote & 0x80)fNote = 0;// <-- Überschlag vermeiden
3
fOctave = fNote / 12;      // <-- Ganzzahlig
4
fPitchIndex = (fNote % 12) + 1;  // <-- Ganzzahlig
5
fPitch1 = PitchTable[fPitchIndex];
6
fPitch2 = PitchTable[fPitchIndex+(inFine>0) ? 1 : -1];
7
fFineByte = abs(inFine) << 1;
8
outPitch = ( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;
9
outPitch <<=fOctave;

von Rolf D. (rolfdegen)


Lesenswert?

Danke für deine Hilfe. Werde deinen Vorschlag ausprobieren und wenns 
klappt oder auch nicht noch einmal hier melden.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Maik

Die Routine funktioniert leider nicht so wie sie soll. Als Ergebnis 
erhalte ich immer Frequenzen im Bereich von 0-5Hz über die spielbaren 
Oktaven.


Mein Code:
1
//*********************************************
2
//
3
//   PhaccuDelta-Value from Midi Note-Nr. 0-11
4
//
5
//   Phaccu_Delta = 411 * Midi-Note Frequenz
6
//
7
//*********************************************
8
uint16_t phaccu_delta [14] = { 
9
  3171,    // B-1
10
  3360,    // C1  // Midi-Note 0-11
11
  3560,
12
  3771,
13
  3996,
14
  4233,
15
  4485,
16
  4752,
17
  5034,
18
  5334,
19
  5651,
20
  5987,
21
  6343,
22
  6720      // B+1            
23
};
24
25
26
//***********************************************
27
// Frequenz_Tune
28
// Wiedergabefrequenz mit Tune-Werten berechnen
29
//***********************************************
30
void frequency_tune()
31
{
32
    uint8_t fNote;
33
    uint8_t inNote = noten_nr;
34
    char inSemi = 0;
35
    char inFine = 0;
36
    uint8_t fFineByte = 0;
37
    char fOctave = 0;
38
    uint8_t fPitchIndex;
39
    __uint24 fPitch1;
40
    __uint24 fPitch2;
41
    __uint24 outPitch;
42
         
43
    fNote = inNote + inSemi;
44
    if(fNote & 0x80) fNote = 0;
45
    fOctave = fNote / 12;
46
    fPitchIndex = (fNote % 12) + 1;
47
    fPitch1 = phaccu_delta[fPitchIndex];
48
    fPitch2 = phaccu_delta[fPitchIndex + (inFine > 0) ? 1 : -1];
49
    fFineByte = abs(inFine) << 1;
50
    outPitch = ( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;
51
    outPitch <<=fOctave;
52
    schrittweite1 = (__uint24)outPitch;

Änder ich die Zeile mit Null shift so ab:
1
outPitch = ( fPitch1 * (255-fFineByte) ) >> 0 + ( fPitch2 * (fFineByte) ) >> 8;
erhalte ich fast die richtige Frequenzen (A = 438.5 Hz).
Der Wert für die Oktavierung funktioniert leider auch nicht und hat 
keine Auswirkungen auf die Wiedergabefrequenz.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Das mit der Oktavierung war eine falsche Aussage von mir. Ich sehe 
gerade das eine Oktavierung nur über den Semiton-Werte funktioniert. 
Also Semiton-Wert zb "12" wäre eine Oktave höher und "-12" eine Oktave 
niedriger.

von Maik M. (myco)


Lesenswert?

Ich habe so meine Probleme mit C/C++. Da muss man sehr auf die 
Typenbreite achten, besonders bei dieser Zeile:
1
outPitch = ( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;

Ich glaube C/C++ rechnet hier in 24bit, die Multiplikation aus 24bit mit 
8bit ergibt allerdings 32bit und der Compiler convertiert das runter 
indem er die höheren (wichtigeren) 8bit weglässt. Das müsste irgendwie 
mit Typecasting lösbar sein, allerdings bin ich da nicht so Fit. Evtl. 
geht es so:
1
outPitch = uint24_t(( (uint32_t)fPitch1 * (255-fFineByte) ) >> 8 + ((uint32_t)fPitch2 * (fFineByte) ) >> 8);

von Rolf D. (rolfdegen)


Lesenswert?

Ich teste es jetzt.

von Rolf D. (rolfdegen)


Lesenswert?

Ne.. leider kein Erfolg. Frequenz immer noch auf 0-32Hz

von Rene B. (themason) Benutzerseite


Lesenswert?

@Maik,

aber das lineare Interpolieren zwischen zwei Halbton-Pitches müsste doch 
eigentlich fehlerhaft sein da es ja eine Exponentialfunktion ist die die 
Frequenzen zwischen den Oktaven und auch entsprechend den Halbtönen 
bestimmt. Wie genau das Ohr diese unterschiede wahrnehmen kann weiß ich 
nicht, aber ich denke das man bei ner abweichung von 50cent schon 
hörbare Frequenzunterschiede wahrnehmen müsste zwischen tatsächlicher 
Frequenz und interpolierter Frequenz.
Ansonsten ist das Verfahren ja richtig und auch recht platzsparend. Ich 
wär bzw bin ganz bruteral mit ner Tabelle über 120 Halbtöne und 8/16/32 
Abstufungen drangegangen, aber das ist im Prinzip ja quatsch, da sich 
die Oktaven ja durch Shiften bilden lassen, und man dann von den 
höchsten Inkrementen bzw Schrittweiten ausgeht und runtershiftet.

von Maik M. (myco)


Lesenswert?

Was passiert, wenn du die Zeile:
1
outPitch = ( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;

durch diese ersetzt:
1
outPitch = fPitch1;

bzw:
1
outPitch = fPitch2;

von Rolf D. (rolfdegen)


Lesenswert?

Ja das wollte ich gerade machen.

 outPitch = (__uint24)fPitch1 << fOctave; = 440,1Hz
 outPitch = (__uint24)fPitch2 << fOctave; = 261,6Hz

von Maik M. (myco)


Lesenswert?

Rene B. schrieb:
> @Maik,
>
> aber das lineare Interpolieren zwischen zwei Halbton-Pitches müsste doch
> eigentlich fehlerhaft sein da es ja eine Exponentialfunktion ist die die
> Frequenzen zwischen den Oktaven und auch entsprechend den Halbtönen
> bestimmt.

Ja im Prinzip ist es falsch, aber man muss halt Kompromisse eingehen. 
Zur Not könnte man einen Exponential-Tabelle nutzen, aber richtig 
berechnen kann man das auf einem AVR nicht.

von Maik M. (myco)


Lesenswert?

Rolf Degen schrieb:
> Ja das wollte ich gerade machen.
>
>  outPitch = (__uint24)fPitch1 << fOctave; = 440,1Hz
>  outPitch = (__uint24)fPitch2 << fOctave; = 261,6Hz

ja, dann hat es irgendwas mit der Typenkonvertierung in der Zeile zu 
tun. Wie gesagt, das war nie mein Ding :)

von Maik M. (myco)


Lesenswert?

Ohne Typkonvertierung könnte es so gehen:
outPitch = ( (fPitch1>>8) * (255-fFineByte) ) + ( (fPitch2>>8) * 
(fFineByte) );

Allerdings produziert das massive Rundungsfehler

von Rolf D. (rolfdegen)


Lesenswert?

Damit ändern sich die Notenwerte in einer Oktave nicht mehr. Sie bleiben 
gleich und verdoppeln sich bei der nächsten Oktave.

von Maik M. (myco)


Lesenswert?

Vielleicht geht's ja so:
1
//*********************************************
2
//
3
//   PhaccuDelta-Value from Midi Note-Nr. 0-11
4
//
5
//   Phaccu_Delta = 411 * Midi-Note Frequenz
6
//
7
//*********************************************
8
uint16_t phaccu_delta [14] = { 
9
  3171,    // B-1
10
  3360,    // C1  // Midi-Note 0-11
11
  3560,
12
  3771,
13
  3996,
14
  4233,
15
  4485,
16
  4752,
17
  5034,
18
  5334,
19
  5651,
20
  5987,
21
  6343,
22
  6720      // B+1            
23
};
24
25
26
//***********************************************
27
// Frequenz_Tune
28
// Wiedergabefrequenz mit Tune-Werten berechnen
29
//***********************************************
30
void frequency_tune()
31
{
32
    uint8_t fNote;
33
    uint8_t inNote = noten_nr;
34
    char inSemi = 0;
35
    char inFine = 0;
36
    uint8_t fFineByte;
37
    uint8_t fOctave;
38
    uint8_t fPitchIndex;
39
    uint16_t fPitch1;
40
    uint16_t fPitch2;
41
    int16_t fPitchDiff;
42
    __uint24 outPitch;
43
         
44
    fNote = inNote + inSemi;
45
    if(fNote & 0x80) fNote = 0;
46
    fOctave = fNote / 12;
47
    fPitchIndex = (fNote % 12) + 1;
48
    fPitch1 = phaccu_delta[fPitchIndex];
49
    fPitch2 = phaccu_delta[fPitchIndex + (inFine > 0) ? 1 : -1];
50
    fPitchDiff = (int16_t) (fPitch2-fPitch1);
51
    fFineByte = ((uint8_t)(abs(inFine))) << 1;
52
    outPitch = (__uint24)(((((int32_t)fPitch1)<<8) + ((int32_t)fPitchDiff*(int32_t)fFineByte)) >> 8);
53
    outPitch <<=fOctave;
54
    schrittweite1 = outPitch;
55
...

von Rolf D. (rolfdegen)


Lesenswert?

Ich habe das Programm etwas abgeändert und es kommen jetzt zumindest die 
richtigen Frequenzen heraus. Allerdings funktioniert es mit 
"inFine"-Werten noch nicht.
1
//***********************************************
2
// Frequenz_Tune
3
// Wiedergabefrequenz mit Tune-Werten berechnen
4
//***********************************************
5
void frequency_tune()
6
{
7
    uint8_t fNote;
8
    uint8_t inNote = noten_nr;
9
    char inSemi = 0;
10
    char inFine = 10;
11
    uint8_t fFineByte = 0;
12
    uint8_t fOctave = 0;
13
    uint8_t fPitchIndex;
14
    uint16_t fPitch1;
15
    uint16_t fPitch2;
16
    __uint24 outPitch;
17
         
18
    fNote = inNote + inSemi;
19
    if(fNote & 0x80) fNote = 0;
20
    fOctave = fNote / 12;
21
    fPitchIndex = (fNote % 12) + 1;
22
    fPitch1 = phaccu_delta[fPitchIndex];
23
    fPitch2 = phaccu_delta[fPitchIndex + 1];// (inFine > 0) ? 1 : -1];
24
    fFineByte = abs(inFine) << 1;
25
    outPitch = (__uint24)( fPitch1 * (255-fFineByte) ) >> 8 + ( fPitch2 * (fFineByte) ) >> 8;    
26
    outPitch = (__uint24)fPitch2 << fOctave;
27
    schrittweite1 = outPitch;


Ups.. du warst schneller. Ich werde deine Programm jetzt testen.

von Rolf D. (rolfdegen)


Lesenswert?

Dein Programm funktioniert soweit. Nur bei den inFine-Werten stimmt was 
nicht. Ich bekomm bei positiven und negativen Werten immer eine niedrige 
Frequenzen heraus.

Zum Beispiel:
inFine =  0  = 440Hz
inFine =  10 = 426Hz
inFine = -10 = 426Hz

von Maik M. (myco)


Lesenswert?

ups ... Auskommtierung vergessen

ersetze
1
fPitch2 = phaccu_delta[fPitchIndex + 1];// (inFine > 0) ? 1 : -1];

durch
1
fPitch2 = phaccu_delta[fPitchIndex + (inFine > 0) ? 1 : -1];

von Rolf D. (rolfdegen)


Lesenswert?

Die Programmzeile hatte ich bereits wieder geändert. Ich habe mir den 
fPitch2 Wert mal angesehen. Der Wert (3360) ist bei inFine = +10 bei 
jeder Midi-Note gleich groß.

von Maik M. (myco)


Lesenswert?

Das kann nicht sein, der müsste sich bei jeder Note um 1 Index 
verschoben zu Pitch1 bewegen.

von Rolf D. (rolfdegen)


Lesenswert?

Midi-Note = 440Hz (Messung: 440Hz)
inFine = 0
fPitch1 = 5651
fPitch2 = 3360
fPitchDiff = 63245


Midi-Note = 440Hz (Messung: 426.3Hz)
inFine = 10
fPitch1 = 5651
fPitch2 = 3360
fPitchDiff = 63245


Midi-Note = 440Hz (Messung: 426.1Hz)
inFine = -10
fPitch1 = 5651
fPitch2 = 3360
fPitchDiff = 63245

von Rene B. (themason) Benutzerseite


Lesenswert?

Also das die beiden fPitch's bei +10 und -10 cent diesselben sind kann 
ja nicht sein. fPitch2 müsste ja ggü fPitch1 den Pitch für einen Halbton 
unter fPitch1 liegen, oder ?

von Maik M. (myco)


Lesenswert?

argh... auf ein Neues...
1
//*********************************************
2
//
3
//   PhaccuDelta-Value from Midi Note-Nr. 0-11
4
//
5
//   Phaccu_Delta = 411 * Midi-Note Frequenz
6
//
7
//*********************************************
8
uint16_t phaccu_delta [14] = { 
9
  3171,    // B-1
10
  3360,    // C1  // Midi-Note 0-11
11
  3560,
12
  3771,
13
  3996,
14
  4233,
15
  4485,
16
  4752,
17
  5034,
18
  5334,
19
  5651,
20
  5987,
21
  6343,
22
  6720      // B+1            
23
};
24
25
26
//***********************************************
27
// Frequenz_Tune
28
// Wiedergabefrequenz mit Tune-Werten berechnen
29
//***********************************************
30
void frequency_tune()
31
{
32
    uint8_t fNote;
33
    uint8_t inNote = noten_nr;
34
    char inSemi = 0;
35
    char inFine = 0;
36
    uint8_t fFineByte;
37
    uint8_t fOctave;
38
    uint8_t fPitchIndex;
39
    uint16_t fPitch1;
40
    uint16_t fPitch2;
41
    int16_t fPitchDiff;
42
    __uint24 outPitch;
43
         
44
    fNote = inNote + inSemi;
45
    if(fNote & 0x80) fNote = 0;
46
    fOctave = fNote / 12;
47
    fPitchIndex = (fNote % 12);
48
    fPitch1 = phaccu_delta[fPitchIndex+1];
49
    if (inFine > 0)fPitchIndex+=2;
50
    fPitch2 = phaccu_delta[fPitchIndex];
51
    fPitchDiff = (int16_t) (fPitch2-fPitch1);
52
    fFineByte = ((uint8_t)(abs(inFine))) << 1;
53
    outPitch = (__uint24)(((((int32_t)fPitch1)<<8) + ((int32_t)fPitchDiff*(int32_t)fFineByte)) >> 8);
54
    outPitch <<=fOctave;
55
    schrittweite1 = outPitch;
56
...

von Rolf D. (rolfdegen)


Lesenswert?

Ja es funktioniert jetzt. Prima :) Der Notenwerte liegen zwar jetzt 
etwas höher A 440Hz = gemessen 440,5 aber das ist ok. Kann man mit dem 
inFine-Wert -1 aber korregieren.

Danke für deine großartige Hilfe. Das Ganze bringt mich in meinem 
Projekt wieder einen großen Schritt nach vorne.

Schönen Tag noch und lieben Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe Heute die Menü-Seite für die DCO-Einstellung fertig gestellt 
(siehe Bild). Jeder Oszillator kann in +-24 Semitone-Schritten 
(entspricht +- 2 Oktaven) verstellt werden. Zusätzlich kan man mit der 
Fine-Einstellung (Schrittweite +-100 Cent) den Oszillator zwischen zwei 
Halbtönen verstimmen. Mit den Tasten "+" und "-" ist außerdem eine 
genauere Einstellung der Parameter möglich.

Nochmals besten Dank an Maik. Ohne seine großartige Unterstützung hätte 
es nicht funktioniert.


Bild: DCO-Einstellung im AVR-Synthi

MfG Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Damits hier nicht zu langweilig wird, gibts zur Abwechslung ein paar 
Demo-Sound. Was in den Sounds noch fehlt, ist die Filter und 
Amplituden-Modulation sowie FM und Synchronisation der Oszillatoren.

AVR-Synthi Demo-Sounds
Link: http://soundcloud.com/rolfdegen/avr-demo-31102012

von Rene B. (themason) Benutzerseite


Lesenswert?

Sehr schönes Demo.

Vor allem gefällt mir der Sound ab 11:30.
Aber ist der Filter wirklich noch nicht mir drin ? Tlw klingt es ja 
schon so :-)
Aber echt sehr schön gemacht. Weiter so. Bin mal gespannt auf die 
restlichen Features wie Ringmod/Sync/FM und eben alles noch mit Filtern 
zusammen :-)

von Rolf D. (rolfdegen)


Lesenswert?

Ne der Filter wird z.Zt. mit dem ADSR-Werten gesteuert.

von Rolf Degen (Gast)


Lesenswert?

Hallo

Ich bin gerade dabei die Sync-Funktion für die Oszillatoren zu 
programmieren. Ich weis allerdings nicht ob mein Ansatz richtig ist 
(siehe Code).
1
//===============================================================
2
// SUBTRAKTIVE KLANGSYSYNTHESE
3
//===============================================================
4
5
SubSynthese:
6
7
//---------------------------------------------------------------
8
// DCO-1 
9
//   * 24-Bit Akku-Breite
10
//   * 24-Bit Phasen-Delta (2,384185mHz/Unit)
11
//   * 8-Bit Sample
12
//---------------------------------------------------------------
13
14
  // Phasen-Akku1 incrementieren
15
  // ----------------------------
16
17
  LDS   delta0, schrittweite1+0  ; 2   Phasen-Delta1 aus SRAM laden
18
  LDS   delta1, schrittweite1+1  ; 2
19
  LDS   delta2, schrittweite1+2  ; 2
20
21
  LDS   phakku0, phaccu1+0       ; 2   Phasen-Akku1 aus SRAM laden
22
  LDS   phakku1, phaccu1+1       ; 2
23
  LDS   phakku2, phaccu1+2       ; 2
24
25
  ADD   phakku0, delta0          ; 1   Phasen-Akku1 + Phasen-Delta1
26
  ADC   phakku1, delta1          ; 1
27
  ADC   phakku2, delta2          ; 1
28
29
  // DCO2 sync
30
  BRCC  test_01           ;     setze Phasen-Akku2 auf null wenn Phasen-Akku1 Überlauf
31
  CLR   r21
32
  STS   phaccu2+0, r21
33
  STS   phaccu2+1, r21
34
  STS   phaccu2+2, r21 
35
   
36
  test_01:
37
  STS   phaccu1+0, phakku0       ; 2   Phasen-Akku1 in SRAM zurückschreiben
38
  STS   phaccu1+1, phakku1       ; 2
39
  STS   phaccu1+2, phakku2       ; 2
40
  
41
42
43
  // Basis-Adresse für Wavetable laden
44
  // -------------------------------------------------
45
  LDS   R30, wavetable1+0        ; 1   Startadr. Wave-Table (Low-Byte)
46
  LDS   R31, wavetable1+1        ; 1                        (High-Byte)
47
48
  // Sample1 aus Wavetable laden (8Bit Auflösung)
49
  // ------------------------------------------------------------------
50
  BL_Wave1:
51
  clr   R21
52
  ADD   R30, phakku2       ; 1   Adresse Sample-Nr.
53
  ADC   R31, r21         ; 1
54
  LPM   dco1out0, Z+             ; 3   Sample aus Wavetable laden (8-Bit)
55
  LPM   dco1out1, Z              ; 3 
56
  clr   dco1out1
57
58
59
  // Phasen-Akku2 incrementieren
60
  // ----------------------------
61
  DCO2:
62
  LDS   delta0, schrittweite2+0  ; 2   Phasen-Delta aus SRAM laden
63
  LDS   delta1, schrittweite2+1  ; 2
64
  LDS   delta2, schrittweite2+2  ; 2
65
66
  LDS   phakku0, phaccu2+0       ; 2   Phasen-Akku aus SRAM laden
67
  LDS   phakku1, phaccu2+1       ; 2
68
  LDS   phakku2, phaccu2+2       ; 2
69
70
  ADD   phakku0, delta0          ; 1   Phasen-Akku + Phasen-Delta
71
  ADC   phakku1, delta1          ; 1
72
  ADC   phakku2, delta2          ; 1
73
    
74
  STS   phaccu2+0, phakku0       ; 2   Phasen-Akku in SRAM zurückschreiben
75
  STS   phaccu2+1, phakku1       ; 2
76
  STS   phaccu2+2, phakku2       ; 2
77
78
79
  // Basis-Adresse für Wavetable laden
80
  // -------------------------------------------------
81
  LDS   R30, wavetable2+0        ; 1   Basis-Adresse Saw-Tabelle (Low-Byte)
82
  LDS   R31, wavetable2+1        ; 1                             (High-Byte)
83
84
  // Sample1 aus Wavetable laden
85
  // -------------------------------------------------
86
  BL_Wave2:
87
  clr   R21
88
  ADD   R30, phakku2       ; 1   Adresse Sample-Nr. 
89
  ADC   R31, r21                 ; 1
90
  LPM   dco2out0, Z+             ; 3   Sample aus Wavetable laden (8-Bit)
91
  LPM   dco2out1, Z              ; 3 
92
  clr   dco2out1
93
94
   //-----------------------------------------------------------
95
  // Addition Sample1 + Sample2
96
  //-----------------------------------------------------------
97
  Wave_out:
98
  ADD   dco1out0,dco2out0    ; DCO1_out + DCO2_out
99
  ADC   dco1out1,dco2out1
100
  LSL   dco1out0        ; Ausgabewert auf 12Bit (mul 3) 
101
  ROL   dco1out1
102
  LSL   dco1out0
103
  ROL   dco1out1
104
  LSL   dco1out0
105
  ROL   dco1out1
106
107
  // --------------------------------------------------------------
108
  // 12Bit Ergebnis zum DAC-Converter (DACA Chanal 0)
109
  // --------------------------------------------------------------
110
  DAC_out:
111
  STS   0x0318, dco1out0          ; 2   L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
112
  STS   0x0319, dco1out1          ; 2   H-Byte to DAC Register (CH0DATAH Adr. 0x0319)

Für eine Info wäre ich dankbar.

von Rene B. (themason) Benutzerseite


Lesenswert?

Meine AVR-Assembler sind zwar recht begrenzt, aber im Prinzip müsste es 
so gehen. Sobald ein Überlauf im Phasenakku 1 festegestellt wird, wird 
Phasenakku 2 genullt. Damit wird OSC2 durch OSC1 synchronisiert (was ja 
auch angestrebt ist :-)).

von Rolf D. (rolfdegen)


Lesenswert?

Ja super. Dann werde ich das im Prinzip so und zusätzlich mit einer 
Abfrage  für die Sync-Funktion in meinem Programm implementieren.

Gruß Rolf und schönes Wochenende.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich brauch mal wieder Hilfe. Ich möchte in Assembler auf einen 256 Byte 
großen Ringbuffer in meinem Main-Programm (in C) zugreifen. So wie ich 
es versuche funktioniert es leider nicht. Ein Rat wäre sehr hilfreich. 
Schon mal Danke im Vorraus. LG Rolf


Ring-Buffer (FIFO) in C:
1
//******************************
2
// write data in to FIFO-Buffer
3
//******************************
4
   buf_data = 170;
5
   test_buffer[wrbuf_pointer] = buf_data;      // save data in to buffer
6
   wrbuf_pointer++;                // inc Buffer-Pointer
7
   buf_data = 0;
8
   buf_status = 1;
9
   _delay_ms(10);
10
   print_8bit_number(buf_data,120,70,2);


Lesen eines Bytes aus dem Ringbuffer in der Assembler-Routine und 
anschließend zurückschreiben in buf_data. buf_dat wird im Main-Programm 
ausgewertet.
1
// Buffer Testfunktion
2
  lds  r20, buf_status;      ;    Bufferstatus prüfen (ist 1 wenn Byte vorhanden)
3
  cpi  r20, 1          ;   
4
  brne next            ;    wenn ungleich Sprung zu next
5
  ldi  r20, lo8(rdbuf_pointer)  ;   ein Datenbyte aus dem Buffer lesen 
6
  sts  buf_data, r20      ;    und wieder abspeichern
7
  
8
  next:

von Maik M. (myco)


Lesenswert?

habe zwar von dem gemixe von C und ASM nicht soviel Ahnung, aber die 
Zeile
1
ldi  r20, lo8(rdbuf_pointer)  ;   ein Datenbyte aus dem Buffer lesen

schaut schon merkwürdig aus. Wenn der Ringbuffer im SRAM liegt, müsste 
die Adressierung 16Bit haben. Keine Ahnung was rdbuf_pointer überhaupt 
ist, aber wäre es ein Pointer in den SRAM (Elementindex eingeschlossen 
), dann würdest du mit ldi nur die Hälfte der Addresse bekommen.

Das ist jetzt nur wilde Spekulation, aber vielleicht geht es so:
1
ldi XL, low(rdbuf_pointer)
2
ldi XH, high(rdbuf_pointer) 
3
ld  r20, X

von Rolf D. (rolfdegen)


Lesenswert?

Danke. Werde deinen Vorschlag gleich testen. rdbuf_pointer ist der 
Adresszeiger bein lesen des Buffers und wrbuf_pointer beim schreiben in 
den Buffer.

von Rolf D. (rolfdegen)


Lesenswert?

Funktioniert leider nicht. Bekomme die Fehlermeldung :"Error  1  garbage 
at end of line"


Die Dekleration der Buffer-Variablen sieht bei mir im Main-Programm so 
aus:

// Test-Buffer (Lesezugriff erfolgt in ASM-Teil)
volatile uint8_t test_buffer[256];       // Receive Buffer for Wave-Data
uint8_t wrbuf_pointer = 0;               // Write_Pointer
volatile uint8_t rdbuf_pointer = 0;      // Read_Pointer
volatile uint8_t buf_data = 0;           // Bufferdaten
uint8_t buf_status = 0;                  // buf_status = 1 wenn Daten im 
Buffer


Die Buffer-Funktion soll später für die Soundausgabe in der ASM-Routine 
genutz werden. Die Sounddaten werden alle im Main-Programm vorberechnet 
und im Buffer gespeichert, wo sie dann im ASM-Teil ausgegeben werden.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich konnte es jetzt so lösen:
1
// Buffer Testfunktion
2
  lds  r20, buf_status;      ;    Bufferstatus prüfen (ist 1 wenn Byte vorhanden)
3
  cpi  r20, 1                ;   
4
  brne next                  ;    wenn ungleich Sprung zu next
5
  ldi ZL, lo8(test_buffer)   ;    Startadresse des Test-Buffers laden
6
  ldi ZH, hi8(test_buffer)
7
  lds r17,(rdbuf_pointer)    ;    Position des Lesezeigers laden
8
  add ZL, r17                ;    und zur Startadresse hinzu addieren
9
  ldi r16,0
10
  adc ZH, r16
11
  ld  r20, Z                 ;    ein Byte aus dem Test-Buffer laden
12
  sts  buf_data, r20         ;    und für Testzweck speichern
13
  next:

In ZL+ZH befinden sich die Start-Adresse des Test-Buffer. In r17 die 
Position des Lesezeiger der auf das aktuelle Datenbyte zeigt.

Gruß Rolf

von Maik M. (myco)


Lesenswert?

da war ich doch nah dran... würde mich interessieren, was bei meinem 
falsch war. Das low/high?

von rolf degen (Gast)


Lesenswert?

Ich programmiere unter atmel Studio 6 und der Assembler ist da etwas 
eigen. Statt low/high muss lo8/Hi im Quellcode stehen.

LG Rolf

von Rolf D. (rolfdegen)


Lesenswert?

rolf degen schrieb:
> Ich programmiere unter atmel Studio 6 und der Assembler ist da etwas
> eigen. Statt low/high muss lo8/Hi im Quellcode stehen.
>
> LG Rolf

Ich meine lo8 und hi8

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich habe die Soundausgabe des AVR-Synthis testweise über einen 256 Byte 
großen Ring-Puffer geleitet (siehe Code). Der Puffer wird im 
Main-Programm (siehe Code) ständig mit Sample-Daten aus einer 8Bit 
Sinus-Tabelle befüllt und in der Interruptroutine für die Soundausgabe 
geleert.

Soweit funktioniert das auch ganz nett. Aber sobald ich Eingaben und 
andere Dinge auf dem Touch-Display mache, bekommt der Puffer nicht mehr 
genug Daten und es treten Fehler in der Soundausgabe auf.

Viele Funktionen für das Touch-Display benötigen mehr Zeit als der 
Puffer es erlaubt. Die maximale Pufferzeit beträgt 6.4 msec bis der 
Puffer leer ist. In der Main-Schleife wird ständig der Füllstand geprüft 
und nach Bedarf wieder gefüllt. Wenn der Prozessor aber z.Zt. mit 
anderen Dingen wzB mit der Display-Ausgabe und Auswertung der 
Touch-Eingaben beschäftigt ist, läuft der Puffer leer und kann nicht 
rechtzeitig wieder befüllt werden.

Man müsste jetzt also hergehen und in den Display-Routinen eine 
Füllstandsabfrage des Puffers integrieren. Sobald die Füllstandsanzeige 
den "Beinahe"-Leerstand signalisiert, wird die Display-Routine 
unterbrochen und der Puffer wieder befüllt. Mal schaun wie ich das 
umsetze. Das Ganze müsste dann später genauso mit den Routinen für die 
Soundberechnung gemacht werden. Da kommt Freude auf..


ASM-Code: Ring-Puffer für die Soundausgabe
1
//**************************************************************
2
//             ATMEL Studio 6 Assembler-Routine 
3
//              Soudausgabe auf DACA Chanal 0
4
// Timer1 Interruptroutine: alle 25usec = 40.0 KHz Samplerate
5
//      
6
//             (CPU ATxmega128A1 Clock 32MHz)
7
// 
8
// Testversion Sound-Puffer  66 Prozessorzyklen = 2,062 µsec
9
//
10
//**************************************************************
11
12
  #include "avr/io.h"
13
14
  .extern sound_out               // Name der Assembler-Funktion
15
  .global TCC1_OVF_vect           // Timer1 Interrupt-Vektor
16
17
//---------------------------------------------------------------
18
// Definition und verwendete Prozessor-Register
19
//---------------------------------------------------------------
20
21
temp     = 16   ; R15 Temp-Register für Berechnungen  
22
sample_low   = 17  ; R16 Sample Low-Byte
23
sample_high  = 18   ; R17 Sample High-Byte    
24
25
//---------------------------------------------------------------
26
// Prozessor-Register inkl. Status-Register sichern
27
// Interrupt-Routine Timer1-Overflow (40.000Hz)
28
//---------------------------------------------------------------
29
30
TCC1_OVF_vect:           
31
  PUSH  R0              ; 2   R0  auf Stack schieben
32
  IN    R0, SREG          ; 1   Status-Register über bereits gesichertes
33
  PUSH  R0              ; 2   R0 auf Stack schieben
34
  PUSH  R1              ; 2   R1  auf Stack schieben
35
  PUSH  R16              ; 2   R16 auf Stack schieben 
36
  PUSH  R17              ; 2   R17 auf Stack schieben
37
  PUSH  R18              ; 2   R18 auf Stack schieben
38
  PUSH  R30              ; 2   R30 auf Stack schieben (ZL)
39
  PUSH  R31              ; 2   R31 auf Stack schieben (ZH)
40
                  ; 17  Zyklen
41
  //------------------------------------------------------------
42
  // Sample aus dem Ring-Puffer laden 
43
  //------------------------------------------------------------
44
  ldi  ZL, lo8(sample_puffer)    ; 1  Puffer-Startadr. laden
45
  ldi  ZH, hi8(sample_puffer)    ; 1  
46
  lds  temp,(rd_pointer)      ; 2  Puffer-Lesezeiger laden
47
  add  ZL, temp            ; 1  und als Offset zur Puffer-Startadr. addieren
48
  ldi  temp,0            ; 1
49
  adc  ZH, temp            ; 1
50
  ld   sample_low, Z        ; 3  lade Datenwert in R16
51
  ldi  sample_high, 0        ; 1  lösche High-Byte im Sample-Word
52
                  ; 11 Zyklen
53
  //-----------------------------------
54
  // 8Bit Sample auf 12Bit erhöhen
55
  // Multiplikation mit 16
56
  //-----------------------------------
57
  
58
  LSL   sample_low          ; 1  Ausgabewert auf 12Bit (mul 16) 
59
  ROL   sample_high          ; 1
60
  LSL   sample_low          ; 1
61
  ROL   sample_high          ; 1
62
  LSL   sample_low          ; 1
63
  ROL   sample_high          ; 1
64
  LSL   sample_low          ; 1
65
  ROL   sample_high          ; 1
66
                  ; 8 Zyklen
67
  //------------------------------------
68
  // Sample-Ausgabe auf 12Bit DAC
69
  //------------------------------------
70
71
  STS   0x0318, sample_low          ; 2  L-Byte to DAC-Register (CH0DATAL Adr. 0x0318)
72
  STS   0x0319, sample_high         ; 2  H-Byte to DAC Register (CH0DATAH Adr. 0x0319)
73
                  ; 4  Zyklen
74
  //-------------------------------------
75
  // Puffer-Lesezeiger inc
76
  //-------------------------------------
77
78
  lds temp,rd_pointer        ; 2  Puffer-Lesezeiger inc
79
  inc temp              ; 1
80
  sts rd_pointer, temp        ; 2  und sichern
81
                  ; 5  Zyklen
82
  
83
   // --------------------------------------------------------------
84
  // Prozessor-Register inkl. Status-Register wiederherstellen
85
  // --------------------------------------------------------------
86
  POP   R31              ; 2   R31 von Stack wiederherstellen (ZH)
87
  POP   R30              ; 2   R30 von Stack wiederherstellen (ZL)
88
  POP   R18              ; 2   R18 von Stack wiederherstellen
89
  POP   R17              ; 2   R17 von Stack wiederherstellen
90
  POP   R16              ; 2   R16 von Stack wiederherstellen
91
  POP   R1              ; 2   R1  von Stack wiederherstellen
92
  POP   R0              ; 2   Status-Register über R0 wieder
93
  OUT   SREG, R0          ; 1   herstellen
94
  POP   R0              ; 2   R0 von Stack wiederherstellen
95
  RETI                ; 4   Return Interrupt und I-Flag quittieren
96
                  ; 21  Zyklen
97
// --------------------------------------------------------------
98
.end
99
//



C-Code: Puffer-Funktion in der Main-Programm Schleife
1
//------------------------------------ Main-Loop ---------------------------------------
2
3
  while(1)
4
  {    
5
    
6
    //-----------------------------------------------------
7
    // Wenn sich Sample-Puffer leert, dann 
8
    // Daten aus der Sinus-Tabelle nach schieben
9
    //-----------------------------------------------------
10
      
11
    while (rd_pointer != wr_pointer)              // Wenn beide Puffer-Zeiger ungleich           
12
    {                              // dann ist freier Platz im Puffer 
13
      buf_data = pgm_read_byte (&(sinus_8Bit[sample_index])); // Sample aus Sinus-Tabelle laden
14
      sample_puffer[wr_pointer] = buf_data;          // Sample in Puffer schreiben
15
      wr_pointer++;
16
      if (sample_index < 255)
17
      {
18
        sample_index++;
19
      }
20
      else sample_index = 0;
21
    }
22
    
23
    //_delay_ms(6);      // maximale Wartezeit bis Puffer leer ( ein Sample 25µsec * 256 = 6,4msec)
24
    
25
    get_encoder();      // Drehgeber abfragen
26
    touch_panel();      // Touch-Panel abfragen    
27
    mididata_avail();    // Prüfe ob Midi-Daten im Empfangspuffer
28
    midi_play();            // Midi-Daten spielen
29
    
30
  }
31
}
32
 
33
//*********************************** END Program **************************************



Noch ein Tip. Wer eine sehr gute Befehlsbeschreibung der AVR-Befehle für 
die Assembler-Programmierung benötig findet diese hier: 
http://www.avr-roboter.de/controller/befehle/beschreibung/beschreibung.html

Gruß Rolf

von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Wie wäre es wenn du in der Main Loop das Funktionskonglomerat 
"get_encoder, touch_panel, mididata_available, midi_play" immer nur pro 
durchlauf einmal aufrufst.
Quasi eine Statemachine die erst get_encoder, dann touch_panel, dann 
mididata_available und dann midi_play aufruft ?

also etwa so :

  char state = 1;

  while (1)
  {

    while (rd_pointer != wr_pointer)
    {
      ...
    }

    switch (state)
    {
      case 1 : state = 2; get_encoder (); break;
      case 2 : state = 3; touch_panel (); break;
      case 3 : state = 4; mididata_available (); break;
      case 4 : state = 1; midi_play (); break;
    }

  }

Ich weiß zwar nicht wie lange die einzelnen Funktionen brauchen, aber 
vllt bietet es sich an längere Funktionen (vor allem wenn Verzögerungen 
im Spiel sind) ebenfalls über eine Statemachine zu realisieren. Der 
Vorteil ist das du dann nur dann was machen mußt, wenn auch wirklich was 
zu tun ist, und du ersparst dir so Wartezeiten die den Prozi dann 
komplett blockieren. Ein weiterer Nebeneffekt ist das solche 
"Salami"-Funktionen eine gewisse Nebenläufigkeit mitbringen. Sprich : Es 
wird quasi ein eigener "Task" daraus, der je nachdem wie er programmiert 
ist eben keine anderen Aufgaben blockiert.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Rene

Ich hab das vorläufig etwas anders gelöst. Der Hinweis von Franz und 
Wolfgang aus dem CC2-Forum war die Lösung. Ich habe in die Routine für 
das Senden der Daten zum Display eine Abfrage für den Soundpuffer 
integriert (siehe Code). Jetzt funktioniert die gleichzeitige 
Display-Steuerung und Soundausgabe ohne Probleme. Verzögerungen bei der 
Ansteuerung des Displays sind mir kaum aufgefallen.


Code: Routine zum Senden der Daten ans Display
1
//**************************************
2
// Ein Byte über SPI zum Display senden
3
// SPI Datenrate 2MHz
4
// *************************************
5
void spi_send (unsigned char data)
6
{
7
    fuellstand = wr_pointer - rd_pointer;        // Füllstand Soundpuffer prüfen
8
    if (fuellstand < 50)                        // wenn < 50 Soundpuffer füllen
9
    {
10
        sound_puffer();
11
    }
12
    else _delay_us(100);                        // wenn Soundpuffer nicht befüllt wird,
13
                                                // dann warte 100µsec bis Display bereit für den Datenempfang
14
                                                // (nur notwendig wenn SPI-Datentransfer schneller als 100KHz)
15
    
16
    SPIC.DATA = data;                            // ein Byte zum Display senden
17
    while(!(SPIC.STATUS & (1 << SPI_IF_bp))){}    // wartet ca. 4µsec bis Byte gesendet wurde
18
}


Soundpuffer Routine
1
//---------------------------------------------
2
// Sound-Puffer füllen
3
//---------------------------------------------
4
void sound_puffer()
5
{ 
6
  uint8_t i;            // Anzahl der Samples für die Befüllung
7
  uint8_t sample;        // Sample aus der Sinus-Tabelle 
8
  
9
  for (i=0;i<200;i++)
10
  {
11
      sample = pgm_read_byte (&(sinus_8Bit[sample_index]));    // Sample aus Sinus-Tabelle laden
12
      sample_puffer[wr_pointer] = sample;                    // Sample in Puffer schreiben
13
      wr_pointer++;                                            // Schreibzeiger des Soundpuffers +1
14
      sample_index++;                                        // Sample-Index für Datenposition in Sinustabelle inc
15
      PORTA.OUT |= (1<<PIN0);                                // Für Testzweck: Portbit High
16
      PORTA.OUT &= ~ (1<<PIN0);                                //                Portbit Low
17
  }
18
}

Bild 1:
Kanal 1 (Oben) Portbit signalisiert die Übertragung von 200 Bytes an den 
Soundbuffer in ca. 230µsec
Kanal 2 (Unten) Sinus-Wave aus dem Soundpuffer

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Ich verkaufe meinen beiden Original CEM3320 Filterbausteine. Geprüft und 
kaum benutzt. Lagen bei mir in der Schublade auf einer Iso-Matte. Alter 
ca. 10 Jahre. Da ich in meinem Synthi-Projekt die SSM2044 einsetze sind 
die CEM3320 überflüssig. Preis ist Verhandlungssache.

Gruß Rolf

Achso.. hät ich beinahe vergessen. Zur Zeit teste ich die 
Speicheranbindung des 8MByte großen SDRAM auf Xplained-Board das ich in 
meinem AVR-Synthi als Wave-Speicher verwenden will. Die Transverleistung 
des Speicherinterface im Xmega zum 8MByte SDRAM liegt bei beachtlichen 
1.4Mbyte in der Sekunde. Für so einen 8Bitter eine stolze Leistung.

Falls alles nach meinen Vorstellungen funktioniert, soll der 
XMega-Prozessor verschiedene 16Bit Waveforms nach dem Systemstart 
vorrausberechnen und in dem 8MByte SDRAM zwischen speichern. Per 
Timer-Interrupt werden die Wave-Daten aus dem Speicher gelesen und an 
als 12Bit Wert an den DAC gesendet. Das ganze funktioniert per Direct 
Digital Synthese und Waveform-Tabellenzugriff.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich will noch einmal auf das Thema Interpolation zu sprechen kommen. 
Wolfgang aus dem CC2-Forum hatte ja bereits in seinem Beitrag 
(http://www.cczwei-forum.de/cc2/thread.php?postid=79168#post79168) viel 
erklärt und gute Tips für die Berechnung geliefert.

Da mir jetzt "Unbegrenzter" Speicherplatz in meinem Synthesizer zur 
Verfügung steht (ganze 8 MegaByte wow..) habe ich einige Test mit der 
Interpolation von Soundsamples gemacht (siehe Bild 1+2) . Die 
Original-Samples hatten jeweils eine Auflösung von 7 Bit.

Bild 1: Links Original Waveform 7Bit, Rechts interpolierte Waveform
Bild 2: Links Original 7Bit Waveform, Mitte interpolierte Waveform

Das Ergebnis ist wirklich gut. Kein Rauschen kein nix. Die Original 7Bit 
Soundsamples klangen im unteren Frequenzbereich (< 500Hz) sehr 
verrauscht. Nach der Interpolation klingt das ganze schon super finde 
ich.


Mein Code für die Interpolation
1
//--------------------------------------------------------------------------
2
// Wave-Interpolation
3
// ------------------ 
4
// Zwei Sample aus Wave-Tabelle laden und drei neue Zwischenwerte berechnen.
5
// Dann 1.Sample und die drei neuen Zwischenwerte für die Soundausgabe ins
6
// SDRAM schreiben.
7
//---------------------------------------------------------------------------
8
void init_wave2()
9
{
10
    // schreiben
11
    uint8_t sample_index = 0;
12
    uint16_t wr_pointer = 0;
13
    uint32_t sample_a = 0;
14
    uint32_t sample_b = 0;
15
    uint32_t sample_xa = 0;
16
    uint32_t sample_xb = 0;
17
    uint32_t sample_xc = 0;
18
    
19
    for (sample_index = 0; sample_index < 127; sample_index++)
20
    {
21
        sample_a = pgm_read_byte (&(wave_7Bit[sample_index]));                // 1.Sample aus Sinus-Tabelle laden
22
        sample_b = pgm_read_byte (&(wave_7Bit[sample_index+1]));            // 2.Sample aus Sinus-Tabelle laden
23
        sample_a = sample_a << 8;                                            // 1.Sample to 16Bit
24
        sample_b = sample_b << 8;                                            // 2. Sample to 16Bit
25
        sample_xb = (sample_a + sample_b) >> 1;                                // 1. - 3.Zwischenwerte berechnen        
26
        sample_xa = (sample_a + sample_xb) >> 1;
27
        sample_xc = (sample_b + sample_xb) >> 1;
28
        hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_pointer,sample_a);    // write 1.Sample to Puffer
29
        wr_pointer = wr_pointer + 2;                                        // inc Sample-Puffer (+2 wegen 16Bit)
30
        hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_pointer,sample_xa);    // write 1.Zwischenwert to Puffer
31
        wr_pointer = wr_pointer + 2;
32
        hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_pointer,sample_xb);    // write 2.Zwischenwert to Puffer
33
        wr_pointer = wr_pointer + 2;
34
        hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_pointer,sample_xc);    // write 3.Zwischen to Puffer
35
        wr_pointer = wr_pointer + 2;                                        // inc Sample-Puffer (+2 wegen 16Bit)
36
    }
37
}

Neue (interpolierte) Wave aus SDRAM abspielen
1
void play_wave2()
2
{
3
    uint16_t sample_index = 0;
4
    uint16_t rd_pointer = 0;
5
    uint16_t sample = 0;
6
    for (sample_index = 0; sample_index < 508; sample_index++)
7
    {
8
        sample = hugemem_read16(BOARD_EBI_SDRAM_BASE + 512 + rd_pointer);
9
        DACA.CH0DATA= sample >> 4;                    // 16Bit Sample to 12Bit
10
        _delay_us(1);
11
        rd_pointer = rd_pointer + 2;        
12
    }
13
}

Mir geht es bei der Interpolation in erster Linie darum, die niedrige 
Auflösung der Wavefiles (8Bit/256Byte Länge und 7Bit/129Byte Länge) die 
sich im Flashspeicher des Xmega-Prozessors befinden, wärend des 
Systemstarts auf 12Bit/1024Byte Länge zu erhöhen und in das SDRAM 
abzulegen. Von da aus soll nach Bedarf jeweils ein Wavefiles für 
Oszillator1+2 in einen Soundpuffer (SRAM im XMega) kopiert, gemixt und 
auf den DAC gesendet werden. Das gleiche passiert mit Berechnungen von 
Wellenformen.

In Bezug auf die SDRAM-Steuerung vielleicht noch ein paar interessante 
Infos. Ein 8Bit Lesezugriff auf das SDRAM dauert mit der "hugemem" 
Routine komplett ca. 1µsec (inlkusiv Adressierung und Rückgabe des 
Speicherwertes). Die ganze Adressierung und Rückgabe des 8Bit 
Speicherwertes wird also in ca. 32 CPU-Takten erledigt. Für einen 16Bit 
Lesezugriff ist die Zeit doppelt so lang. Das interne Steuerinterface 
(EBI) für das SDRAM wird im Xmega-Prozessor mit dem doppelten CPU-Takt 
von 64MHz betrieben. Die schnellste Zugriffszeit für das SDRAM auf 
meinem Xplained Board liegt laut Datenblatt bei 7.5nsec.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Bin jetzt etwas verärgert  . Habe das neue SP2 für Atmel Studio6 
installiert und jetzt kann ich kein Programm mit meinem AVRISP MKII mehr 
flashen. Kann mir da einer weiterhelfen ?

Liegt es vielleicht an Win8 ? Wenn ja fliegt Win8 im hohen Bogen von 
meiner Festplatte. Mit Win8 bin ich wieso nicht ganz zufrieden !

von Rolf D. (rolfdegen)


Lesenswert?

Irgendetwas stimmt da nicht mit dem Programmiergerät. Die ausgelesenen 
Hex-Daten aus dem Flashpeicher des Xmegas sehen im unteren Teilbereich 
anders aus als die erzeugten Hex-Datei in Atmel Studio6 ???

von Rolf D. (rolfdegen)


Lesenswert?

Hallo.. ich bins noch einmal

Ich habe Win8 noch einmal neu installiert und danach Atmel Studio 6 SP2. 
Leider ohne Erfolg. Der Xmega wird vom AVRISP MKII nicht richtig 
programmiert. Ein manuelles Verify über die Tool-Funktion in 
Atmel-Studio zeigt Fehler am Ende der Programmdaten im XMega.

Ich habe jetzt unter Windows8 die Treibersignierung deaktiviert und 
Atmel Studio 5.1 installiert. Das funktioniert auf Anhieb und ohne 
Probleme

Atmel: "Don't change a running system" :(

Ich werde jetzt erst einmal bei Atmel Studio 5.1 bleiben und mein 
Projekt unter Windows 8 weiter entwickeln. Aber ich wunder mich schon 
ein wenig, das Atmel die Version 6 mit dem SP2 für Windows8 kompatilen 
hält und keiner meckert ??

LG Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben

Nachdem sich nun die Fachleute von Atmel um mein Problem mit dem 
Programmieradapter AVRISP MKII und ATMEL Studio 6 kümmern, kann ich mich 
wieder voll meinem Synthi-Projekt widmen.

Ich möchte den AVR-Synthi mit zwei VCA-Chips (spannungsgesteuerter 
Verstärker) vom Typ SSM2164 austatten, weil ich mit der Soundqualität 
nicht zu frieden bin. Bei leisen Klängen ist ein Hintergrundrauschen vom 
DA-Wandler und dem Filterbaustein SSM2044 zu hören. Da der VCA-Chip am 
Ende der Übertragungskette, also hinter den Filtern sitzt, wird das 
Rauschen vom DAC und Filterbaustein mit abnehmbarer Lautstärke des VCAs 
auch leiser und ist dann kaum noch warnehmbar. Gesteuert werden die 
beiden VCA-Chips wie auch die Filter durch die PWM-Anschlüsse am 
Xmega-Prozessor.

Das Hardwarekonzept für die Klangerzeugung sieht jetzt so wie in Bild 1 
aus. Allerdings sind VCA-Chips nicht gerade billig. Ich habe sie bei 
einem Münchner Lieferanten (Sahin Electronic) für einen Stückpreis von 
18,- Euro bekommen. Auf Ebay sind die Chips preisgünstiger zu bekommen, 
haben aber sehr lange Lieferzeiten (5-7 Wochen) weil aus Übersee.


Bild 1: AVR-Synthi "WAVE 1"

LG Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Rolf Degen schrieb:
> Ich möchte den AVR-Synthi mit zwei VCA-Chips (spannungsgesteuerter
> Verstärker) vom Typ SSM2164 austatten, weil ich mit der Soundqualität
> nicht zu frieden bin.

Hast Du schon mal darüber nachgedacht, einen externen I2S-DAC 
(16...24Bit) zu verwenden? Mittels UART im SPI-Mode und per Event-System 
synchronisiertem Timer für die WordClock bekommt man ein astreines, 
komplett in Hardware laufendes I2S-Interface hin. Nachladen kann man die 
Daten per DMA.

I2S-DACs so in Richtung CS4344 kosten zum Beispiel bei CSD-electronics 
keine 3 EUR. I2S kann man auch wunderbar auf SPDIF umwandeln :-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Knut

Das wäre auf jeden Fall eine Option bzw Verbesserung über die man später 
nachdenken kann. Aber erst einmal muss das ganze Projekt funktionieren. 
Es sind momentan noch zu viele Baustellen an denen ich arbeite.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Heute sind meine zwei bestellten VCA-Chips (SSM2164D) angekommen. Die 
werde jetzt mal schnell in die Synthi-Schaltung geklebt und dann die 
Ansteuerung über die Software programmieren. Mal schaun wies klingen 
wird.

Softwaremäßig sieht es zur Zeit etwas schwierig aus. Der Programmcode 
ist mittlerweile sehr groß und unübersichtlich geworden. Aus diesem 
Grund, habe ich damit angefangen, die vielen Funktionen in 
Funktionsblöcke zusammenzufassen und in sogenannten Include-Files 
abzulegen.

Das ganze Code wird dadurch übersichtlicher und verständlicher.

Das Projekt sieht zum Beispiel jetzt so aus wie im Bild 1. Auf der 
linken Seite steht eine ausgewählte Funktion, die zB. Daten über die 
SPI-Schnittselle des XMega-Prozessor zum Display sendet. Auf der rechten 
Seite sieht man die Ordnerstruktur und die ganzen Include-Files mit den 
darin befindlichen Funktionen.

Bild 1: AVR-Synthi Projekt mit ATMEL Studio6


Gruß Rolf

von eProfi (Gast)


Lesenswert?

Hallo Rolf,
Hut ab vor Deinen Experimenten.

Aber ein paar Dinge sind mir noch unklar:
>    uint32_t sample_a = 0;
>    uint32_t sample_b = 0;
>    uint32_t sample_xa = 0;
>    uint32_t sample_xb = 0;
>    uint32_t sample_xc = 0;
Warum 32?  16 sollte da voll ausreichen.

>    for (sample_index = 0; sample_index < 127; sample_index++)
Zeitkritische for-Schleifen lasse ich immer bis 0 laufen, da der 
Vergleich wegfällt, er wird implizit im Dec-Befehl ausgeführt 
(Zero-Flag).
Natürlich muss es auch beim Schreiben in dieser Reihenfolge geschehen.

Außerdem: muss es nicht <128 (oder <=127) heißen für 0..127 ?


also:  sample_index=127;do{...}while(--sample_index!=0);
wichtig ist vorher decrement, dann vergleich, sonst vergleicht er gern 
mit 0xff.

Außerdem würde ich hier ebenfalls mit einem Pointer arbeiten.

Du liest jedes Sample 2 mal aus, zuerst als b, dann als a.
Du kannst ja statt des 1. Reads  sample_a=sample_b schreiben.


Mein Vorschlag (aus dem Stegreif, alles ungetestet) dürfte doppelt so 
schnell laufen:
  uint8_t   cnt;
  uint16_t  sample_a,sample_b;
  uint16_t* sample_ptr,wrt_ptr;

  sample_ptr = .....;wrt_ptr = ....;
  sample_b = pgm_read_byte (&(wave_7Bit[sample_ptr++]));
  cnt=128;do{
    sample_a=sample_b;
    sample_b=pgm_read_byte (&(wave_7Bit[sample_ptr++]));
    delta=sample_b - sample_a;
    sample_a*=4;
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr   ,sample_a   );
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);
    }while(--cnt);

von Rolf D. (rolfdegen)


Lesenswert?

Hallo eProfi

Danke für deine guten Vorschläge. Ich weis, das ganze ist von mir noch 
nicht optimal programmiert. Es war auch mein erster Versuch mit dem 
Zugriff aufs SDRAM. Ich werde deine Vorschläge auf jeden Fall 
berücksichtigen.

Danke. Gruß Rolf

von eProfi (Gast)


Lesenswert?

Nochwas:
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr   ,sample_a   );
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);
    hugemem_write16(BOARD_EBI_SDRAM_BASE + 512 + wr_ptr+=2,sample_a+=d);

geht so schneller, da er die beiden Adress-Additionen nicht jedes mal 
machen muss:
vor der do..while:
    uint16_t wrt_ptr; //war oben fälschlich ein Pointer uint16_t*
    wr_ptr = BOARD_EBI_SDRAM_BASE + 512;

in der do..while:
    hugemem_write16(wr_ptr   ,sample_a   );
    hugemem_write16(wr_ptr+=2,sample_a+=d);
    hugemem_write16(wr_ptr+=2,sample_a+=d);
    hugemem_write16(wr_ptr+=2,sample_a+=d);


Ausgabe würde ich unbedingt mit timergesteuerter DMA machen.
Habe ich mal mit einem Renesas M32C (interner DAC als DMA-Ziel) so 
gemacht, keine Belastung durch die Ausgabe.

von Rolf D. (rolfdegen)


Lesenswert?

eProfi schrieb:

> Ausgabe würde ich unbedingt mit timergesteuerter DMA machen.
> Habe ich mal mit einem Renesas M32C (interner DAC als DMA-Ziel) so
> gemacht, keine Belastung durch die Ausgabe.


Ich weis nicht recht, ob meine Methode (timergesteurte Soundausgabe über 
Assembler-Routine) im Vergleich zur DMA-Funktion doch die bessere ist. 
In dem Assembler-Teil für die Soundausgabe wird der 12Bit Wert aus dem 
Soundpuffer direkt in das Ausgaberegister des DA-Wandler geschriebe.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo

Zur Abwechslung mal ein geiler Demo-Sound aus dem AVR-Synthi. Dabei 
wurde die Filterfrequenz und die Oszillatorfrequenz moduliert.

https://soundcloud.com/rolfdegen/lfovcfmod

Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Klingt doch ganz manierlich ;-)

von Rene B. (themason) Benutzerseite


Lesenswert?

Klingt echt toll dein AVR Synthi :-) Nur weiter so.

von egonotto (Gast)


Lesenswert?

Hallo,

klingt wirklich gut.

MfG
egonotto

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe ein kleines Verständnis Problem mit der abgebildeten 
VCA-Schaltung von Oliver Gillert (Entwickler des Shruthi Synthis). Wie 
man erkennen kann, ist im Gegenkopplungszweig von Operationsverstärker 
(IC3A) ein VCA (IC7C) geschaltet (rotes Rechteck). Ich bin mir einfach 
nicht genau im klaren darüber, wozu der VCA (IC7C) notwendig ist. 
Vielleicht dient er zur Anpassung an eine lineare 
Steuerspannungskennlinie für den eigentlichen VCA in IC9D.

Bild: VCA-Schaltung


Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo zusammen..

Wolfgang aus dem CC2-Forum meint, das es sich hierbei um ein 
Lin-Log-Wandler als Multiplizierer handelt.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Die Weihnachtstage habe ich dazu genutzt, um die VCA-Schaltung für 
meinen AVR-Synthesizer zu bauen und zu testen. Herausgekommen ist die im 
Bild1 gezeigte Schaltung. Grundlage war der Schaltungsentwurf von Oliver 
Gillert 
[https://ox1aha.bay.livefilestore.com/y1psza5s_RUtuXITmcuMA58lD5eyOBqyuXUQMaaMn7uBGqJqOuzvw-yzL8Q-P8wOXyN1doNAyF2V1vleuuO1fYgZ7lN4EPhcD2v/VCA_01.png].

Ich musste allerdings ein paar Änderungen für meine AVR-Synthi machen, 
da Oliver in seinem Shruthi-Synthesizer mit einem anderen Spannungspegel 
(+5Volt) am PWM-Eingang arbeitet.

Bild 1: AVR-Synthesizer VCA-Schaltung

Mit dem Trimmer R5 wird die Steuerkennlinie für den VCA angepasst. Mit 
R3 wird das Steuersignal für den VCA verstärkt.

Bei der Beschaltung des VCA's gibt es noch eine Besonderheit. Der VCA 
besitzt einen Mode-Pin (Pin1). Der Mode-Pin ermöglicht die Einstellung 
des Ruhestroms durch den Verstärker im VCA. Ist er der Mode-Pin nicht 
beschaltet, dann treten am VCA-Ausgang geringere Verzerrungen aber 
höheres Rauschen auf. Ist der Mode-Pin mit einem Pullup-Widerstand (hier 
R12) beschaltet, dann nehmen die Verzerrungen zu und das Rausches ist 
geringer.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Ich hoffe, ihr seit alle gut in das neue Jahr gerutscht. Ich habe mit 
meinen Freunden aus China gefeiert und das Neujahr begrüsst. Zur Party 
hatte ich extra Luftschlangen, Konfetti und Bleigießen mitgebracht, um 
zu zeigen, wie hier das neue Jahr gefeiert wird. Es war wunderschön.. :)

Auch diese Tage hatte ich etwas Zeit für mein Projekt und habe die 
Filterschaltung für den AVR-Synthi etwas verbessert und getestet (siehe 
Bild 1).

Meine Annahme, das der Steuereingang des Filter-ICs SSM2044 die gleiche 
logarithmische Steuercharakteristik besitzt wie der VCA-Chip SSM2164D 
war ein Irrtum. Da der Filter-Chip eine lineare Steuerkennlinie besitzt, 
ist der Bauteilaufwand dafür sogar etwas geringer. Das IC1d dient hier 
als Filter für das PWM-Steuersignal. Durch R1 wird das Steuersignal am 
Ausgang des Operationsverstärkers auf +0.90V angehoben und über den 
Spannungsteiler an den Steuereingang für die Filterfrequenz geführt. Die 
Steuerspannung für den Filter liegt hier, wie im Datenblatt genannt, 
zwischen -90mV und +90mV.

Das Audiosignal vom XMega-DAC wird über einen LP-Filter IC2c an den 
Eingang des Filter-ICs geführt. Über den Trimmer P1 kann das 
Filter-Eingangssignal abgeschwächt werden, um Übersteuerungen am 
Filterausgang zu vermeiden. Ich habe den Audiopegel am Filterausgang auf 
6.0 V~ eingestellt um etwas Reserven nach oben zu haben. Maximal ist ein 
Ausgangspegel von 8.0 V~ am Filterausgang möglich. Bei eingestellter 
Resonanz kann es schon mal vorkommen, das der maximale Audiopegel 
überschritten wird und es zu Verzerrungen kommt. Die Lösung ist entweder 
den Filtereingangspegel mit P1 zu reduzieren, oder die Steuerspannung 
für die Resonanz zu verringern.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Hab mal ein kleines Video gedreht und auf Youtube hochgeladen. Es zeigt 
die VCA-Schaltung im AVR-Synthi in Aktion.

Link zum Youtube-Video: http://www.youtube.com/watch?v=nTUUqwcewA8


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

VCF und VCA-Schaltung sind jetzt fertig. Hier ein kleines Youtube 
Demo-Video. Es zeigt die LFO-Modulation von VCF und VCA.

http://www.youtube.com/watch?v=iwUUhr8rD48

Achtung! Sound ist sehr laut.

Hier noch schnell ein Bild mit dem kompletten Hardwareaufbau meines 
AVR-Synthis in der Stereo-Version.

Bild 1: AVR-Synthi Stereo-Version

Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Na das geht doch schon ganz ordentlich. Ich stell mir das Teil jetzt 
schon mal an einem Sequencer vor :-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Knut

Danke. Ich bin jetzt dabei, die LFO's zu programmiere. Insgesammt sollen 
es einmal sechs Stück werden für 2x VCA, 2x VCF, DCO, PAN. Davon sind 
jeweils zwei für die Stereo-Kanäle vorgesehen.

Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Wenn Du das Ding fertig hast und ordentlich dokumentierst, baue ich mir 
vielleicht auch einen :-)

von Rolf D. (rolfdegen)


Lesenswert?

An einer Dokumentation solls nicht scheitern. Sind immerhin schon 12 
Blog-Seiten im CC2-Forum mit vielen Informationen die das Thema 
Synthesizebau und Softwareentwicklung betreffen. Das Ganze könnte sogar 
für ein Buch ausreichen. Mal schaun was da noch kommen wird. Auf jeden 
Fall steckt noch eine Menge an Arbeit für die Software drin.

Gruß Rolf

PS: Bald wirds wieder ein paar "verrückte" Demo-Sounds geben, die ich 
beim experimentieren mit dem Synth zufällig erzeugt habe. Aber dieses 
mal in Stereo :)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Rolf Degen schrieb:
> Sind immerhin schon 12
> Blog-Seiten im CC2-Forum mit vielen Informationen die das Thema
> Synthesizebau und Softwareentwicklung betreffen.

Ja, war schon drauf ;-).

Rolf Degen schrieb:
> Auf jeden
> Fall steckt noch eine Menge an Arbeit für die Software drin.

Darum lass ich Dich erst mal in Ruhe machen :-P.

Vielleicht kann man, wenn das Projekt fundierte Kenntnisse abwirft, mal 
über die Hardware schauen. Ich denke, dass man den Controller gegen 
einen neueren XMEGA tauschen sollte und zu den Wandlern / Schnittstellen 
hätte ich auch noch die eine oder andere Idee.

Rolf Degen schrieb:
> Bald wirds wieder ein paar "verrückte" Demo-Sounds geben, die ich
> beim experimentieren mit dem Synth zufällig erzeugt habe. Aber dieses
> mal in Stereo :)

Freu mich drauf!

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Es gibt wieder was neues rund um den AVR-Synthi zu berichten Ich habe 
das DCO-Menü etwas verändert und hoffe das es jetzt etwas 
übersichtlicher ist (Bild 1). Die Tune-Funktion für die Oszillatoren 
wird einen eignen Menü-Seite bekommen.

Bild 1: DCO-Menü im AVR-Synthi
Bild 2: Auswahl der Wellenform im DCO-Menü

Da es ja zwei Oszillatoren im AVR-Synthi gibt, kann man für beide auch 
auch unterschiedlichen Wellenformen auswählen. Drückt man auf den Button 
"Wave", dann öffnet sich ein weiters Menüfenster, in dem man die 
Wellenform für den Oszillator mit dem Encoder oder Bargraph auswählen 
kann. Die ausgewählte Wellenform wird zusätlich auf dem Display 
dargestellt (Bild 2).

Im neuen DCO-Menü kann für jeden Oszillator auch die Lautstärke von 
0-127 eingestellt werden. Ferner können die beiden Oszillatoren entweder 
als Mono-Summe auf beide DA-Wandler Ausgänge geschaltet werden, oder 
getrennt auf die zwei DA-Wandler Kanäle für Links und Rechts (Stereo).

Heute werde ich auch ein Youtube-Video mit den ersten Stereo-Demo Sounds 
vom AVR-Synthi hochladen und hier verlinken.

So.. hier ist das angekündigte Youtube-Video mit den Stereo Demo Sounds 
vom AVR-Synthi: http://www.youtube.com/watch?v=B1hQOvVLosQ

Bis dann.. Lieben Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Ich habe bemerkt das der Stereo Demosound im Youtube-Video ein paar 
Störungen hat. Warscheinlich durch die Videokomprimierung verursacht. 
Deshalb habe ich den Demosound noch einmal als MP3-File mit 320kBit 
Auflösung auf SoundCloud hochgeladen.

Stereo Demosound

https://soundcloud.com/rolfdegen/avr-synthesizer-wave-1-stereo

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Auf der Suche nach einer einfachen und praktischen Speicherlösung für 
die Wavefiles und
Soundparameter in meinem AVR-Synth, bin ich auf das ALFAT-Modul von der 
Firma GHI-Electronics
gestoßen.

Bild 1: ALFAT-Modul von GHI-Electronics

Mit dem ALFAT-Modul können Daten über die SPI-Schnittstelle des 
Xmega-Prozessors
auf oder von SD & MMC-Karten und USB-Speicher-Laufwerke geladen werden.
Die maximale Datenübertragungsgeschwindigkeit wird vom Hersteller mit 
bis zu
4MBytes pro Sekunde angegeben.

ALFAT-Konzep
Ein FAT-Dateisystem für eine SD-Card oder USB-Stick benötig auf einem 
Mikrocontroller
wzB dem ATXmega große Ressourcen. Der SoC-Prozessor auf dem ALFAT-Modul 
ermöglicht
einen schnellen und einfachen Speicherzugriff per UART, SPI oder 
I2C-Schnittstelle und
entlastet dadurch den ATXmega-Prozessor im AVR-Synthi. Das ALFAT-Modul 
unterstützt lange
Dateinamen und ist von Microsoft für den gewerb-lichen Einsatz 
lizensiert.

Bild 2: ALFAT-Konzept

Einige Features
* Built-in 2-port USB Host controller.
* FAT16 and FAT32 File system.
* No limits on media size, file size or file/folder count.
* LFN (Long File Name), licensed by Microsoft.
* Friendly user interface through UART,SPI or I2C.
* Programmable UART baud-rate.
* Up to 8 simultaneous file access.
* SD/SDHC card support, no 2GB limit. GHI electronics is an SD 
association member.
*High speed 4-bit SD card interface.
* Up to 4000 KBytes/sec file access speed SD cards/USB.
* Single 3.3V power source.


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe jetzt das "ALFAT OEM Board" an den AVR-Synthesizer 
angeschlossen und die ersten Funktionen programmiert
wzB die Initialisierung und Formatieren einer SDCARD oder das Auslesen 
der RealClockTime. Mit dem Auslesen der RCT
hatte ich am Anfang allerdings ein Problem, weil der spezielle 
Uhren-Quarz auf dem ALFAT-Board nicht bestückt war
(Absicht oder nicht ?). Ich hatte noch einen in meiner Krabbelkiste und 
habe diesen auf das Board gelötet. Danach klappte
alles einwandfrei.

Bild 1: AVR-Synthesizer mit ALFAT OEM Board

Das ALFAT-Board benötigt eine Versorgungsspannung von +5V. Intern wird 
die Spannung für die SDCARD
auf 3.3 Volt gewandelt. Die beiden USB-Buchsen liegen an +5Volt . Da das 
ALFAT-Board die +5 Versorgungs-
spannungschiene vom Netzteil etwas mehr belastet, habe ich die 
Glättungs-Elkos von 470µF auf 2200µF erhöht.
Durch die größere Belastung auf der +5Volt Schiene wurde jetzt der 
Festspannungsregler 7805 etwas heiss.
Aus diesem Grund habe ich ihm einen kleinen Kühlkörper spendiert.

Die Tage werde ich die Routinen für das Speichern und Laden von 
Wellenformen programmieren und als Anwendungs-
beispiel hier posten. Ich denke, das ist vielleicht auch für andere 
Anwendungen wzB Datenlooger oder so interessant.


Bis dahin lieben Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Die Soundbeispiele sind wieder sehr schön.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo ihr Lieben..

Nach längerer Abwesenheit wegen Krankheit melde ich mich Heute wieder 
zurück. Ich muss mich leider noch etwas erholen und aus diesem Grund 
gibt es noch nichts Neues zu berichten.
Ich hoffe, das ich bald wieder gesund bin und etwas mehr Zeit habe, um 
an meinem Projekt weiter zu arbeiten. Aber im Moment hat mir der Arzt 
viel Bewegung verschrieben und da bleibt leider nicht so viel Zeit für 
die Computerarbeit. Aber ich versuche trotzdem immer mal wieder etwas zu 
berichten, damit es hier nicht zu langweilig für euch wird.

Bis dahin bleibt gesund und viel Spaß beim stöber hier im Forum.

Lieben Gruß Rolf


Nachtrag: Gerade im shruthi-Forum 
(http://www.mutable-instruments.net/forum/) gelesen und vielleicht 
interessant für euch..

In der Ausgabe 1/2013 "c't Hardware Hacks" 
(http://shop.heise.de/katalog/ct-hardware-hacks-1-2013) wird der Bau 
eines "Mini-Synthesizer" mit einem ATMEL-Chip beschrieben.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo ihr Lieben..

Gibt wieder einiges neues zu berichten auf meiner Blockseite im 
CC2-Forum. Da gehts um neue Boards, Soundkarten und Umbau, Cubase und 
ASIO-Latenz und Drehencoder. Wenn Ihr Lust habt, dann schaut doch 
einfach mal hier vorbei: 
http://www.cczwei-forum.de/cc2/thread.php?postid=80909#post80909

Gruß Rolf

von Rolf D. (rolfdegen)



Lesenswert?

Hallo zusammen

Ich möchte euch den ersten Gehäuse-Entwurf für mein Synthesizer "WAVE 1" 
vorstellen. Die Idee stammt von Wolfgang (alias Wiesolator) aus dem 
CC2-Forum. Grundlage ist ein Alugehäuse der Firma BOPLA (Bild 2).
Die gelbe Frontplatte lasse ich von der Firma Schaeffer herstellen. Die 
zwei Gehäuseseitenteile werden aus Holz sein. Die Idee für die 
zusätzlichen Regler (Edit) hatte Wolfgang. Für Live-Aktionen können die 
Regler mit einer Funktion belegt werden.

Was in dem Entwurf noch fehlt, sind Volume-Regler für den 
Kopfhöreranschluss und SD-Card Beschriftung (oben).

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Hier eine kleine Vorstellung meiner MiniScope-Funktion im 
AVR-Synthesizer:

Youtube-Video: http://www.youtube.com/watch?v=4O1XCRsIUDQ

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Mein Scope im AVR-Synthesizer besitzt jetzt eine TimeBase- und 
Trigger-Funktion

Youtube-Video: Scope-Funktion: 
http://www.youtube.com/watch?v=B0ticWx_BFo

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr da..

Hab mal wieder etwas an meinem Synth gebastelt bzw programmiert und 
herausgekommen ist eine neue Menü-Seite für die Modulation-Matrix (Bild 
1).

Links kann man eine Modulations-Quelle zB LFO1 auswählen und Rechts 
sieht man dann die Modulations Ziele für LFO1 mit den eingestellten 
Depth-Werten. Da es sich beim "WAVE 1" um einen "Echten" Stereo 
Synthesizer handelt, gibt es für den linken und rechten Kanal getrennte 
Modulations-Ziele zB VCF1 und VCF2. Einige Modulations-Ziele wzB PAN, FM 
and Noisgenerator fehlen allerdings noch.


Bild 1: Modulations-Matrix im AVR-Synthesizer

Meine Projekt-Seite: 
http://www.cczwei-forum.de/cc2/thread.php?threadid=5878&threadview=0&hilight=&hilightuser=0&page=15

Mein Youtube-Kanal: http://www.youtube.com/user/rolfdegen1806

Grüße Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben..

Heute Morgen will ich wie gewohnt etwas an meinem Synthesizer Projekt 
arbeiten und starte dafür Atmel Studio 6.1. Morgens hat man ja meistens 
die beste Phase für gute Ideen und Gedanken. Aber dann erlebe ich eine 
Überraschung die mich echt umgehauen hat.

Beim compilieren meines Projekt-Files zeigt mit Atmel Studio plötzlich 
7791 Fehler an. Ups.. was ist das denn ?? Gewohnt bin ich ja ab und zu 
so ein paar blöde Syntax-Fehler die man so aus Flüchtigkeit beim 
programmieren macht wzB das vergessen einer Geschweiften Klammer am Ende 
einer Funktion, oder oft ein vergessenes Semikolon am Ende einer 
Anweisung. Aber 7791 Fehler. Ne.. das is doch a bissel viel

Nach langem Suchen und vielem hin und her wollte ich schon aufgeben und 
da kam mir der Zufall zur Hilfe. Im ASF Wizard von Atmel Studio 6.1 kann 
man die ASF-Module Version upgraden. Der Eintrag stand bei mir auf 
3.5.0. Ich habe ihn auf die letzte Version 3.9.1 gestellt und konnte 
mein Projekt jetzt ohne Fehler compilieren.

Bild 1: Atmel Studio 6.1 ASF Wizard

Wieso der Fehler Heute Morgen aufgetreten ist und nicht schon Gestern 
Nacht, als ich das letzte mal mein Projekt compeliert habe, das bleibt 
mir ein Rätsel. Auf jeden Fall bin ich froh das es wieder funktioniert.

Mein Fazit: Ich mach jetzt jeden Tag ein Backup auf einer externen 
Festplatte.

Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

ATMEL-Studio ist immer für Überraschungen gut. Mein Kollege flucht auch 
öfter. Da ich in ASM programmiere, bleibe ich weitgehend verschont ;-). 
Manchmal ist Fortschritt nicht auf Anhieb zu verstehen...

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Knut

Schön von dir zu hören. Mit der Zeit hat man ja so seine Erfahrungen mit 
ATMEL STUDIO gemacht und kann damit umgehen. Mein Projekt ist 
mittlerweile schon sehr groß geworden. Bin gerade dabei, das ATMEL 
Xplained-Board 
(http://www.watterott.com/de/Atmel-UC3-A3-Xplained-AT32UC3A3-XPLD) durch 
ein Breakout-Board mit einem ATXmega128A1 
(http://mikrocontroller-praxis.de/de/Development-Tools/AVR-Mikrocontroller-Module/XMega100-Breakout.html) 
zu ersetzen, damit ein Nachbau günstiger wird. Auf dem Xplained-Board 
gabs viele Dinge die ich für mein Synthesizer-Projekt nicht benötigte 
und einige Ports waren nicht zugänglich. Dies ist mit dem Xmega 
Breakout-Board jetzt kein Problem mehr. Ein preisgünstiges SD/MICRO-SD 
CARD BREAKOUT MODULE 
(http://mikrocontroller-praxis.de/de/Development-Tools/SD/MICRO-SD-CARD/SD/MICRO-SD-CARD-BREAKOUT-MODULE.html) 
habe ich ebenfalls bestellt. Hatte davor eine teures SDCARD-Modul von 
ALFAT (https://www.ghielectronics.com/catalog/product/337) mit USB 
geplant. Aber das ist mit über 50,- Euro doch sehr teuer. Das Display 
teure Touch-Display wurde ebenfalls ersetzt gegen ein preisgünstiges 
DOGXL160 Display. Damit wird der Synth im Nachbau etwas günstiger. 
Überlege noch wegen den verwendeten Filter-IC SSM2044, ob ich diese 
nicht gegen eine günstige Filterschaltung mit OTAS vom Typ LM13700 
ersetzen soll. Aber vorerst bleib ich bei den SSM2044.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Einen wunderschönen, sonnigen und guten Montag Morgen wünsch ich Euch 
allen :)

Hier ein paar Bildchen von meinem Synth-Gehäuse. Bin gerade dabei das 
Frontpanel für die Frontplatte zu löten. Aber sieht schon nicht schlecht 
aus find ich.. :)

Bilder: AVR-Synthesizer Gehäuse


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo again.. ich schon wieder smile

Damit man einen kleinen Eindruck gewinnt, wie der Synthesizer später 
einmal aussehen wird, hab ich mal eine Fotomontage gemacht. Ist mir 
nicht so gut gelungen, bin aber auch kein "gut bezahlter" Grafiker smile

Bild 1: Synthesizer "WAVE 1"

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo

Für den Xmega-Prozessor in meinem Synthesizer plane ich noch eine 
Speichererweiterung von 512KByte SRAM. Das SRAM gibt es als Breakout 
Board auf eBay schon ab 7,99 US $. Dann hätte ich die Möglichkeit, beim 
Systemstart die Soundparameter und großen Wellenform Dateien von der 
SDCard in das SRAM zu laden. Angebunden wird das SRAM an den EBI-Bus 
(Port H-K) des Xmega. Mit dem Xmega kann ich wesentlich schneller auf 
Wellenform Daten und Soundparameter zugreifen als über die SDCard. Die 
SDCARD dient dann lediglich als externer Datenspeicher.

Bild 1: IS62WV51216BLL SRAM Board
Bild 2: EBI Port Xmega

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Ich habe gerade festgestellt, das auf dem bestellten SRAM-Board 
(IS62WV51216BLL SRAM Board) ein 16Bit SRAM sitzt und nicht wie gedacht 
um ein 8Bit Typ. Das freut mich doch sehr, da es insgesammt 1MByte 
Speicherplatz sind. Wow.. smile

Die Adressierung mit dem Xmega ist allerdings etwas tricki. Um das SRAM 
zu adressieren sind zwei Stück 8-BIT D-LATCH Typ 74HC573 für die 
Bereitstellung der höheren Adressleitungen von A8-A18 notwendig. 
Zusätzlich ist für die vollen 16Bit Nutzung des SRAMs eine freie 
Adressleitungen (zB A19) notwendig, die auf den "LB" Anschluss 
(LowerByte) und über einen Inverter an "UB" Anschluss SRAM zu legen ist.

Bild 1: Xmega EBI-Interface
Bild 2: SRAM IS62WV51216BLL-55TLI

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben..

Die VCA-Page in meinem Synth ist jetzt fertig (siehe Bilder). Mit der 
Taste "Function" kann man auf der VCA-Page zwischen den Einstellungen 
für die Lautstärke und Balance umschalten. Die rechteckigen Symbole für 
Osc und Noise werden entsprechend der Balance-Einstellung wie bei einem 
analogen Fader nach oben oder unten verschoben.

Softwaretechnisch ware es nicht ganz leicht (zumindes für mich 
Augenzwinkern ) die Volume- und Balance-Funktionen für Oszillator und 
Rauschgenerator umzusetzen. Ein Teil der Funktionen (Berechnung 
Lautstärkeverhältnis Linker und Rechter Audiokanal) wurde in der 
Menüsteuerung, die komplett in C geschrieben ist, umgesetzt (siehe 
C-Code). Ein anderer Teil dieser Funktion wurde in die Assembler 
Routinen für die Soundausgabe integriert (siehe unten).

Im Anhang zwei Bilder von der VCA-Page und Code-Beispiel.


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Habe mit großartiger Unterstützung von Andre (tubeohm.com) nun einen 
neuen Stereo Audio-Filter für meinen Synth gebaut. Im Vergleich zum 
alten Filter mit den SSM2044 IC klingt der neue Filter im Bass- und 
Hochtonbereich sehr ausgewogen.

Hier meine Stereo Filter Demo: 
http://www.youtube.com/watch?v=fyGdspVTL8c

Was noch fehlt ist die Auswahl von verschiedenen Filterkombinationen zB. 
LP+LP zu einem 4pol LP Filter mit 24dB pro Oktave (mono) oder HP+HP, 
LP+HP oder BP+BP.

Bild 1: Stereo Filter Hardware
Bild 2: Vorläufiges Schaltbild eines Filterkanals

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Happy Halloween :)

Noch rechtzeitig zu Halloween hier ein paar Geistersounds aus meinem AVR 
Synthesizer. Dank der neuen Modulation Matrix in meinem Synth, sind ein 
paar irre Sounds entstanden. Viel Spaß beim anhören.

https://soundcloud.com/rolfdegen/halloween-sound

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Es hat sich wieder was getan in meinem Synthesizer. Die Envelope Pages 
haben eine Realtime-Anzeiger für den Verlauf der Hüllkurve (ADSR) 
erhalten. Die Anzeige (kleines schwarzes Fenster) befindet sich oben 
Rechts und ist mit Env gekennzeichnet. Wird zB eine Noten Taste am 
Keyboard gedrückt, erscheint der Verlauf der ADSR-Hüllkurve vom AMP Env 
in Echtzeit in dem kleinen schwarzen Fenster.

Bild 1: Hüllkurvenverlauf


Die Modulations Matrix ist fast fertig. Mit "Source" wird der Modulator 
zB LFO1 ausgewählt. Mit "Destin." (Destination) das Modulations Ziel zB 
Osc1. Mit "Depth" wird die Modulationhöhe eingestellt. Um eine bessere 
Übersicht über die zur Zeit aktiven Modulatoren zu haben, habe ich diese 
mit einem Stern Symbol gekennzeichnet. Nicht aktive Mudulatoren haben 
keinen Stern.

Die Verknüpfung der Modulatoren mit dem Ziel erfolgt immer additativ. 
Wenn zB LFO1 und LFO3 auf das gleiche Modulationziel zB Osc1 geschaltet 
werden, wirkt die Summe beider Modulationssignale auf den 
Modulationseingang von Osc1.

Bild 2: Modulations Matrix

Der Synthesizer besitzt jetzt außer dem AMP Env und Filter Env noch zwei 
weitere freie Envelope Generatoren (Env3+4). Diese besitzen eine eigene 
Menü-Page mit den gleichen Parametereinstellungen wie der AMP Env und 
Filter Env und sind für Modulationszwecke vorgesehen.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Leute

Ich habe Probleme mit EBI Interface auf meinem ATxmega128A1 (siehe 
Bild). Ich verwende ein 512KB SRAM und einen ATMEL Xmega128A1 (Rev H) im 
EBI-Modus. Die höheren Adress-Bits A16-18 an Port H funktionieren nicht 
korrekt. Die Adressbits A0-A15 funktionieren ohne Problem. Das Speichern 
und Lesen von 64KB SRAM Daten ist kein Problem. Aber oberhalb des 64KB 
Adressraums werden die Adressleitungen A16-A18 (CS0-CS2) vom EBI 
Interface nicht richtig angesteuert. Die Adressleitungen A16-A18 sind 
bei jedem Schreibsignal (WR-Signal low aktive) immer auf high Pegel.

Bild 1: SRAM Anbindung an Xmega128A1

Bild 2: EBI-Port Konfiguration


Mein Code:
1
//---------------------------------------------------- 
2
// init extern 512KB SRAM 
3
// --------------------------------------------------- 
4
void init_sram(void) 
5
{ 
6
   // Set signals which are active-low to high value 
7
   PORTH.OUT = 0xFF; 
8
    
9
   // Configure bus pins as outputs(except for data lines). */ 
10
   PORTH.DIR = 0xFF; 
11
   PORTK.DIR = 0xFF; 
12
    
13
   // init EBI 3PORT/AL1/CS3 (A16-19) 
14
   EBI.CTRL |= EBI_SRMODE_ALE1_gc; 
15
   EBI.CTRL |= EBI_IFMODE_3PORT_gc; 
16
17
   EBI.CS3.CTRLA |= EBI_CS_MODE_SRAM_gc; 
18
   EBI.CS3.CTRLA |= EBI_CS_ASIZE_16M_gc; 
19
   EBI.CS3.BASEADDR = 0x00; 
20
   EBI.CS3.CTRLB |= EBI_CS_SRWS_2CLK_gc; // EBI time 
21
} 
22
23
//---------------------------------------------------- 
24
// write sram 
25
// --------------------------------------------------- 
26
void wr_sram(void) 
27
{ 
28
   uint32_t start_adr = 0x4000; // init Startadr. over 16KB SRAM space in Xmega128A1 
29
   uint8_t data = 0; 
30
   for (uint32_t i = 0; i < 0x80000; i++) 
31
   { 
32
      hugemem_write8(start_adr + i, data); 
33
      data++; 
34
   } 
35
}

Im Voraus vielen Dank für eure Hilfe. Schöne Grüße aus Wuppertal. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo liebe Mitleser..

Mit Hilfe des ATMEL Support Team konnte ich mein Problem jetzt lösen. 
Leider funktioniert der schnellere EBI-Mode mit nur einem Adresslatch im 
ATxmega128A1-AU nicht. Diese Version des Prozessor ist leider schon 
etwas älter und Fehler wurden nur noch in den neuen Version wzB dem 
ATxmega128A1U behoben. Das U in der Bezeichnung steht für ein 
zusätzliches USB-Interface im Prozessor. Um die Kompatibilität und die 
Verwendung beide Prozessoren im Synthesizer zu gewährleisten, habe ich 
einen EBI-Mode mit zwei Adresslatch für das SRAM ausgewählt. Dieser 
funktioniert mit beiden Prozessoren fehlerfrei, ist aber im Zugriff auf 
das SRAM um 2 Takte langsamer (siehe EBI-Timing).

Bild 1: EBI Interface mit zwei Adresslatch

Bild 2: EBI Timing

Um die Ansteuerung des 512KB SRAM zu testen, habe ich ein Beispiel (EBI 
SRAM Example - STK600 ATxmega128A1) aus dem ATMEL Studio 6.1 geladen. 
Das ATMEL AVR STK600 ist ein Starter-Kit und Entwicklungs-System für AVR 
8-Bit bis 32-Bit ATMEL Mikrocontroller. Das Beispiele funktioniert aber 
auch mit einem ATxmega ohne Entwicklungsboard. Wichtig ist dann aber, 
das der Prozessortakt beim Systemstart richtig eingestellt wird (siehe 
init_clock im Beispiel Code).

Bild 3: SRAM Example Project from ASF

Beispiel Code für 512KB SRAM:
1
/* 
2
 * Include header files for all drivers that have been imported from 
3
 * Atmel Software Framework (ASF). 
4
 */ 
5
#include <asf.h> 
6
#include <hugemem.h> 
7
#include <ebi.h>
8
9
//*************************************************************************
10
//
11
//             init CPU Clock 32Mhz (ext. Clock 16MHz)
12
//
13
//*************************************************************************
14
void init_clock(void)
15
{    
16
    
17
    // set startuptime for extern Crystal Oscillator
18
    OSC_XOSCCTRL = OSC_XOSCSEL_XTAL_16KCLK_gc | OSC_FRQRANGE_12TO16_gc;
19
    
20
    // enable ext. 16MHz Crystal Oscillator
21
    OSC.CTRL = OSC_XOSCEN_bm;
22
    
23
    // wait oscillator is stable
24
    while(!(OSC.STATUS & OSC_XOSCRDY_bm));
25
    
26
    // set PLL  16MHz * 2
27
    OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 0x02;
28
    
29
    // enable PLL
30
    OSC.CTRL |= OSC_PLLEN_bm;
31
    
32
    // wait PLL is stable
33
    while(!(OSC.STATUS & OSC_PLLRDY_bm));
34
    
35
    // protect I/O register
36
    CCP = CCP_IOREG_gc;
37
    
38
    // enable PLL-Clock
39
    CLK.CTRL = CLK_SCLKSEL_PLL_gc;
40
}
41
 
42
43
static struct ebi_cs_config     cs_config; 
44
45
//------------------------- 
46
// init EBI for 512KB SRAM 
47
//------------------------- 
48
void init_sram(void) 
49
{ 
50
   // Set signals which are active-low to high value 
51
   PORTH.OUT = 0xFF; 
52
    
53
   // Configure bus pins as outputs(except for data lines). */ 
54
   PORTH.DIR = 0xFF; 
55
   PORTK.DIR = 0xFF; 
56
    
57
   ebi_setup_port(18, 2, 0, EBI_PORT_SRAM | EBI_PORT_3PORT 
58
   | EBI_PORT_CS0); 
59
   ebi_cs_set_mode(&cs_config, EBI_CS_MODE_SRAM_gc); 
60
   ebi_cs_set_address_size(&cs_config, EBI_CS_ASPACE_512KB_gc); 
61
   ebi_cs_set_base_address(&cs_config, BOARD_EBI_SRAM_BASE); 
62
   ebi_cs_set_sram_wait_states(&cs_config, EBI_CS_SRWS_1CLK_gc); 
63
   ebi_cs_write_config(3, &cs_config); 
64
   ebi_enable_cs(3, &cs_config); 
65
} 
66
67
//---------------------------------------------------- 
68
// write sram 
69
// --------------------------------------------------- 
70
void wr_sram(void) 
71
{ 
72
   hugemem_ptr_t   p; 
73
   uint32_t base = BOARD_EBI_SRAM_BASE; 
74
   uint_fast8_t    data = 0; 
75
   uint32_t offset = 0x00; 
76
   p=(hugemem_ptr_t)((uint32_t)base + offset); 
77
    
78
   for (uint32_t i = 0; i < 0x80000; i++) 
79
   { 
80
      if (i== 0x12345) 
81
      { 
82
         hugemem_write8(p+i, 0x55); 
83
      } 
84
      else 
85
      { 
86
         hugemem_write8(p+i, data); 
87
          
88
      } 
89
      data++; 
90
   } 
91
} 
92
93
//---------------------------------------------------- 
94
// write sram 
95
// --------------------------------------------------- 
96
void rd_sram(void) 
97
{ 
98
   hugemem_ptr_t   p; 
99
   uint32_t base = BOARD_EBI_SRAM_BASE; 
100
   uint_fast8_t   data1 = 0; 
101
   uint_fast8_t   data2 = 0; 
102
   uint32_t offset = 0x00; 
103
   p=(hugemem_ptr_t)((uint32_t)base + offset); 
104
       
105
   for (uint32_t i = 0; i < 0x80000; i++) 
106
   { 
107
      data1 = hugemem_read8(p+i); 
108
      if (i==0x12345) 
109
      { 
110
         if (data1 != 0x55) 
111
         { 
112
            Led1_on; 
113
         } 
114
      } 
115
       
116
      else 
117
      { 
118
         if (data1 != data2) 
119
         { 
120
            Led1_on; 
121
         } 
122
          
123
      } 
124
      data2++; 
125
       
126
   } 
127
}

conf_board.h:
1
/** 
2
 * \file 
3
 * 
4
 * \brief User board configuration template 
5
 * 
6
 */ 
7
8
#ifndef CONF_BOARD_H 
9
#define CONF_BOARD_H 
10
11
12
//! State that huge memory access (beyond 64k RAM) should be enabled 
13
#define CONFIG_HAVE_HUGEMEM 
14
15
//! Base address of SRAM on board 
16
#define BOARD_EBI_SRAM_BASE    0x800000UL 
17
18
//! Size of SRAM on board, given in bytes: 1 Mb / 128 kB 
19
#define BOARD_EBI_SRAM_SIZE    0x80000UL 
20
21
#endif // CONF_BOARD_H

PS: Empfehlenswert ist es, bei Neuentwicklungen den neusten 
ATxmega128A1U Chip zu verwenden, da der alte ATxmega128A1 einige Bugs 
hat. Leider sitzt auf vielen der angeboten Xmega Developementboards noch 
der alte ATxmega128A1-AU drauf.

Gruß Rolf

von Rolf D. (rolfdegen)



Lesenswert?

Hallöchen..

Es geht langsam vorran. Momentan habe ich wieder etwas mehr Zeit für 
mein Projekt. Das 512KB große SRAM soll als Wellenformspeicher im 
Synthesizer dienen. Da das SRAM einen 16Bit breiten Datenbus besitzt und 
das Speicher-Interface (EBI) des Xmegas nur einen 8Bit Datenbus hat, 
kann man eigentlich nur die Hälfte der SRAM Kapazität mit den 
Datenleitung von D0-D7 nutzen. Aber mit einer kleinen Trickschaltung 
lässt sich auch die andere Hälfte nutzen.

Dafür besitzt das SRAM zwei Anschlüsse mit der Bezeichnung "LB" 
(Lower-Byte) und "UB" (Upper-Byte). Wird "LB" auf Low Pegel geschaltet, 
dann werden die Ein- oder Ausgänge für das Lower-Byte auf die 
Datenleitung D0-D7 geschaltet. Die Datenleitung D8-D15 wird zum gleichen 
Zeitpunkt hochohmig. Das gleiche geschieht mit dem "UB" Anschluss. Wird 
"UB" low, dann wird D8-D15 auf die Datenleitungen geschaltet und D0-D7 
sind hochohmig. Durch diese Art der Ansteuerung kann man problemlos die 
Datenleitungen D0-D7 und D8-D15 am SRAM parallel schalten. Für die 
Umschaltung von Lower-Byte auf Upper-Byte sorgt die Adressleitung A19 am 
Pin 16 von IC4 und das Nandgatter IC5. Im Adressbereich von 0x00000 - 
0x7FFFF (0 - 524.287) wird jetzt das Lower-Byte im SRAM benutzt und im 
Adressbereich von 0x80000 - 0xFFFFF (524.288 - 1.048.575) das 
Upper-Byte. Damit ergibt sich eine Speicherkapazität von 2*512KB = 
1MByte.

Bild 1: 512KB-SRAM am Xmega

Bild 2: SRAM Pinout

Bild 3: SRAM Funktionsblock

Bild 4: 512x16 SRAM Steckboard

Das SRAM gibts in SMD Bauform aufgelötet auf einem Steckboard mit einer 
Power-LED für knapp 6,- Euro plus Versand bei Waveshare Electronics oder 
ebay: http://www.wvshare.com/product/IS62WV51216BLL-SRAM-Board.htm


Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Hier eine kleine Klangkostprobe aus meinem Synthesizer:
https://soundcloud.com/rolfdegen/wavedemo-01

Die Wavesounds habe ich in Audacity monophon aufgenommen und als 
RAW-File im 8Bit/16KHz Format exportiert. Über die SDCard habe dann das 
Wavefile in meinem Synth eingelesen. Die Zwei Oszillatoren habe ich 
gegeneinander etwas verstimmt um einen räumlichen Klang zu erzeugen. Die 
Sounds werden noch ohne Loops abgespielt, da ich diese Funktion zur Zeit 
programmiere.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Obwohl Weihnachten vor der Tür steht und noch so viele Dinge zu tun sind 
(wir wollen am 24. eine kleine Weihnachtsparty geben), habe ich noch 
etwas Zeit gefunden an meinem Synthesizer zu arbeiten.

Wie in meinem letzten Beitrag schon erzählt, programmiere ich gerade an 
einem simplen Wave Editor in meinem Synthesizer. Zur Zeit können nur 
Loop-Punkte für die Wiedergabe der Wavefiles gesetzt werden. Später 
werden noch mehr Funktionen folgen.
Man glaubt gar nicht, wieviel Entwicklungsarbeit hinter so simplen 
Funktionen wie zB einer Cursorsteuerung für ein Grafikdisplay stecken 
und die Auswahl eines Loop-Pointers für die Wellenform. Es reicht leider 
nicht aus, eine einfach senkrechte Linie für den Cursor auf dem Display 
zu zeichnen. Bevor das geschieht, muss als erstes der 
Bildschirmhintergrund gerettet werden, damit beim späteren Ändern der 
Cursorposition der alte Hintergrund (Wellenform) wieder restauriert 
werden kann.

Bild: Wave-Editor

Youtube:http://www.youtube.com/watch?v=DceCkckwcMI&feature=youtu.be

Viel Gedankenschweiß hat mich auch die Zoom-Funktion für die Darstellung 
der Wellenform gekostet. Wenn man bei einer kleineren Auflösung der 
Wellenform zB nur jeden 10.Sample darstellt, dann enstehen große Lücken 
in der Amplitudenabbildung der Wellenform und somit auch eine 
fehlerhafte Darstellung auf dem Display. Das könnte man sicherlich in 
"Hoher Mathematik" lösen, aber Rechenzeit auf dem Xmega-Prozessor ist 
kostbar. Also habe ich nach einer anderen Lösung gesucht. Nach etlichen 
Überlegungen und viel Gedankenschweiß bin ich mit Hilfe von "Audacity" 
(Audioeditor) auf eine annehmbare Lösung gestoßen. Mal angenommen der 
1.Sample hätte einen Amplitudenwert von 10, der 2. von 255, der 10. von 
18. Dann würde bei einer Sampleabtastung von nur jedem 10.Samplewert der 
2. Wert (255) mit der höchten Amplitude und der Rest bis 10 fehlen. Also 
liegt es doch nahe, aus der Gruppe von den 10 Samples nur diesen zu 
nehmen, der die höchsten Amplitude hat. Und genau das ist die Lösung. 
Die Abbildung entspricht jetzt einer Hüllkurve dieser Wellenform.

Gruß Rolf

: Bearbeitet durch User
von Rene B. (themason) Benutzerseite


Lesenswert?

@Rolf

Sehr schön gemacht. Sieht ja mittlerweile sehr ansehnlich aus dein 
Synthesizer. Schick schick.

Aber wieso musst du vorher den Bildschirm sichern beim Cursorverschieben 
? Wenn du doch eine invertierte vertikale Linie zeichnest und vor dem 
verschieben bzw bevor du deine Darstellung und/oder den Cursor änderst 
einfach die vertikale Linie erneut invertieren hast du doch wieder den 
Ausgangsbildschirm nur ohne Cursor Linie, oder ?
Das mit der höchsten Amplitude bzw dem 'zusammenfassen' von Samples hab 
ich auch mal so gemacht. Geht ganz gut und erspart einem jede Menge 
Rechenzeit.
Gerade wenn man 'nur' auf einem AVR hantiert muß man ja so einige Kniffe 
parat haben damit sich das ganze a) noch halbwegs bedienen lässt und b) 
der AVR nicht nur mit der Darstellung ausgelastet ist, sondern seine 
'Hauptaufgaben' auch noch wahrnehmen kann.

Weiter so, und schonmal nen frohes Fest und viel Spaß noch beim Basteln 
:-)

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Rene
Schön von dir zu hören :) Das DOGXL 160-7 Display besitzt leider keinen 
internen Speicher. Aus diesem Grund muss ich die Pixel, die der Cursor 
überschreibt, für eine spätere Wiederherstellung vorher sichern.

Gruß Rolf und Frohes Fest

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Wünsche Allen ein schönes Weihnachtsfest und guten Rutsch ins neue Jahr.

Ein großes Dankeschön auch an die Macher und Admins des mikrocontroller 
Forums :)

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Die Loop Funktion im Synthesizer
Mein Synthesizer ist jetzt mit einem 1MByte großen Wellenform Ram 
ausgestattet. Dadurch lassen sich auch sehr große Samples abspielen. 
Aber nur das einfache Abspielen eines Samples im Synthesizer und die 
Steuerung der Abspielgeschwindigkeit (Tonhöhe) wäre musikalisch gesehen 
etwas zu langweilig. Aus diesem Grund hat man das "Loopen" erfunden. Es 
handelt sich dabei um das wiederholte Abspielen eines bestimmten Sample 
Bereiches. Als es noch keine Sample-Player gab, hat man ein an beiden 
Enden zusammengeklebtes Stück eines Tonbandes genommen und wiederholt 
abgespielt. Eine ähnliche Technik ist im Jahre 1963 im Mellotron, dem 
Vorläufer des modernen Samplers angewendet worden.

Die Loop-Funktion für die Samples habe ich in einer Unterseite des 
Osc-Menüs integriert und kann über die Funktionstaste am Synthesizer 
aufgerufen werden. Ob ein Menü eine Unterseiten besitzt, sieht man an 
einem kleinen eingeblendeten Symbol (Fensterrahmen mit Pfeil) oben 
rechts neben der Seitennummer. An einer Funktion zum Laden verschiedener 
Wellenform-Files wird noch gearbeitet.

Um die Bedienung für die Loop Einstellung zu vereinfachen, habe ich die 
Cursorsteuerung über drei Encoder realisiert. Mit dem 1. Encoder steuer 
man den Cursor über die Wellenform. Befindet sich der Cursor jeweils am 
linken oder rechten Rand, dann wird automatisch der Wellenformauschnitt 
verschoben. Der 2. Encoder ist für die Zoom Funktion zuständig. Gezoomt 
wird immer an der aktuellen Cursor Position und in Bildschirmmitte. Mit 
dem 3. und 4. Encoder lässt sich der Loop-Anfang (LoopA) und das 
Loop-Ende (LoopB) einstellen. Zur Veranschaulichung habe ich ein Video 
auf Youtube hochgeladen.

Youtube: http://www.youtube.com/watch?v=Y-alU-4saMI


Bis zum nächsten mal und lieben Gruß. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen. Ich wünsche allen ein schönes und interessantes neues 
Jahr 2014

Zur Zeit arbeite ich an einer Soundverwaltung für meinen Synthesizer. 
Für die Datenspeicherung benutze ich eine handelsübliche 4Giga Byte 
große SDCard, auf der maximal 12800 Sounds verwaltet werden können. Von 
der SD Karte werden alle Soundparameter, Wellenformen und Samples in den 
Synthesizer geladen.Es ist schon erstaunlich, wenn man die Synthesizer 
und Sampler aus den 80er Jahren mit der heutigen Technologie vergleicht. 
Das Laden von Wellenformen und Samples dauerte damals je nach Datengröße 
schon mal etwas länger und nebenbei hatte man noch Zeit für eine Tasse 
Kaffee (siehe Video). Bevorzugte und preiswerte Speichermedien für die 
Synthis und Sampler waren damals 5.25 Zoll oder 3.5 Zoll Disketten. Die 
größeren und teuren Systeme hatte sogar schon Festplatten mit einer 
"sagenhaften" Kapazität von 10MByte. Die heutige Speichertechnologie ist 
im Vergleich dazu in astronomischer Größe gewachsen und auch wesentlich 
schneller und einfacher in ihrer Handhabung geworden. Eine Speichergröße 
von 64Giga Byte auf einer winzigen SD Karte wäre zur damaligen Zeit 
undenkbar gewesen.

Bild 1: PPG WAVETERM aus den 80er Jahren
Youtube: http://www.youtube.com/watch?v=q88NovUIPQM

Ich habe versucht, das Laden und Abspeichern von Sounddateien in meinem 
Synthesizer etwas zu vereinfachen. Dafür habe ich eine einfache 
Datenstruktur mit drei Hauptordnern auf der SD Karte entwickelt (siehe 
Bild). Im Ordner "Sound" befinden sich 100 Sound Bänk. Jede Soundbank 
enthält die Klangparameter für 128 Sounds. Pro Sound sind 256 Byte für 
die Klangparameter reserviert, das macht insgesamt pro Soundbank also 
256*128 = 32KByte an Daten. Der Ordner "WAVE" beinhaltet alle 
Wellenformen für die Klangsynthese wzB Sinus, Rechteck, Sägezähn uvm. 
Der Ordner "Sample" beinhaltet, wie der Name schon sagt, alle ladbaren 
Samples. Maximal können in 100 Sample Bänken mit jeweils 128 Samples 
verwaltet werden. Das gleiche gilt natürlich auch für den Wellenform 
Ordner. Wellenformen und Samples können in der jetzigen Softwareversion 
im Synthesizer nur geladen werden. Erstellen kann man diese aber ohne 
große Probleme mit dem Audioeditor "Audacity" unter Windows und auf die 
SD Karte kopieren. So ist dem Klangbastler kaum eine Grenze gesetzt.



Bild 2: Datenstruktur auf der SD Karte für meinen Synthesizer
(Kleiner Fehler in der Zeichnung: sollten 100 statt 99 Bänke sein).

Bild 3-4: Datei Menü in meinem Synthesizer


Bild 5: SD Karte Interface in meinem Synthesizer
Wave1Disk.jpg


Wer sich näher mit der Benutzung einer SD Karte für ein eigenes Projekt 
mit einem Mikrocontroller wzB ATmega oder Arduino beschäftigen möchte 
hier ein paar nützliche Links:

http://www.ulrichradig.de/home/index.php/avr/mmc-sd
http://www.mikrocontroller.net/articles/AVR_FAT32
http://arduino.cc/de/Reference/SDCardNotes

Bis zum nächsten Mal und lieben Gruß. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..
GIF-Format hochladen. Siehe Bildformate.
Text:

Zur Zeit wird mal wieder viel gelötet, gezeichnet und es werden 
Stücklisten geschrieben. Eine kleine Änderung gibts in der VCA 
Schaltung. Diese hat eine Lautstärkeregelung bekommen.

Bild1: VCA Schaltung mit Lautstärkeregelung


Die Stromversorgung für den Synth wurde ebenfalls etwas abgeändert und 
auf "Low cost" getrimmt. Ein AC-Netzteil mit 9 Volt/1000mA wird 
benötigt.

Bild2: Stromversorgung für den Synth

Ich bin gerade dabei das endgültige Layout für meinen Synthesizers auf 
einer Lochrasterplatte zu löten und dann ein PCB Board zu entwerfen. 
Dabei spielt die Positionierung der Bauteile eine wichtige Rolle. Die 
Platine habe ich in zwei Hälften unterteilt. Auf der linken Seite ist 
der ganze Analoge Teil wzB Stromversorung und der analoge Multimode 
Filter untergebracht. Auf der rechten Seite der komplette Digitalteil 
wzB Prozessor, Ram und SD-Karte. Das soll den Störeinfluss der 
Digitalschaltung auf die analoge Filterschaltung vermindern. Die 
Position des SD-Karteneinschubs habe ich zwecks besserer Bedienbarkeit 
nach vorne an die Gerätefront verlegt.

Bild3-7: Prototyp Synthesizer "WAVE 1"

Die Filterschaltung ist noch nicht ganz bestückt. Im Moment arbeite ich 
daran.

Bis zum nächsten mal. Lieben Gruß aus Wuppertal smile

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben..

Die vergangenen Tage hatte ich im Mutable Intruments Forum viele Ideen 
und Anregungen für die Filterschaltung in meinem Synthesizer erhalten. 
Da war u.a. auch die Rede von einer Distortion Schaltung (Verzerrer) 
oder einer Delay Schaltung für Echo und Hall. Beides sehr interessante 
Dinge, die den Filter auf jeden Fall noch interessanter machen könnten. 
Die Distortion Schaltung habe ich dank zur Verfügung stehender Bauteil 
schnell aufgebaut und getestet. Für die Delay Schaltung ist der 
Schaltungsaufwand etwas größer. Ich musste erst ein spezielles Bauteil, 
einen PT2399, bestellen. Bei dem PT2399 handelt es sich um einen Audio 
Prozessor mit Echo Funktionen. Der Stückpreis liegt bei 1,50€.

Bild 1: Filter Schaltung mit Distortion

Funktionsbeschreibung Distortion Schaltung
Das Eingangssignal wird über den Spannungsteiler R30 und R31 an den OTA 
geführt. Der Operationsverstärker IC 5B und die beiden Transistoren sind 
als Spannungsbegrenzer (Limitter) geschaltet und begrenzen die maximale 
Ausgangsspannung des Operationsverstärkers auf ca 1.0 Volt (VPP). IC 5C 
hat die Aufgabe das Signal zu verstärken. Über den Trimmer R28b wird die 
Ausgangsspannung am Operationverstärker IC 5B so eingestellt, das im 
Ruhezustand (Steuereingang 0V) das Ausgangssignal unterhalb der 
Spannungsbegenzung von 1.0 Volt liegt. Über den Steuereingang an R28 
kann jetzt die Verstärkung im OTA IC3B bzw die Verzerrung am Ausgang 
stufenlos geregelt werden und.

Bild 2-4: Signalkurven Distortion (unterer Oscilloskop Kanal ohne 
Distortion)

Sound Demo Distortion: https://soundcloud.com/rolfdegen/distortion

Youtube Video Sparta Delay: 
http://www.youtube.com/watch?v=hjWpkibWL3k#t=78

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Gestern habe ich meine bestellten Bauteile im Briefkasten gefunden. 
Schnell die Delay Schaltung aufgebaut und getestet. Das Ergebnis gibts 
auf Soundcloud :)

Bild 1: Delay Schaltung für meinen Synthesizer


Delay Demo: 
https://soundcloud.com/rolfdegen/sample-with-delay-from-my-diy

von eProfi (Gast)


Lesenswert?

Lieber Rolf,
ich danke Dir sehr, dass Du uns an Deinen Erfolgen teilhaben lässt!

Ich habe vor 25 Jahren ähnliches versucht, bin aber bei weitem nicht so 
weit gekommen. Damals wusste ich einfach noch zu wenig. Die Möglichkeit 
zum Austausch mit anderen Gleichgesinnten war gleich null.

Description
The MAXIM MAX260/MAX261/MAX262 CMOS dual second-order universal 
switched-capacitor active filters allow microprocessor control of 
precise filter functions. No external components are required for a 
variety of bandpass, lowpass, highpass, notch, and allpass 
configurations. Each device contains two second-order filter sections 
that place center frequency, Q, and filter operating mode under 
programmed control.

Mit dem MAX260 hatte ich es probiert. Schon damals habe ich von Klängen 
geträumt, wie Du sie jetzt erzeugen kannst.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hier das Innenleben des PT2399 Delay Chip und mein MCU Board vom 
Synthesizer. Bildquelle von Wolfgang aus dem CC2 Forum alias Wiesolator.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Zur Zeit arbeite ich noch ein wenig an dem Filter im Synthesizer. Die 
Delay Schaltung hat jetzt einen Panorama Regler erhalten. Es wird 
zusätzlich noch einen analogen Stereoeingang für den Filter geben. So 
lassen sich dann auch externe Audiosignale über den Filter und das Delay 
dazu mischen. Die Distortion Schaltung mußte aus Platzmangel für die 
Delay Schaltung weichen.

Kleine Klangkostprobe aud Soundcloud: 
https://soundcloud.com/rolfdegen/delay-sound-08

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Hier gibts schon vorab die ganzen Schaltpläne für mein Synthesizer 
Projekt. Kann man sich als Eagle oder JPG File herunterladen.

Download: 
https://onedrive.live.com/?cid=ebf4191b1e6970c0&id=EBF4191B1E6970C0%212280&ithint=file,.rar

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Es gibt wieder viel Neues von meinem DIY Synthesizer zu berichten.

Ich bin gerade dabei einen Programmabschnitt zu programmieren, der es 
ermöglicht, eine 16Bit WAVE-Datei von der SD Karte in den Synthesizer zu 
laden und dann als 8Bit Sample abzuspielen. Eigentlich ist eine 
WAVE-Datei ganz simpel aufgebaut. Am Anfang der WAVE-Datei ist ein 
Haeder bestehend aus 44 Byte, in dem z.B. das Format, Bitbreite und 
Samplerate gespeichert sind. Diese Header-Daten werden vom Synthesizer 
im Moment noch ignoriert. Nach den Header-Daten folgen die eigentlichen 
Sample-Daten. Diese sind bei einer 8Bit Wave-Datei vorzeichenlos 
(unsigned). Bei 16Bit bestehen sie aus 2Byte mit Vorzeichen. Das erste 
Byte ist das Low-Byte gefolgt vom High-Byte mit Vorzeichen. Um aus den 
16Bit jetzt ein Vorzeichenloses Byte für den Synthesizer zu generieren 
reicht es aus, das Low-Byte einfach fallen zu lassen und das High-Byte 
mit 128 zu addieren.

Das WAVE Format (Bild 1).
1
// set folder ---------------------------------------------------------
2
    uint8_t error_status = 0;
3
    ffcd("");
4
    ffcd("SAMPLE");ffcd(foldername);
5
    
6
    // open file ----------------------------------------------------------    
7
    if( MMC_FILE_OPENED == ffopen(sample_name,'r'))
8
    {
9
        uint32_t file_len = file.length; 
10
        // set baseaddress sram
11
        hugemem_ptr_t   p;
12
        uint32_t base = BOARD_EBI_SRAM_BASE; // 0x800000UL
13
        uint_fast8_t    data = 0;
14
        uint32_t offset = 0x00000;
15
        p=(hugemem_ptr_t)((uint32_t)base + offset);
16
        uint8_t sample; 
17
        
18
        // load WAVE-File 16Bit signed Little-endian / Low-byte first -----
19
        // Sample-Bank 01-99
20
        
21
            // skip Header from WAVE-File
22
            for (uint8_t i = 0; i < 44; i++)
23
            {
24
                sample = ffread();
25
            }
26
            
27
            file_len = ((file_len - 44) / 2);
28
            
29
            
30
            for (uint32_t i = 0; i < file_len; i++)
31
            {
32
                sample = ffread();            // load L-Byte and ignore
33
                sample = ffread();            // load H-Byte
34
                sample = sample + 128;        // convert in unsigned 8Bit
35
                hugemem_write8(p+i, sample);  // write Sample in SRAM
36
            }

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Bisher war es in meinem Synthesizer nur möglich Wave-Dateien in Mono zu 
laden. Ich möchte dieses Wochenende nutzen, um auch Stereo Dateien in 
meinen Synth zu laden. Ferner möchte ich die Auflösung von 8Bit auf 
12Bit erhöhen. Das entspricht der maximalen Auflösung der DA-Wandler im 
Xmega Chip.

Im Header einer Wave-Datei sind zB. auf Adresse 0x16 die Informationen 
über die Anzahl der Kanäle gespeichert. Bei Mono hat die Adresse 0x16 
den Wert 1 und bei Stereo den Wert 2.


Bedeutung der Daten im Riff Header (Bild 1)

Aus dem Mutable-Forum (http://mutable-instruments.net/forum/) habe ich 
einen guten Tip erhalten, wie ich das 8Bit Rauschen 
(Quantisierungsfehler) bei der DA-Wandlung per Software etwas reduzieren 
kann. Diese Funktion nennt sich "noise shaping" und verschiebt das 
Bitrauschen bei leisen Pegeln in einen höheren Frequenzbereich, so das 
es vom Ohr nicht mehr so laut wahrgenommen wird (siehe Bild).

Frequenzgang 8Bit Rauschen (Bild 2)
1
// skip Header from WAVE-File
2
            for (uint8_t i = 0; i < 44; i++)
3
            {
4
                sample = ffread();
5
            }
6
            
7
            // calculate data length
8
            file_len = ((file_len - 44) / 2);
9
            
10
            uint8_t quantization_error;
11
            int16_t signed_sample_16;
12
            uint8_t sample_l;
13
            uint8_t sample_h;
14
            
15
            for (uint32_t i = 0; i < file_len; i++)
16
            {
17
                // load 16Bit sample-data
18
                sample_l = ffread();            // load L-Byte 
19
                sample_h = ffread();            // load H-Byte
20
                
21
                // convert to signed 16Bit
22
                signed_sample_16 = (((int16_t)sample_h)<<8 | sample_l);
23
                
24
                // calculate data for noise-shaping
25
                int32_t sample_16 = (int32_t)(signed_sample_16);
26
                sample_16 += quantization_error;
27
                if (sample_16 < -32768){sample_16 = 32768;}
28
                else if (sample_16 > 32767){sample_16 = 32767;}
29
                int8_t sample_8 = sample_16 >> 8;
30
                quantization_error = sample_16 - ((int32_t)(sample_8) << 8);
31
                
32
                // convert to unsigned 8Bit
33
                sample_8 = sample_8 + 128;
34
                
35
                // write to 1MByte SRAM
36
                hugemem_write8(p+i, sample_8);
37
            }

Hier ein kleines Soundbeispiel für die Rauschreduzierung mit und ohne 
Noise Shaping: https://soundcloud.com/rolf-degen/noise-shaping-2

Gruß Rolf
1.Sample mit Noise Shaping und 2.Sample ohne Noise Shaping

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Um die Kosten für einen Bausatz zu senken, will ich mal schaun ob ein 
anderes LC-Display wzB das SSD1289 von sainsmart am Synth funktioniert. 
Es handelt sich hierbei um ein 3.2" großes Farb LCD das mit einen 
Straßenpreis von 7-15 Euro fast überall erhältlich ist.

SainSmart 3.2" Color LCD 320x240 Pixel (Bild 1)

Aber hier mein erster Entwurf für das GUI mit dem neuen Display. Da es 
nur im 16Bit Modus angesteuert werden kann, musste ich die Portleitungen 
auf dem MCU-Board etwas umbelegen. Das Display wird jetzt über einen 
16Bit Datenbus angesteuert, was den Vorteil hat, das es wesentlich 
schneller die Grafik aufbaut als beim alten Display.

Erster GUI Entwurf auf dem LCD (Bild 2)

Schaltbild vom MCU Board (Bild 3)

Im Anhang die C-Routinen zum Ansteuern des SainSmart 3.2" LCD (SSD1289).


Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Eine kleines Problem das vlt. mit ein wenig Mathematik (ohne Fließkomma) 
gelöst werden kann ?

Ich möchte die 128 Positionen der weiße Markierung auf dem 
Encoder-Drehknopf berechnen und auf dem LCD neu zeichnen. Ohne 
Berechnung würde eine Wertetabelle für jede der 128 Positionen des 
Drehknopfes für die X- und Y-Position wertvollen Speicherplatz 
verschwenden. Vielleicht gibts ja eine mathematische Lösung.


Weiße Markierung auf dem Drehknopf (Bild 1)


Ich habs mal wieder geschafft Dank Oliver vom "Mutable Forum" 
(http://mutable-instruments.net/). Wie bei vielen komplizierten Dingen 
hat mich das ein wenig Ehrgeiz und Gedankenschweiß gekostet ;) Im Anhang 
der C-Code,  Sinus Tabelle und die Bitmap vom Knopf.

Kleines Youtube Video mit der Knop Demo: 
https://www.youtube.com/watch?v=hqgHXLH7daI&feature=youtu.be

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Ein roter Knopf in Aktion

Youtube: https://www.youtube.com/watch?v=Juv843YsqZY&feature=youtu.be

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Kleiner Zwischenstand meiner Entwicklungsarbeit am Synth. Hab gerade die 
LFO1-Menu Page neue entworfen. Mit dem Regler "Wave" kann man jetzt eine 
LFO Wellenform selektieren.

Bild: LFO1 Menu Page

Gruß Rolf

von Erich (Gast)


Lesenswert?

Hallo Rolf,

komme auf diese Info aufgrund deines Betrags vom 26.01.2013 bzgl. der 
Verwendung des "ALFAT OEM Board".
Am 10.07.2013 informierst du uns allerdings darüber, das Board jetzt 
doch nicht mehr verwenden zu wollen weil zu teuer für dein Projekt.
Vorher hattest du geschrieben, bereits erste SW für das o.a. Board 
erstellt zu haben.

Da ich ggf. das ALFAT Produkt für eine Logger-Funktionalität an einem 
sehr kleinen uC nutzen will, wäre mir mit deiner "alten" SW evtl. im 
ersten Schritt weitergeholfen.

Soll ich dir ein PN schreiben oder wie komme ich an deine "alte" SW ran?

Nochwas: Dein (neuer) Downloadlink vom 01.06.2014  (ondrive Link) schein 
nicht (mehr?) zu funktionieren.

Gruss

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Erich

Für das ALFAT SD Board habe ich leider keinen Quellcode mehr gefunden. 
Hab den vermutlich gelöscht als ich mich entschieden habe, die SD Karte 
direkt am XMega Prozessor zu betreiben. Bei ALFAT gibts aber Code 
Beispiele zum Download: 
https://www.ghielectronics.com/downloads/ALFAT/ALFAT_SoC_Processor_User_Manual.pdf

Hab dir mal Code Beispiele von ALFAT hochgeladen.
Code-Beispiele: 
https://onedrive.live.com/?cid=EBF4191B1E6970C0&id=EBF4191B1E6970C0%212594

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Bei der Ansteuerung des neuen LCD ist mir aufgefallen, das man die 
Übetragungsgeschwindigkeit mit der die Daten vom Xmega Prozessor zum LCD 
gesendet werden noch optimieren kann. Jeder Port des ATxmega kann als 
virtuelles Portregister konfiguriert werden. Hat man einen virtuellen 
Port konfiguriert, können bei diesem die selben Pinkonfigurationen wie 
bei normalen Ports vorgenommen werden. Insgesamt stellt der Xmega 4 
dieser Register zur Verfügung. Durch die Verwendung eines virtuellen 
Ports erfolgt die Übertragen eines Datenbytes innerhalb eines Taktzyklus 
von 32nsec bei 32MHz Systemtakt. Ein Standart Portzugriff dauert im 
Vergleich dazu doppelt so lang also 64nsec.

Virtuelle Port Konfiguration
1
// Standart Zugriff auf PortA benötigt 2 Taktzyklen
2
PORTA.DIR = 0xFF;   // Datenrichtung auf Ausgang
3
PORTA.OUT = 0xFF;   // PortA auf hight
4
5
// Virtueller Zugriff auf VPORT0 (PortA) (benötigt 1 Taktzyklus)
6
PORTCFG.VPCTRLA |= PORTCFG_VP0MAP_PORTA_gc;   // lege PortA auf Virtuellen VPort0
7
VPORT0.DIR |= 0xFF;   // Datenrichtung auf Ausgang 
8
VPORT0.OUT = 0xFF;   // VPort0 auf hight


Eine weitere Möglichkeit die Übertragungsgeschwindigkeit zu erhöhen ist 
die, den Prozessortakt des Xmega von 32MHz auf 48MHz zu erhöhen. Der 
Xmega arbeitet dann zwar außerhalb seiner Herstellerspezifikation, aber 
das scheint den Xmega Prozessor nicht weiter zu stören, denn er zeigte 
in meinen ganzen Tests keine Ausfallerscheinung. Erhöhte Temperatur 
konnte ich auch nicht feststellen. Werde den 48MHz Takt aber noch einmal 
bei einer anderen Produktcharge des Xmegas testen, bevor ich das 
implementiere.


Xmega Takteinstellung 48MHz (ext. 16MHz Quarz)
1
void init_clock(void)
2
{    
3
    // set startuptime for extern Crystal Oscillator
4
    OSC_XOSCCTRL = OSC_XOSCSEL_XTAL_16KCLK_gc | OSC_FRQRANGE_12TO16_gc;
5
    
6
    // enable ext. 16MHz Crystal Oscillator
7
    OSC.CTRL |= OSC_XOSCEN_bm;
8
    
9
    // wait oscillator is stable
10
    while(!(OSC.STATUS & OSC_XOSCRDY_bm));
11
    
12
    // set PLL  16MHz * 2
13
    OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 0x03; // 0x02 = 32MHz, 0x03 = 48MHz
14
    
15
    // enable PLL
16
    OSC.CTRL |= OSC_PLLEN_bm;
17
    
18
    // wait PLL is stable
19
    while(!(OSC.STATUS & OSC_PLLRDY_bm));
20
    
21
    // protect I/O register
22
    CCP = CCP_IOREG_gc;
23
    
24
    // enable PLL-Clock
25
    CLK.CTRL = CLK_SCLKSEL_PLL_gc;
26
    
27
    // Peripheral Clock output: Disabled
28
    PORTCFG.CLKEVOUT=(PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) |
29
    PORTCFG_CLKOUT_OFF_gc;
30
}

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo..

Ich bräuchte mal einen Tip. Wie kann ich das Phasen Jitter (siehe Bild 
ca. 3Khz) in meinem Synthesizer verringern. Für die Klangerzeugung 
benutze ich die DDS Synthese. Das Phasen Jitter beträgt in allen 
erzeugten Frequenzen 25usec. Das entspricht genau der Abtastrate im 
Synthesizer.

Code Beispiel DDS-Synthese in meinem Synth
1
//————————————————————————————————————-
2
// load phase register all 25usec (40KHz Sample Frequence)
3
//————————————————————————————————————-
4
LoadPhaccu1:
5
LDS phakku0, phaccu1+0  ; (R26) load 32Bit Phaseaccu
6
LDS phakku1, phaccu1+1  ; (R27)
7
LDS phakku2, phaccu1+2  ; (R28)
8
LDS phakku3, phaccu1+3  ; (R29)
9
10
//————————————————————————————————————-
11
// Load 256 Byte Sample from 1MB XRAM Addr. 0x0000
12
//————————————————————————————————————-
13
Osc1Sample:
14
MOV R30, phakku3  // set XRAM address (is H-Byte Address from Phaseaccu)
15
LDI R31, 0x00 
16
LDI R21, 0x00
17
LDI R22, 0x80  // load AddressOffset 0x80 (is necessary for addressing the XRAMs in xmega)
18
ADD R21, R22  // add
19
OUT 0x3B, R21  // set XRAM Address to EBI Port
20
LD R1, Z  // load 8Bit Sample from XRAM in R16
21
OUT 0x3B, R1  // special EBI command
22
23
//————————————————————————————————————-
24
// inc Phaseaccu OSC1 (32Bit)
25
// ————————————————————————————————————
26
LDS pha_inc0, phaccu_stepsize1+0  ; load 24 Bit PhaseIncrement
27
LDS pha_inc1, phaccu_stepsize1+1
28
LDS pha_inc2, phaccu_stepsize1+2
29
30
ADD phakku0, pha_inc0  ; add PhaseIncrement 
31
ADC phakku1, pha_inc1
32
ADC phakku2, pha_inc2
33
LDI R2, 0x00
34
ADC phakku3, R2
35
36
//————————————————————————————————————-
37
// save Phaseaccu
38
// ————————————————————————————————————
39
STS phaccu1+0, phakku0  ; save Phaseaccu
40
STS phaccu1+1, phakku1
41
STS phaccu1+2, phakku2
42
STS phaccu1+3, phakku3
43
44
//————————————————————————————————————-
45
// Other functions for sound calculation (sample is present in r1)
46
// ————————————————————————————————————
47
...

von Steffen S. (bitmaster)



Lesenswert?

Interessantes Problem. Ich habe für meinen Rechteckgeneratoren für die 
AY-3-8910 Emulatoren eine Art Interpolation eingebaut. Dadurch hört sich 
der Rechteck schon viel besser an. Ohne Interpolation stört das Jitter 
schon stark, besonders bei höheren Frequenzen.
Dieses Verfahren habe ich z.B. hier verwendet:
http://www.youtube.com/watch?v=8IbIF8ySEHA&list=UU4Awd2MW09pjAJPmH1fSTgw&;
oder hier:
http://www.youtube.com/watch?feature=player_detailpage&list=UU4Awd2MW09pjAJPmH1fSTgw&v=pL8v8zhmBoA

Man muss bedenken, dass man eigentlich nicht wirklich ein Rechtecksignal 
hören kann da dass Ohr sozusagen ein Tiefpass ist. (und der 
NF-Verstärker natürlich auch) Man muss also ein Tiefpassgefiltertes 
Rechtecksignal erzeugen. Dann hat sich auch das Jitterproblem erledigt.
Das ist die 'bandlimited square wave generation'. Habe ich bisher noch 
nicht angewendet. Aber schonmal eingearbeitet ;)

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Danke für die Info.

Ich versuche mal die Interpolation in den Assembler Code einzubinden.

Bandlimited Wellenformen habe ich schon implimentiert. Klingen auch ganz 
gut. Der Jitter ist mein Hauptproblem.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Steffen

Das ist mein ASM Code Beispiel nach einer Idee von Oliver aus dem 
Mutable Forum:
1
//-------------------------------------------------------------------------
2
// Load Sample Osc1 from 1MB XRAM Addr. 0x0000
3
//-------------------------------------------------------------------------
4
Osc1Sample:
5
mov  r30, phakku3    // load H-Byte Phaseaccu (is same Address vor XRAM)
6
ldi  r31, 0x00 
7
ldi  r21, 0x00
8
ldi  r22, 0x80      // load Adress Offset (XRAM)
9
add  r21, r22      // and add with XRAM Offset Address in R18
10
out  0x3b, r21      // set XRAM Address to EBI Port
11
ld   r16, Z          // load first Sample from XRAM
12
ld   r17, Z+         // load secound Sample from XRAM
13
out  0x3B, r1      // special EBI command
14
15
mov  r0, r16
16
mov  r1, r17
17
18
// oliver
19
mul phakku2, r1    // mul L-Byte Phakku mit r1
20
movw R30, r0
21
com phakku2
22
mul phakku2, r0
23
add r30, r0 
24
adc r31, r1
25
eor r1, r1

Das 16Bit Ergebnis soll in R30+31 stehn. Leider funktionierts irgendwie 
nicht. Die Routine gibt nur Müll aus. Im Anhang die 
Interpolationsroutine von Oliver
1
static inline uint8_t InterpolateSampleRam(
2
    const uint8_t* table,
3
    uint16_t phase) {
4
  uint8_t result;
5
  uint8_t work;
6
  asm(
7
    "movw r30, %A2"           "\n\t"  // copy base address to r30:r31
8
    "add r30, %B3"            "\n\t"  // increment table address by phaseH
9
    "adc r31, r1"             "\n\t"  // just carry
10
    "mov %1, %A3"             "\n\t"  // move phaseL to working register
11
    "ld %0, z+"               "\n\t"  // load sample[n]
12
    "ld r1, z+"               "\n\t"  // load sample[n+1]
13
    
14
  "mul %1, r1"              "\n\t"  // multiply second sample by phaseL
15
    "movw r30, r0"            "\n\t"  // result to accumulator
16
    "com %1"                  "\n\t"  // 255 - phaseL -> phaseL
17
    "mul %1, %0"              "\n\t"  // multiply first sample by phaseL
18
    "add r30, r0"             "\n\t"  // accumulate L
19
    "adc r31, r1"             "\n\t"  // accumulate H
20
    "eor r1, r1"              "\n\t"  // reset r1 after multiplication
21
    "mov %0, r31"             "\n\t"  // use sum H as output
22
    : "=r" (result), "=r" (work)
23
    : "r" (table), "r" (phase)
24
    : "r30", "r31"
25
  );
26
  return result;

Gruß Rolf

: Bearbeitet durch User
von Steffen S. (bitmaster)


Lesenswert?

Meine Interpolation ist für die direkte Erzeugung einer 
Rechteckschwingung gedacht. Also ohne Wavetable.
Es ist einfach nur ein Register (v). Das höchstwertige oder ein höheres 
Bit (hier &H1000000) gibt das Rechtecksignal an. Es wird je nach Freq 
immer ein bestimmter Wert (incr) addiert.
Durch die Interpolation werden die Flanken "weicher" da diese zwischen 
den 2 Rechteckamplituden liegen.
Warum dein Code nicht funktioniert kann ich nicht sagen, das musst du 
selber rausfinden (kenne AVR nicht besonders gut).
In vb.net mache ich das so:
1
                        vtmp = v + incr
2
                        If v And &H1000000 Then
3
                            sample = 1
4
                        Else
5
                            sample = -1
6
                        End If
7
8
                        If (v Xor vtmp) And &H1000000 Then  ' edge changed
9
                            c = 1 - 2 * (vtmp And &HFFFFFF) / incr
10
                            sample = sample * c
11
                        End If

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Rolf Degen schrieb:
> Eine weitere Möglichkeit die Übertragungsgeschwindigkeit zu erhöhen ist
> die, den Prozessortakt des Xmega von 32MHz auf 48MHz zu erhöhen. Der
> Xmega arbeitet dann zwar außerhalb seiner Herstellerspezifikation, aber
> das scheint den Xmega Prozessor nicht weiter zu stören, denn er zeigte
> in meinen ganzen Tests keine Ausfallerscheinung. Erhöhte Temperatur
> konnte ich auch nicht feststellen. Werde den 48MHz Takt aber noch einmal
> bei einer anderen Produktcharge des Xmegas testen, bevor ich das
> implementiere.

Das funktioniert nur mit den uralten XMEGA_A1, Revision G und früher, 
sowie dann wieder mit den A1U und den anderen USB-XMEGAs. Revision H des 
A1 lief bei mir nur bis 40Mhz, dann war Schluss. Hatte ich damals mit 
meinem SD-Karten-Wave-Recorder getestet.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Knut

Die Übertrakung war nur so eine Idee, die bei meinem Alten Xmega128A1 
auch funktioniert. Wollte nur mal wissen, ob andere Komponenten das so 
mitmachen. Die SD Karte SD Karten (4GB Class4) hatten keine Probleme 
beim Lesen. Schreibfunktion konnte ich nicht testen.Fürs LCD waren die 
Ansteuersignale schon zu kurz. Aber wie gesagt, war nur so ein Test :)

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Das Beispiel Programm funktioniert. Um zwei Bytes für die Interpolation 
hintereinander zu laden kann man gewöhnlich Z+ (ld first_sample, Z+) für 
die Adressierung des nächsten Samples benutzen. Dann würde aber die 
Adresse 0x100 am XRAM (externes 1MByte SRAM) anliegen und nicht 0x001. 
Aus diesem Grund wird die Adresse des Phasenaccu inc und erneut in das 
Adressregister für das XRAM geschrieben.

1
//-------------------------------------------------------------------------
2
// Load 1.Sample from 1MB XRAM Addr.  (sample size is 256 Byte)
3
//-------------------------------------------------------------------------
4
sample1 = 16
5
6
mov  r30, phakku2    // load Phaseaccu (is same Address vor XRAM)
7
ldi  r31, 0x00
8
ldi  r21, 0x00
9
ldi  r22, 0x80      // load Adress Offset (XRAM)
10
add  r21, r22      // and add with XRAM Offset Address in R18
11
out  0x3b, r21      // set XRAM Address to EBI Port
12
ld   sample1, Z      // load Sample from XRAM
13
out  0x3B, r1      // special EBI command
14
15
//-------------------------------------------------------------------------
16
// Load 2.Sample from 1MB XRAM Addr.+1
17
//-------------------------------------------------------------------------
18
sample2 = 17
19
inc r30          // inc Phaseaccu
20
out  0x3b, r21      // set XRAM Address to EBI Port
21
ld   sample2, Z      // load Sample from XRAM
22
out  0x3B, r1      // special EBI command
23
24
//-------------------------------------------------------------------------
25
// Interpolation
26
//-------------------------------------------------------------------------
27
mul phakku1, sample2
28
movw R30, r0
29
com phakku1
30
mul phakku1, sample1
31
add r30, r0 
32
adc r31, r1
33
eor r1, r1
34
mov sample1, r31    // 8Bit Result in sample1

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Beispiel im Bild für die Interpolation in meinem Synth.
Obere Signalkuve ist interpoliert und die untere nicht.

Youtube: https://www.youtube.com/watch?v=L_BU1DcWZU8&feature=youtu.be

Das Ergebnis hört sich schon viel besser an :)  Für die Wellenformen 
Rechteck und Sägezahn werde ich Bandlimited Waves verwenden.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöli.. oder so  :nihao:

Ich hoffe euch allen gehts gut. Der Name "DIYWA" für meinen Synthesizer 
gefällt mir. Die ersten drei Buchstaben "DIY" für Do It Yourself und 
"WA" für Wave. Klingt auch irgendwie cool  :supi:

Heute habe ich mich etwas mit der Grafik für das TFT Display 
beschäftigt. Für die Wellenformdarstellung bzw Scope-Funktion wollte ich 
dicke Linien zeichnen. Die Standart Liniebreite von einem Pixel kann man 
bei größerer Entfernung nicht mehr genau erkennen. Zuerst hatte ich 
versucht, zwei Linien mit einer Verschiebung von einem Pixel in X und Y 
Richtung zu zeichnen. Mit dem Ergebnis war ich aber nicht sonderlich 
zufrieden. Die beiden Linien liefen an manchen Stellen etwas auseinander 
(Bild 1). Dann kam mir aber der richtige Gedanke. Ich hatte mal gelesen, 
das Grafikkarten im PC Dreiecke benutzen um Geometrische Formen oder 
andere Dinge zu zeichnen. Also habe ich meine Routine fürs Zeichenen 
einer dicken Linie etwas abgeändert. Statt nur einen Pixel an der X- und 
Y-Koordinate zu zeichnen habe ich drei Pixel mit einem Verstatz von +1 
Pixel an die X- und Y-Koordinate gezeichnet.

Bild 1: Linie mit 2 Pixel
1. Pixel auf X und Y
2. Pixel auf X+1 und Y+1

Bild 2: Linie mit drei Pixel
1. Pixel auf X und Y
2. Pixel auf X+1 und Y
3. Pixel auf X und Y+1

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Leute von Heute smile

Ich verwende das 3.2' TFT von SainSmart mit SSD1289 in meinem
Synthesizer Projekt. Die Ansteuerung und Initialisierung sowie Grafik 
und Textausgabe
funktionieren mit der Eingebunden Library wunderbar und problemlos. Jetz
möchte ich aber ein digitalisiertes Audio-Signal als Wellenform in einem
Gitterraster wie zB auf einem Oszilloskop darstellen. Der
Display-Controller SSD1289 bietet dafür die Möglichkeit zwei
Windowsbereiche zu definieren und irgendwie übereinander zu legen
(Picture in Picture Mode). Das 1.Windows wäre dann mein Raster und das
2.Windows wäre meine digitalisierte Audio-Wellenform. Leider schaffe ich
es nicht, beide Windows übereinander zu legen und gleichzeitig
darzustellen. Hab diverse Register-Settings ausprobiert, aber keine
funktionierte.

Bild 1: Register-Settings im SSD1289 Controller
Im Bild 1 ein Auszug aus dem Manuel des Controllers SSD1289 in Bezug auf
den Picture in Picture Modus. Vielleicht hat jemand eine Idee.

Bild 2: MiniScope im "DIYWA 1"
Aktuell verwende ich einen Windowsbereich im Ram des Displays. Darin
werden Raster und Wellenform immer wieder neu gezeichnet was viel Zeit
kostet (siehe Video).

Youtube: https://www.youtube.com/watch?v=cNkAbWzbGfE&feature=youtu.be

Vielen Dank für Eure Hilfe. Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Es gibt einen neuen DIY Synthesizer namens "Groovesizer TB2".
The TB2 is a 4 note paraphonic wavetable synth with (digital) filter, 
envelope and LFO.
In addition to the built-in wave shapes (sine, triangle, saw, square, 
noise), additional wave shapes can be loaded from SD card.
For sound generation, it makes use of the two 12-bit DACs built into the 
Due’s ATSAM3X8E processor (output is mono in the current configuration, 
but stereo operation is also possible).
The TB2 will be available in kit form (ETA December 2014).

Bild 1: Der "Groovesizer"

Youtube: 
https://www.youtube.com/watch?v=8N2JAbtbiMk&feature=youtube_gdata_player


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben..

Habe heute die Envelope Menüseiten fertig gestellt. Rechts ist ein 
kleines Fenster in dem in Echtzeit die Envelope Kurve gezeichnet wird, 
wenn eine Midi-Note empfangen wird.

Bild 1: Envelope Page

Grüße Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Freunde..

Mich beschäftigt schon seit längerer Zeit ein Problem mit dem digitalen 
ADSR Generator in meinem Synthesizer. Wenn ich in meinem monophonen 
Synthesizer zwei Midi-Noten sehr schnell hintereinander spiele ohne 
dabei die Release Phase der 1.Note abzuwarten, dann ensteht ein 
störendes Klick Geräusche zwischen den beiden Noten (siehe roter Kreis 
Bild 1).

Mein ADSR-Generator funktioniert nach folgenden Regeln. Wenn ich eine 
Keyboard Taste drücke dann startet der ADSR bei einem Level von Null. 
Drücke ich während der ADSR-Phasen eine zweite Taste, dann startet der 
ADSR wieder bei einem Level von Null.

Bild 1: Signalverlauf von zwei Noten die kurz hintereinander angespielt 
werden

Um das zu vermeiden, könnte man den ADSR-Generator retriggern und den 
neuen Attack-Level auf den auf den letzten Wert des ADSR vor der 
Retriggerung setzen. Das wird zB. beim ADSR-Modul A-140 von der Firma 
Doepfer gemacht (siehe Bild 2).

Bild 2: ADSR-Modul A-140

Ich hab den Code in der ADSR Envelope Routine etwas abgeändert. Jetzt 
wird der aktuelle ADSR-Wert der 1.Note als neuer Startwert für den ADSR 
der 2.Note benutzt. Im Bild kann man den Hüllkurvenverlauf der beiden 
Noten gut erkennen.

Bild 3: Ergebnis der Änderung: Keine Klick Geräusch zwischen zwei Noten

Ein Problem gibts aber noch. Wenn der DDS Phasengenerator beim Starten 
der Samples auf Null zurückgesetzt wird um den Sample ab Anfang 
abzuspielen, dann gibts wieder Klick Geräusche zwischen zwei Noten. Mal 
schaun wie ich das lösen kann :(

Grüße aus Wuppertal. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Kleines Update für die Dateiverwaltung. Es werden jetzt alle WAV-Dateien 
im 8/12/16/24 Bit Format geladen. Angezeigt wird der Dateiname mit 
maximal 8 Zeichen sowie die Auflösung und die Dateigröße. Eine 
Datumsanzeige ist für später geplant.

Bild: WAV-Samples im Datei Explorer

Zur Zeit verbessere ich die Programmabläufe im inneren Kern des Synthis. 
Man nennt das im Fachjargon auch statemachine (Zustandsautomat).

Vereinfacht dargestellt sieht die "Statemachine" im Synthi dann so aus 
wie im Bild 2.

Um Programmablaufpläne zu zeichnen gibts hier eine schöne Freeware 
namens Diagram Designer
Download: http://www.fosshub.com/Diagram-Designer.html

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo..

Ich bin gerade am überlegen, wie ich eine Wellenform Grafik zB mit einer 
horizontalen Länge von 402 Pixel auf ein 320 Pixel breites Grafik LCD 
verkleinern kann, so das es auf das ganzen Breite passt.


Lösungsansatz 1
Ich teile die Anzahl Wellenform Pixel / Anzahl LCD Pixel = 1,25

Geht aber nicht ganz auf, da nur jeder 2.Pixel gezeichnet wird  verwirrt 
(siehe Bild)

Lösungsansatz 2
Auf dem LCD bleiben noch 82 Pixel frei. Um diesen Platz auszunutzen 
teile ich die 402 Pixel / 82 = 4 und zeichne jeden 4.Bildpunkt der 
Wellenform Grafik zweimal  ?

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Aus dem mutable-instruments Forum kam mal wieder die rettende Idee.

PS: Oliver du bist der Größte smile

Nach seiner Idee konnte ich das Problem dann so lösen:
1
// draw wave-file ————————————————————-
2
3
uint32_t source = 0;
4
uint32_t increment = (uint32_t)(file_lenght << 8)/310;
5
6
for (uint16_t i = 4; i < 315; i++)
7
{
8
uint8_t sample = hugemem_read8(p + (source >> 8)); // p = xram startadr
9
10
sample = sample >>1;
11
source += increment;
12
uint16_t x0 = i;
13
uint8_t y0 = 94; // middle position of screen
14
15
if (sample > 64)
16
{ y0 = 94-(sample  64); sample = sample  64;}
17
else
18
{y0 = 94; sample = 64  sample;}
19
20
vline(x0, y0, sample, color_orange); // plot sample on screen
21
}

Das Resultat seht ihr auf dem Bild.

LG Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Zur Zeit programmiere ich die Cursor und Loop-Funktionen für das neue 
Display neu. Wegen der höheren Auflösung müssen alle Routinen geändert 
werden. Bei dieser Gelegenheit miste ich auch alte und langsame Routinen 
aus.

Ein kleiner Trick wurde verwendet, um den Cursor schnell über die 
Wellform zu bewegen. Ein 610 Byte großer Buffer im externen SRAM des 
Synthesizers dient als Zwischenspeicher für 310 vertikale 
Linienkoordinaten. Aus den 310 vertikalen Lienen Koordinaten berechne 
ich die aktuelle Wellenformdarstellung aus dem Soundspeicher . Beim 
Trüberfahren und verlassen des Cursor wird die vertikale Linie wieder 
neu gezeichnet (restauriert). Somit ist kein kompletter Bildspeicher für 
jeden Pixel notwendig und das Neuzeichnen funktioniert dadurch sehr 
schnell.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen miteinander..

Es gibt wieder was neues für die Ohren. Aber dieses mal nicht von mir, 
sondern von Johannes Taelman.
Er hat einen sehr interessanten Synthesizer auf Basis eines ARM 
Cortex-M4 Chips entwickelt und diesen
möchte ich euch nun vorstellen.

Der Axoloti Synthesizer ist eine Mischung aus Hard- und Software. Am PC 
werden die verschiedenen
Klangmodule wie bei einem Modularen Synthesizer mit dem Axoloti-Patcher 
zusammengebaut und
vernetzt. Per USB wird das Programm in den Speicher des Synthesizers 
übertragen und kann per Midi
gespielt werden. Das interessante dabei ist, das vor der Übertragung der 
Patch am PC in Realtime
vorgehört werden kann

Youtube: https://www.youtube.com/watch?v=i22_KoAqmpI#t=24
Axoloti-Website: http://axoloti.be/
Axoloti-Patcher: https://www.youtube.com/watch?v=d7Xv99v1RwI

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Heute habe ich die zwei neuen Ersatz XMega100 Breakout Boards bekommen 
und die Stiftleisten angelötet. Zum Ausprobieren habe ich diese in den 
Stecksockel auf dem Motherboard vom Synthesizer gesteckt und mit 
ATMEL-Studio geflasht. Die beiden Breakout Boards funktionieren 
fehlerfrei. Jetzt kann ich ohne Risiko den Xmega Prozessor 10.000 mal 
umprogrammieren (flashen) ohne das ich Angst haben muss, das ein Bit 
nicht mehr funktioniert smile

Bild: XMega100 Breakout Board


Zur Zeit arbeite ich noch an der Zoom-Funktion für die Anzeige der 
Wellenform und den Loop-Points. Ich hoffe das ich das dieses Wochenende 
endlich hin bekomme.

Lieben Gruß aus Wuppertal. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo liebe Freunde der Musik...

Vom Elektor Magazin soll es in der Januar und Februar Ausgabe einen 
neuen Synthesizer Bausatz
geben. Der "J2B Synthesizer" besitzt auch wie der Axoloti Synthesizer 
einen 32-Bit ARM Cortex-
M3 Prozessor für die Klangerzeugung.

Die Inspiration für die Entwicklung des J²B SYNTHESIZER kam durch den 
8-Bit Synthesizer
ATmegatron von Paul Soulsby (http://soulsbysynths.com/).


Hier einige Daten:
Monophonic 9-bit synthesizer
32 waveforms + user defined
15 filter types
2 envelope generators
LFO with 16 waveforms
15-pattern arpeggiator
16 patch memories
6 live controls
MIDI
Patch saving/loading over MIDI
NXP LPC1347 32-bit ARM Cortex-M3 microcontroller
2 output channels
Open Source & Open Hardware design

Den J²B SYNTHESIZER kann man sich auf Youtube auch anhören: 
https://www.youtube.com/watch?v=rwNBSdC3ZqA#t=16

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Gestern habe ich die Bauteile für meinen Shruthi Synthesizer bekommen. 
Da ich zu den ungeduldigen Menschen zähle, habe ich eine Nachtschicht 
eingelegt und den Shruthi zusammen gelötet. So in den frühen 
Morgenstunden wäre ich fast mit dem Lötkolben in der Hand eingeschlafen 
und bin dann doch ins Bett gegangen..  Augenzwinkern

Bild1: Mein Shruthi Synthesizer

Dank der guten Dokumentation und Lötanleitung auf der Mutable Instrument 
Website ist der Shruthi sehr einfach und leicht zu löten und schnell 
zusammenzubauen. Beim Bestellen der Bauteile sollte man beachten, das es 
unterschiedliche Stücklisten für verschieden Lieferanten wzB Mouser oder 
Reichelt gibt. Ich habe mich für Reichelt entschieden, da dieser 
Lieferant kostengünstiger ist. Ein kleines Problem gabs bei der 
Bestellung der Tasten. Die Original Tasten gabs bei Reichelt nicht und 
ich musste dafür andere Tasten nehmen. Bei Mouser bekommt man die 
Original Tasten und die anderen Bauteile problemlos geliefert.

Stückliste Reichelt: 
https://secure.reichelt.de/index.html?&ACTION=20&LA=5010&AWKID=1026199&PROVID=2084

Stückliste Mouser: 
https://www.mouser.de/ProjectManager/ProjectDetail.aspx?AccessID=dcda87764c

Dank meiner langjährigen Lötkünste war der Shruthi schnell 
zusammengelötet und betriebsbereit. Beim Flashen der aktuellen Firmware 
über ATMEL STUDIO hatte ich ein kleines Problem. Die Voreinstellung für 
die PDI Clock-Rate von 1MHz für den Mikrocontroller ATmega644P muss im 
Menü auf 125KHz herunter gesetzt werden, da sonst der ATmega644P nicht 
erkannt wird..

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen

So.. am Wochenende hab ich mal wieder fleißig am Synth programmiert und 
den Step Sequenzer integriert. Er ist noch nich ganz fertig, aber schon 
lauffähig smile

Noten Symbol: Ausgewählte Midi-Note von 0-127
H ist die Notendauer
V ist die Lautstäke der Note und wird durch einen blauen Balken 
angezeigt
Roter Punkt bedeutet das der Step aktiv ist. Grau bedeutet ausgeschaltet

Später wirds noch eine Reset und Skip Funktion für jeden Step geben.

Bild1: Der Step Sequenzer im "Degenerator"

Das Ganze kann man sich auf Youtube ansehen und anhören. Der Ton kommt 
von der Webcam und ist leider nicht so prickelnd :(

Youtube: 
https://www.youtube.com/watch?v=pIb-1a0dA6I&list=UUXQSpP0qn5MXSkyDo6PZ4Cw

Gruß Rolf

: Bearbeitet durch User
von Rene B. (themason) Benutzerseite


Lesenswert?

Echt sehr schick. :)

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Hallo, beobachte schon seit längerer Zeit dein Projekt in div. Foren. 
Gratulation dazu!
Ich selbst habe, nach dem Bau eines 4-stimmigen AVR-hybrid Synth, auch 
ein neues Projekt am Laufen. Vielleicht interessieren dich die ein oder 
anderen Eckdaten:
Quasi drei "Module" bzw. Platinen:
"Klangerzeuger" ist ein PIC32MX250xx, der auf 68MHZ getaktet ist. Clou 
an diesem PIC: I2S! D.h. ich habe zwei 16 Bit DAC's daran gehängt 
(PT8211-S) und komme somit auf 4 analoge Einzelausgänge. Des weiteren 
hängt noch ein 8-fach 8-bit DAC daran (LTC1665) womit ich die analogen 
Filter ansteuern kann. Als Klangquelle nehme ich 16-bit Wavetables mit 
jeweils 1024 steps (hörbarer Unterschied zu den 128ern, v.a. bei tiefen 
Frequenzen!). Normale Wavetables (Waldorf Blofeld) können auch 
importiert werden.
Direkt mit dem PIC ist das Quad-analog Filterboard verbunden. Basis ist 
der VCA-Chip SSM2164 (LP/HP/BP). Ähnliches Design wie beim Shruti.
Die dritte Ebene ist die "Steuerzentrale": Da verwende ich einen 
leaflabs maple mini clone um 3-4 Euro (STM32F103CB). Der hat einen 
USB_MIDI Stack, d.h. er wird über USB als Midi Interface erkannt. An dem 
hängt die notwendige Peripherie wie: (touch)TFT, OLED, Encoders, 
Buttons, SPI-Flash-ROM (64M-bit/8M-byte Winbond W25Q64) für Patches und 
Wavetables, "echtes" MIDI,... somit ist der PIC komplett frei für die 
Klangerzeugung. Verbindung STM32 zu PIC erfolgt über I2C, d.h. es werden 
nur die notwendigen Steuerbefehle übermittelt.
Kostenpunkt für einen Synth (ohne Case!): weit unter 100 Euro.
Die Platinen lass ich mir in China über dirty cheap PCB`s fertigen 
(10STK 10x10cm 2-layer um 20 Euro, Versandkostenfrei), da ich seit 
meinem 8-bit Projekt keinen Bock mehr auf through-hole habe und nur noch 
SMD verwende ;)
Entwicklung wird jedoch noch etliche Monate dauern, aber im Prinzip 
funktioniert alles schon am Breadboard bzw. mit meine Proto-Modulen.
LG
Matthias

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Matthias

Mit viel "Neid" habe ich deinen Bericht gelesen ;)

Das wird mit Sicherheit ein sehr guter Synthi werden. Hab auch schon 
überlegt ob ich auch auf einen leistungsstärkeren ARM Controller setzen 
soll. Aber da fehlt mir einiges an Wissen und gute Systemtools wzB eine 
Entwicklungsumgebung. Ich programmiere meinen Synth mit ATMEL-Studio 6.2 
in C und Assembler und versuche aus dem verwendeten ATmega128 alles an 
Ressourcen herauszuholen was möglich ist.

Die Arbeitsaufteilung auf mehrere Prozessoren macht schon Sinn. So sind 
dann auch mehrere Stimmen möglich. Mein Synth hat leider nur eine Stimme 
aber dafür in Stereo. Ich verwende die zwei DAC-Ausgänge im ATmega128 
für Oszillator 1+2, 2x Analoge VCA's LM13700, 2x Analoge 12db Filter 
LM13700 (LP,HP,BP), einen Delay-Channel mit PT2399 Chip. Die 
CV-Steuerung erfolgt durch die 10 PWM-Ausgänge des ATmegas.

Die 128 festen Wellenformen (128x 256Byte) werden jetzt beim Systemstart 
von der SD Karte ans Ende des 1MByte großen SRAM-Speichers geladen. Der 
User kann dadurch eigene Wellenformen mit einem Wave-Editor erzeugen und 
diese ins SRAM laden. Der Rest steht dem Sample-File zur Verfügung.

Um das Aliasing bei den tiefen Frequenzen etwas zu minimieren mach ich 
eine Interpolation von zwei Samples. Ein Code-Beispiel aus meinem synth 
ist im Anhang gelistet. Vielleicht kannst du ja gebrauchen.

Zur Zeit arbeite ich noch viel an der Software. Habs ja nicht gelernt 
und tuh mich da halt etwas schwer. Aber wie sagt man so schön.. Mühsam 
nährt sich das Eichhörnchen :)

: Bearbeitet durch User
von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Soviel "Neid" brauchst du nicht zu haben, bin ja selbst nur ein 
"Pfuscher" und hab mir sowohl das "analoge Wissen" als auch die 
rudimentären C++ Kenntnisse in den letzten Jahren beigebracht (gut, hab 
auch schon früher am Atari 800 und dann am ST geklopft) ;)
Wegen Entwicklungsumgebung:
Verwende sowohl für den PIC32 als auch für den STM32 "Arduino Derivate" 
(wobei ich an der STM32-Arduino Portierung auch beteiligt bin). D.h. Der 
Code ist - im großen und ganzen - recht austauschbar. Vorteil dabei ist, 
dass ich sehr viel dadurch aus diversen Foren/Blogs "zusammenkopieren" 
konnte. So ist z.B. die Phasenregulierung der Oszillatioren aus einem 
ehemaligen Arduino AVR Code enstanden. Genauso habe ich etliche 
Libraries recht einfach portieren können, zB die exzellente MIDI Library 
hat auf Anhieb geklappt.
Ich selbst fand den Übergang von AVR zu ARM nicht so schwierig, hab mit 
einem Tiva-C begonnen, der ein sehr gutes Datenblatt besitzt. Nachteil 
beider "32-Bitter" die ich jetzt verwende: Beide haben keine FPU, das 
wäre für unsere Zwecke das non-plus-ultra.
Der Vorteil des V2164/SSM2164 gegenüber dem LM13x00 ist, dass der CV 
Eingang exp. ist, d.h. man erspart sich das lästige 2 Transistoren 
lin-exp-Spielchen, das noch dazu temperaturunbeständig ist. D.h. man 
erspart sich bei den billigeren LM's kaum etwas. (auf Ali gibt es die 
SSM2164 um 2 Euro pro Stück - ohne Gewähr! :) )
Auslagerung auf mehrere uC's ist für mich kein Thema, bei den 
(dumping)Preisen. Blöderweise gibt es nicht "den" perfekten uC 
(Ergänzung: noch(!) nicht, es kommt im Juni der PIC32MZxxxEF raus: mind. 
200MHZ,2048kb SRAM, true random generators, 4x I2S= 8 Stimmen...) : Der 
PIC32 kann zwar I2S, dafür hat er nur 5 (oder 6?) PWM Kanäle, der STM32 
umgekehrt. Interessant wäre eine "echte" SRAM Anbindung mit eben 1MB+ 
wie bei dir, dafür fehlen mir die Kenntnisse, bzw. die Pin's. Da bleiben 
mir "nur" die 32kb SRAM im PIC und die 20kb im STM32 übrig. Ist aber 
genug für die klassische Morphing Wavetable von Waldorf: 16Bit, 64 
Wellenformen zu 128 Schritten = 16kB, da bleiben 16KB für den "Rest" im 
PIC. Genauer gesagt:
4 Stimmen zu je(!)
OSC1 (morphing Wavetable od. 1024 steps)
OSC2 (1024 steps standard Wavetable)
2-3 LFO's
2-3 ADSR's
natürlich hat jede Stimme die gleiche Wavetable Konfiguration, geht sich 
anders auch nicht aus.

von Rolf D. (rolfdegen)


Lesenswert?

Ich bin mal gespannt auf die ersten Klänge aus deinem Synth :)

Zur Zeit arbeite ich noch an der Mudlationmatrix. Am 23.April gehts dann 
mit dem Prototype ins TV Studio. Der CC2 hat mich eingeladen um den 
Synth vorzustellen. Hoffe es funktioniert alles bis dahin. Ein Gehäuse 
muss ich auch noch machen. Halt noch viel Arbeit..

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Der "DE:GENERATOR" ist ready for sounding..

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Der Studiobesuch beim CC2

Hallo liebe Freunde..
Der Studiobesuch beim CC2 war sehr interessant und eine große Freude für 
mich. Endlich konnte ich den "Urgesteinen" des damaligen WDR Computer 
Clubs Wolfgang Back und Wolfgang Rudolph leibhaftig die Hände schütteln. 
Der Heinz war dieses mal leider nicht dabei.

Es ist sehr interessant zu beobachten mit welcher Routine und 
Gelassenheit und vor allem mit wieviel Humor die beiden Wolfgänge eine 
TV Sendung machen. Und ich live dabei und mittendrin.. wow.

Von Lampenfieber vor den drei Kameras war bei mir keine Spur mehr als 
ich mit Wolfgang Rudolph ins Gespräch kam und von den Anfängen meiner 
Entwicklung am Synthesizer erzählte. Techniker unter sich.. da sind 15 
Minuten nix. Die Minuten flogen im Eiltempo an mir vorbei und ich hätte 
noch Stunden vom Synthesizer, Elektronischer Musik u.a. Dingen erzählen 
können. Aber da war noch Stefan Krister und der wollte etwas über den 3D 
Druck erzählen. Dem wollte ich nicht die Show stehlen smile

Hab mal ein paar Fotos aus dem Studio von NRW TV geschossen um zu 
"beweisen" das ich wirklich da war Augenzwinkern

Fotos CC2 Studiobesuch

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo..

Diese Woche arbeite ich noch einmal am Frontpannel. Wegen der ca. 20cm 
langen 8Bit Datenleitungen vom Prozessorport zum Display kommt es 
gelegentlich zu Störungen auf dem Display. Die Daten werden mit einer 
Geschwindigkeit von 16Mhz übertragen. Ich habe mir überlegt für die 
Display-Ansteuerung einen eignen ATmega328P Prozessor auf dem 
Frontpannel einzusetzen. Dadurch werden die Datenleitung zum Display 
sehr kurz und Störungen bei der Datenübertragung vermieden. Die 
Datenübertragung vom ATxmega128 Hauptprozessor zum Display-Prozessor 
erfolgt dann über den schnellen I2C Bus der Prozessoren.

Noch ein Vorteil hätte diese Änderung. Der Hauptprozessor würde mit der 
aufwendigen Berechnung für Lienen, Rechtecken und Textzeichen auf dem 
Display entlastet werden. Das würden dann der Display-Prozessor 
übernehmen. Die Abfrage der Taster und Encoder könnte der Display 
Prozessor ebenfalls übernehmen.

Bild: Altes Prozessorboard und Frantpannel

So.. dann mal ran an die Arbeit. Bauteile sind schon bestellt smile

Gruß Rolf

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

für solche Dinge (Auslagerung von Displays...) eignen sich hervorragend 
die kleinen "Arduino mini clones" auf ebay und aliexpress. Upload mit 
FTDI oder anderem USB-serial converter. Kostenpunkt: ca. 2 Euro Stück 
(Versandkostenfrei).
(Sorry, kann keinen Link posten, da alles was ich versuche mit der 
Meldung: Der Beitrag scheint Spam zu enthalten: nicht abzuschicken ist 
((A)ffilate, (t)inyurl). Toll gelöst, admins, Hut ab!)
Letzter Versuch: (Klammern entfernen)
http://(t)iny(url).com/mhd9449

Hab auch erfolgreich die "Kleinen" mit nur 3.3V "befeuert" (dürfte mit 
16MHZ kein Problem sein, wenn auch außerhalb der Specs) -> spart bei 
TFT's die 5V/3.3V Konvertierung.
Obwohl ich gerade bei Displayansteuerung die maple mini clones (ab 3.5 
STK) empfehlen würde, aber da müsstest du dich in ARM/STM32 einarbeiten.

Liebe Grüße
Matthias

von Rolf D. (rolfdegen)


Lesenswert?

Hallo zusammen !

Auf Youtube sind die zwei TV-Folgen über meinen Synthesizer im CC2 
Channel zu sehen.

1.Folge: https://www.youtube.com/watch?v=8MZyrBaEf94

2.Folge: https://www.youtube.com/watch?v=tl1SMwQXm7o

Viel Spaß beim ansehen. :)

Gruß Rolf

von Alex W. (a20q90)


Lesenswert?

Hallo Rolf,

meine Hochachtung! Tolles Projekt!

von Rolf D. (rolfdegen)


Lesenswert?

Danke. Noch viel Arbeit bis zum Bausatz..

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!

Es gibt wieder viel neues zu berichten. In den vergangenen Wochen habe 
ich an der Modulationsmatrix gearbeitet und den Envelope Generator 
(ADSR) verbessert.

Bild 1: Modulationsmatrix

Mögliche Modulationsquellen
LFO1
LFO2
ENV1
ENV2
Velocity
Mod.Wheel
Pitch Wheel
Randomgenerator
Noise
Sequenzer

Mögliche Modulationsziele
Osc1
Osc2
Osc1+Osc2
VCA-Gain
VCF Cutoff
Resonance
Osc-Pan
VCA-Pan
Fx-Pan
LFO1
LFO2

Die Menü Page für die Modulationsmatrix ist bereits fertig (siehe Bild). 
Über den Cursor kann einer von 20 sogenannten Modulations-Slots 
ausgewählt werden. Über die Regler "Source" und "Destination" werden die 
Modulationsquelle und das Ziel bestimmt. Mit "Amount" wird die 
Modulationsstärke eingestellt.

Jetzt muss ich das Ganze "nur noch" in eine kleine Formel packen und 
berechnen. Hilfe ich brauch einen Mathematiker  holy-willi




Envelope Generator
Die alten Routinen für den Envelope Generator benötigten viel Rechenzeit 
durch Divisionen und hatten Rundungsfehler. Angeregt durch den Envelope 
Generator im Shruthi Synthesizer und die großartige Unterstützung von 
Oliver aus dem Mutable Forum habe ich den Quellcode für meinen 
Synthesizer angepasst. Dieser besteht im wesentlichen aus einem 16Bit 
Counter und einer kleinen Tabelle um die Lineare Kurvenform in eine 
Exponentiale Kurve zu konvertieren. Die "wav_res_env_expo" Tabelle kann 
auch gegen eine andere Kurvenform ausgetauscht werden. Dadurch ergeben 
sich sehr interessante Envelope Verläufe. Ferner sind auch mehr als nur 
vier Envelope-Phasen (ADSR) möglich.

Mutabel Instrument Forum: 
http://mutable-instruments.net/forum/discussion/2504/shruthi-synthesizer-and-my-wave-1/p16

C-Code: Envelope Generator (ADSR)
1
//----------------------------------------------------------------
2
// Variable
3
//----------------------------------------------------------------
4
5
uint16_t phase_;
6
uint16_t phase_increment;
7
uint16_t ramp_start_;
8
uint16_t ramp_end_;
9
uint8_t  ramp_a_;
10
uint8_t  ramp_b_;
11
uint16_t value_;
12
13
14
// init envelope
15
    adsr1_phase = ATTACK;
16
    adsr2_phase = ATTACK;
17
    phase_ = 0;
18
19
//-------------------------------------------------------------------------
20
// Envelope function
21
//-------------------------------------------------------------------------
22
void envelope(void)
23
{
24
  // increment 16Bit env_ramp
25
  phase_ += phase_increment;
26
27
  // check end of attack phase
28
  if (phase_ < phase_increment)
29
  {
30
    // set next envelope phase
31
    adsr1_phase ++;
32
    phase_ = 0;
33
  }
34
  else
35
  {
36
    // interpolate 8Bit env_expo table with 16Bit phase_
37
    uint8_t step = InterpolateSample(wav_res_env_expo, phase_);
38
    // calc 16Bit envelope value
39
    uint16_t ramp_expo =  U8MixU16(ramp_a_, ramp_b_, step);
40
    value_ = ramp_start_ + ((uint32_t)(ramp_end_ - ramp_start_) * ramp_expo >> 16);
41
  }
42
}
43
44
//-------------------------------------------------------------------------
45
// Envelope Phase
46
//-------------------------------------------------------------------------
47
void env_routine(void)
48
{  
49
  // Midi Sync ----------------------------------------------------------
50
  if (midi_sync_flag == 1)
51
  {
52
    midi_sync_flag = 0;
53
    midi_gate_flag = 1;
54
    
55
    // init envelope
56
    adsr1_phase = ATTACK;
57
    adsr2_phase = ATTACK;
58
    phase_ = 0;
59
    
60
    // ReTrigger Osc
61
    if (wavebank1 > 0 && Osc1_ReTrig == 1)
62
    {
63
      phaccu1 = 0;
64
      phaccu2 = 0;
65
    }
66
    
67
    // set Note Frequency
68
    frequency_tune();          // set note-frequency to osc1+2
69
    loop_end_flag1 = 0;
70
    loop_end_flag2 = 0;
71
    
72
    // LFO Trigger
73
    lfo1_run = 1;
74
    if (lfo1_trig == 1)
75
    {
76
      lfo1_phaccu = 0;
77
    }
78
    lfo2_run = 1;
79
    if (lfo2_trig == 1)
80
    {
81
      lfo2_phaccu = 0;
82
    }
83
  }
84
  
85
  // Env 1 (VCA) --------------------------------------------------------
86
  if (adsr1_phase == ATTACK)
87
  {
88
    // load 7Bit attack_value1 from encoder (0-127) and convert to 16Bit phase_increment
89
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[attack_value1]));
90
    ramp_start_ = 0;
91
    ramp_end_ = 65535;
92
    ramp_a_ = 0;
93
    ramp_b_ = 255;
94
    
95
    envelope();
96
    adsr1_out = value_;
97
    release_level = value_;
98
  }
99
  else if (adsr1_phase == DECAY)
100
  {
101
    // load 7Bit decay_value1 from encoder (0-127) and convert to 16Bit phase_increment
102
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[decay_value1]));
103
    
104
    // load 7Bit sustain level from encoder (0-127) and convert to 16Bit phase_increment
105
    ramp_start_ = pgm_read_word (&(sustain_rates[sustain_value1]));
106
    ramp_end_ = 65535;
107
    ramp_a_ = 255;
108
    ramp_b_ = 0;
109
    
110
    envelope();
111
    adsr1_out = value_;
112
    release_level = value_;
113
  }
114
  
115
  else if (adsr1_phase == RELEASE)
116
  {
117
    // load 7Bit decay_value1 from encoder (0-127) and convert to 16Bit phase_increment
118
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[relaese_value1]));
119
    ramp_start_ = 0;
120
    ramp_end_ = release_level;
121
    ramp_a_ = 255;
122
    ramp_b_ = 0;
123
    
124
    envelope();
125
    adsr1_out = value_;
126
  }
127
  
128
  if (midi_gate_flag == 0)
129
  {
130
    if (adsr1_phase < 3)
131
    {
132
      adsr1_phase = RELEASE;
133
      phase_ = 0;
134
    }
135
  }
136
  
137
  // Env2 (VCF) ---------------------------------------------------------
138
  
139
//---------------------------------------------------------------------------
140
// inline function and tables
141
//---------------------------------------------------------------------------
142
143
static inline uint8_t InterpolateSample(
144
  //const uint8_t* table, uint16_t phase) {
145
  const uint8_t table[], uint16_t phase) {
146
  uint8_t result;
147
  uint8_t work;
148
  asm(
149
  "movw r30, %A2"           "\n\t"  // copy base address to r30:r31
150
  "add r30, %B3"            "\n\t"  // increment table address by phaseH
151
  "adc r31, r1"             "\n\t"  // just carry
152
  "mov %1, %A3"             "\n\t"  // move phaseL to working register
153
  "lpm %0, z+"              "\n\t"  // load sample[n]
154
  "lpm r1, z+"              "\n\t"  // load sample[n+1]
155
  "mul %1, r1"              "\n\t"  // multiply second sample by phaseL
156
  "movw r30, r0"            "\n\t"  // result to accumulator
157
  "com %1"                  "\n\t"  // 255 - phaseL -> phaseL
158
  "mul %1, %0"              "\n\t"  // multiply first sample by phaseL
159
  "add r30, r0"             "\n\t"  // accumulate L
160
  "adc r31, r1"             "\n\t"  // accumulate H
161
  "eor r1, r1"              "\n\t"  // reset r1 after multiplication
162
  "mov %0, r31"             "\n\t"  // use sum H as output
163
  : "=r" (result), "=r" (work)
164
  : "r" (table), "r" (phase)
165
  : "r30", "r31"
166
  );
167
  return result;
168
}
169
170
static inline uint16_t U8MixU16(uint8_t a, uint8_t b, uint8_t balance) {
171
  uint16_t result;
172
  asm(
173
  "mul %3, %2"      "\n\t"  // b * balance
174
  "movw %A0, r0"    "\n\t"  // to sum
175
  "com %2"          "\n\t"  // 255 - balance
176
  "mul %1, %2"      "\n\t"  // a * (255 - balance)
177
  "com %2"          "\n\t"  // reset balance to its previous value
178
  "add %A0, r0"     "\n\t"  // add to sum L
179
  "adc %B0, r1"     "\n\t"  // add to sum H
180
  "eor r1, r1"      "\n\t"  // reset r1 after multiplication
181
  : "&=r" (result)
182
  : "a" (a), "a" (balance), "a" (b)
183
  );
184
  return result;
185
}
186
187
188
//-------------------------------------------------------------------------
189
// Attack increments 16Bit
190
//-------------------------------------------------------------------------
191
const uint16_t lut_res_env_portamento_increments[] PROGMEM = {
192
  
193
  65535,  18904,  16416,  14304,  12504,  10968,   9647,   8509,
194
  7525,   6672,   5931,   5285,   4719,   4224,   3788,   3405,
195
  3066,   2766,   2500,   2264,   2053,   1865,   1697,   1546,
196
  1411,   1290,   1180,   1082,    993,    912,    839,    773,
197
  713,    658,    608,    562,    521,    483,    448,    416,
198
  387,    360,    335,    313,    292,    272,    255,    238,
199
  223,    209,    196,    184,    172,    162,    152,    143,
200
  135,    127,    119,    113,    106,    100,     95,     90,
201
  85,     80,     76,     72,     68,     64,     61,     58,
202
  55,     52,     50,     47,     45,     43,     41,     39,
203
  37,     35,     33,     32,     30,     29,     28,     26,
204
  25,     24,     23,     22,     21,     20,     19,     18,
205
  18,     17,     16,     16,     15,     14,     14,     13,
206
  13,     12,     12,     11,     11,     10,     10,      9,
207
  9,      9,      8,      7,      7,      6,      6,      5,
208
  5,      4,      4,      3,      3,      2,      2,      1  
209
};
210
211
const uint8_t wav_res_env_expo[] PROGMEM = {
212
  0,      4,      9,     14,     19,     23,     28,     32,
213
  37,     41,     45,     49,     53,     57,     61,     65,
214
  68,     72,     76,     79,     83,     86,     89,     92,
215
  96,     99,    102,    105,    108,    111,    113,    116,
216
  119,    121,    124,    127,    129,    132,    134,    136,
217
  139,    141,    143,    145,    148,    150,    152,    154,
218
  156,    158,    160,    161,    163,    165,    167,    169,
219
  170,    172,    174,    175,    177,    178,    180,    181,
220
  183,    184,    186,    187,    188,    190,    191,    192,
221
  193,    195,    196,    197,    198,    199,    200,    201,
222
  202,    203,    205,    206,    206,    207,    208,    209,
223
  210,    211,    212,    213,    214,    215,    215,    216,
224
  217,    218,    218,    219,    220,    221,    221,    222,
225
  223,    223,    224,    225,    225,    226,    226,    227,
226
  227,    228,    229,    229,    230,    230,    231,    231,
227
  232,    232,    233,    233,    233,    234,    234,    235,
228
  235,    236,    236,    236,    237,    237,    238,    238,
229
  238,    239,    239,    239,    240,    240,    240,    241,
230
  241,    241,    241,    242,    242,    242,    243,    243,
231
  243,    243,    244,    244,    244,    244,    245,    245,
232
  245,    245,    245,    246,    246,    246,    246,    246,
233
  247,    247,    247,    247,    247,    248,    248,    248,
234
  248,    248,    248,    248,    249,    249,    249,    249,
235
  249,    249,    249,    250,    250,    250,    250,    250,
236
  250,    250,    250,    251,    251,    251,    251,    251,
237
  251,    251,    251,    251,    251,    252,    252,    252,
238
  252,    252,    252,    252,    252,    252,    252,    252,
239
  252,    253,    253,    253,    253,    253,    253,    253,
240
  253,    253,    253,    253,    253,    253,    253,    253,
241
  253,    254,    254,    254,    254,    254,    254,    254,
242
  254,    254,    254,    254,    254,    254,    254,    254,
243
  254,    254,    254,    254,    254,    254,    254,    255,
244
  255
245
};
246
247
//-------------------------------------------------------------------------
248
// Sustain level 16Bit
249
//-------------------------------------------------------------------------
250
const uint16_t sustain_level[] PROGMEM = {
251
      1,    11,    33,    65,   106,   157,   218,   287,
252
      366,   454,   550,   655,   769,   891,  1022,  1162,
253
      1310,  1466,  1630,  1803,  1984,  2173,  2370,  2576,
254
      2789,  3011,  3240,  3477,  3723,  3976,  4237,  4506,
255
      4783,  5068,  5360,  5660,  5968,  6284,  6607,  6938,
256
      7277,  7623,  7977,  8338,  8707,  9084,  9468,  9860,
257
      10259, 10666, 11080, 11502, 11931, 12367, 12811, 13263,
258
      13722, 14188, 14661, 15142, 15630, 16126, 16629, 17139,
259
      17657, 18181, 18713, 19253, 19799, 20353, 20914, 21483,
260
      22058, 22641, 23231, 23828, 24432, 25043, 25662, 26288,
261
      26920, 27560, 28207, 28862, 29523, 30191, 30867, 31549,
262
      32239, 32935, 33639, 34350, 35068, 35792, 36524, 37263,
263
      38009, 38762, 39522, 40288, 41062, 41843, 42631, 43425,
264
      44227, 45036, 45851, 46674, 47503, 48339, 49182, 50033,
265
      50889, 51753, 52624, 53502, 54386, 55278, 56176, 57081,
266
      57993, 58912, 59837, 60770, 61709, 62655, 63608, 65535
267
};


Link: https://www.youtube.com/watch?v=2nDW_XA8oTU


Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen und guten Abend smile

Ich glaube das die Sounds vom DE:Generator sehr interessant sind ich 
mich nicht verstecken muss im Vergleich zu anderen Synthis, obwohl meine 
Kiste nur 8Bit macht.

Testweise habe ich heute einen 580KByte großen Chor-Sample geladen und 
über den eigebauten Stepsequenzer abgespielt.
Im normalen Fall wird der Wellenform Oszillator bei jeder Tastenanschlag 
retriggert und beginnt das Abspielen des Samples von vorne (Sound 
Beispiel 1.Teil). Ich habe diese Funktion über einen Switch (ReTrig) 
abschaltbar gemacht, so dass der Wellenform Oscillator im Loop läuft und 
bei jedem Tastenanschlag ein anderer Wellformabschnitt vom Sample 
gespielt wird (Sound Beispiel 2.Teil). Der Sound klingt dadurch 
abwechslungsreicher und weniger statisch. Das funktioniert allerdings 
nur bei Flächensounds sehr gut.

Sound Beispiel
1.Teil Note trigger Waveform Oszillator
2.Teil: free rum Waveform Oszillator

Soundcloud: https://soundcloud.com/rolfdegen/osc-re-trigger

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Mit Neo und Morpheus war ich heute in der Matrix und tauche gleich 
wieder ein ebueb

Kleiner Scherz. Wer den Film Matrix nicht kennt hier zur Film Info: 
http://de.matrix.wikia.com/wiki/Matrix_Wiki

Diese Woche arbeite ich wieder an der Modulationsmatrix. Keine leichte 
Sache unglücklich Aber Dank einiger Tips aus dem Mutable Forum will ich 
das mit Hilfe eines Zweidimensionale Daten Arrays versuchen umzusetzen.

Zweidimensionale Daten Arrays: 
http://www.c-howto.de/tutorial-arrays-felder-zweidimensional.html

Bild1: Modulationsmatrix im DE:Generator

Wie man auf dem Bild erkennen kann, besteht das Daten Array aus 6 Reihen 
(Slots) mit jeweils 3 Datenfeldern (Source, Destination, Amount).

Der Zugriff auf ein Datenelement in der Modulationsmatrix erfolgt mit 
einem Zeilen- und Spaltenindex. Unter C sieht das zB dann so aus:
1
amount = (slot_array[2][2]); // load lfo1 amount

Die Berechnung eines Modulationsknoten besteht im wesentlichen aus der 
Multiplikation von Source- und Destination-Werten. Um die Berechnungen 
schnell auszuführen, habe ich Inline-Assembler Routinen verwendet. Mit 
Inline-Assembler kann man kleine optimierte Assembler Routinen direkt in 
den C-Code einbetten.
1
// LFO1 => VCF Modulation  --------------------------------------------
2
temp_cv = U16ShiftRight4(Env2.value_); // convert 16Bit Envelope to 12Bit PWM-Control for Filter-Cutoff 
3
amount2 = (slot_array[2][2]) << 1; // load lfo1 amount *2
4
modul2 = lfo1_out * amount2 >> 8;
5
temp_cv = U16U8MulShift8(temp_cv,(255-modul2));
6
7
// set Filter Cutoff --------------------
8
CV_VCF_Cha1 = temp_cv;
9
CV_VCF_Cha2 = temp_cv;
10
11
12
13
// Inline-Assembler Routinen (avr-gcc) ------------------
14
static inline uint16_t U16ShiftRight4(uint16_t a) {
15
    uint16_t result;
16
    asm(
17
    "movw %A0, %A1" "\n\t"
18
    "lsr %B0"      "\n\t"
19
    "ror %A0"      "\n\t"
20
    "lsr %B0"      "\n\t"
21
    "ror %A0"      "\n\t"
22
    "lsr %B0"      "\n\t"
23
    "ror %A0"      "\n\t"
24
    "lsr %B0"      "\n\t"
25
    "ror %A0"      "\n\t"
26
    : "=r" (result)
27
    : "a" (a)
28
    );
29
    return result;
30
}
31
32
static inline uint16_t U16U8MulShift8(uint16_t a, uint8_t b)
33
{
34
    uint16_t result;
35
    asm(
36
    "eor %B0, %B0"    "\n\t"
37
    "mul %A1, %A2"    "\n\t"
38
    "mov %A0, r1"     "\n\t"
39
    "mul %B1, %A2"  "\n\t"
40
    "add %A0, r0"     "\n\t"
41
    "adc %B0, r1"     "\n\t"
42
    "eor r1, r1"      "\n\t"
43
    : "=&r" (result)
44
    : "a" (a), "a" (b)
45
    );
46
    return result;
47
}

Die Schwierigkeit in der Programmierung besteht jetzt darin, die 
einzelnen Modulationsknoten in der Matrix zusammen zu führen. Daran 
arbeite ich jetzt...

Bis bald und eine schöne Wochen wünscht euch der Rolf aus Wuppertal :)

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo again..

Da ich zur Zeit an der Modulationsmatrix arbeite, habe ich spaßeshalber 
mal einen Filter Sweep Test mit dem Shruthi Synthesizer (mit Polivoks 
Filter) und dem DE:Generator gemacht.

Filter Sweep Test auf Youtube: 
https://www.youtube.com/watch?v=2RPmd5Tvcns

Deutlich sind die Abstufungen im Filter Sweep vom Shruthi Synthesizer zu 
hören. Das kommt durch die 8Bit Auflösung der Filter Steuerspannung. Im 
DE:Generator hat die Steuerspannung eine 12Bit Auflösung. Abstufungen 
sind kaum zu hören.

In der Modulationsmatrix kann bereits der VCA und VCF mit den LFO's und 
Envelope Generatoren moduliert werden. Der Rest folgt..

Falls sich jemand vorab für den C Code interessiert. Den gibts im Anhang 
und ohne Gewähr  Augenzwinkern

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen zusammen..

Es gibt wieder viel Neues zu berichten u.a.

Ich habe die Eingangsschaltung für den Analog Digital Wandler etwas 
verbessert. Als erstes habe ich die interne Referenzspannungsquelle im 
Xmega durch einen LM336-Z2.5 ersetzt. Der LM336 erzeugt eine positive 
Referenzspannung von 2.5 Volt. Über den Port-Eingang PA0 wird die 
Referenzspannung dem Xmega zugeführt. Da ich den ADC-Eingang im 
sogenannten Single-ended Mode betreibe, benötigt dieser am Eingang eine 
positive Offset Spannung von 1.25 Volt die ich über den Spannungsteiler 
aus R100, R101 und R102 einstelle. Die Kondensatoren C101, C104 und C105 
verringern hochfrequente Störanteile. Der Widerstand R103 dient als 
Strombegrenzer für den ADC-Eingang bei zu hohen Eingangsspannungen die 
bei Übersteuerung am Audio-Eingang auftreten können. Interne 
Schutzdioden im ADC-Eingang des Xmega schützen zusätzlich. Die 
Störgeräusche sind jetzt minimal. Der ADC im Xmega arbeitet mit einer 
Samplerate von 40KHz. Ein steilflankiger Tiefpassfilter ist dadurch 
nicht mehr notwendig. Für einen 8Bit Sampler ist der Klang erstaunlich 
gut. Hab mal ein Hörbeispiel auf Soundcloud hochgeladen.

Soundcloud Sample Demo: https://soundcloud.com/rolfdegen/sample-demo-02

Bild: ADC-Input am Xmega

Mehr Infos über den DE:generator hier: 
http://www.cczwei-forum.de/cc2/thread.php?threadid=5878&threadview=0&hilight=&hilightuser=0&page=24

Gruß Rolf

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Mit welcher Spannung betreibst Du den OpAmp? Da der Schaltplan ohne die 
Versorgungspins abgebildet ist, kann man hier nur raten?

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Knut

Die Versorgungsspannung für den analogen Schaltungsteil im Synthesizer 
ist +8V -8V

Bild: Stromversorgung


Initialisierung des ADC im Xmega
1
// 8Bit / unsigned mode / ext.VRef 2.5V / Prescaler 256 / singleended / input PortA Pin3
2
  ADCA.CTRLB = ADC_RESOLUTION_8BIT_gc;
3
  ADCA.REFCTRL = ADC_REFSEL_AREFA_gc;    
4
  ADCA.PRESCALER = ADC_PRESCALER_DIV256_gc;
5
  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
6
  ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc;
7
  ADCA.INTFLAGS = 0x03;   // set intflags
8
  ADCA.CTRLA = ADC_ENABLE_bm;    // ADC enabled

Gruß Rolf

: Bearbeitet durch User
von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Lieber Rolf, wirklich bemerkenswert, was du mit dem AVR anstellst, Hut 
ab!

Bzgl. Shruti Filter: Soweit ich mich erinnern kann, hat der ja einen 
extra expo Schaltkreis für die Cutoff, eigenartig, dass hier noch die 
Steps zu hören sind und du mit den 12 Bits klar im Vorteil bist. 
Vielleicht tritt dieses Phänomen nur mit dem Polivoks Board auf?
Das 8-Bit Sample ist auch ein Traum, kaum zu glauben wenn man es nicht 
weiß!

Mutable Instruments ist eine meiner Hauptinspirationsquellen, insb. was 
Filterdesign anbelangt: Habe mir z.B. für mein 4-LP dual Filter 
(10x10cm) so ziemlich viel vom Ambika Synth abgeschaut 
(http://mutable-instruments.net/ambika/build/voicecards ---> 4-pole 
voicecard), das ganze in KiCad "nachgemalt", erweitert (incl. PT8211 
16-bit I2S DAC) und bei dirtypcbs in Auftrag gegeben, bin schon 
gespannt, ob meine Platine dann funktionieren wird. Für 25 USD für 10STK 
Platinen echt ein Schnäppchen (wenn man 6-8 Wochen Zeit hat...) Habe die 
Platine auch öffentlich gestellt, würde ich aber noch nicht bestellen, 
da ich sie erst testen muss:
http://dirtypcbs.com/view.php?share=10898&accesskey=96ae3ff6362e41d344ac5ff96a73fc62

Ich bin übrigens gespannt, ob du jemals auf ARM umsteigen wirst oder 
wäre das zuwenig Herausforderung für dich? :)

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ahh, OK. Sonst hätte ich einen anderen OV als den guten alten 072 
vorgeschlagen, so Rail2Rail Zeugs. Ich dachte, der Synth wäre mobil, 
also mit Akku/Batterien... Allerdings hätte ich den Signed mode des ADC 
verwendet, da unsigned single ended meist etwas bugbehaftet ist. Es sei 
denn, Du rechnest intern auch ohne Vorzeichen.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

@Matthias
Danke. Für die Filter und VCA Ansteuerung verwende ich eine 12Bit PWM im 
Xmega. Der Shruthi macht das mit 8Bit. Deshalb die hörbaren Abstufungen 
im Shruthi.
Ein guter Freund (Andre von der Firma TubeOhm) hat mir beim 
Filterdesigne sehr geholfen. Für die 1.Version des Filters im 
"DE:generators" haben wir uns für eine 12dB Variante mit OTAS vom Typ 
LM13700 entschieden. Die Stereo Filterplatine wird aber austauschbar 
sein, so das jeder auf seinen Geschmack kommen dürfte. Düfte für dich 
dann ganz interessant sein.

ARM Prozessoren sind sehr preisgünstig, schnell und haben 32 Bit. Auf 
jeden Fall werde ich bei den nächsten Projekten mal schaun ob ich die 
benutze. Ein 16Bit DIY Sampler wäre etwas tolles. Mir fehlt halt noch 
der Überblick auch was die Entwicklungstools und Programmierung angeht.


@Knut
Batterie Betrieb ist kaum machbar, weil der Stromverbrauch zu hoch ist. 
Ich habe intern 4 Spannungen mit +3.3V , +5V, +8V , -8V und eine 
Leistungsaufnahme von ca. 6 Watt.
Den ADC betreibe ich im Single-ended Mode ohne Vorzeichen. Der Sample 
wird in 8Bit ohne Vorzeichen im 1MByte Ram mit einer Abtastrate von 
40KHz gespeichert.
Jeder DCO kann auf diesen Sample getrennt zugreifen. Dadurch sind schöne 
Effekte wzB Phasing o.ä. möglich.

Zur Zeit programmiere ich eine Aussteuerungsanzeige mit Speicherung des 
letzen Spitzenwertes, für die Aufnahme von Samples (Bild). Ist aber noch 
nicht ganz fertig.

Gruß Rolf

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Falls du Interesse an ARM's in Zukunft hast, kontaktiere mich bitte, hab 
mich da schon reingearbeitet (speziell punkto Audio).
Ich bin selbst am Projekt stm32duino (STM32F103 bzw. auch in Zukunft die 
STm32F4 bis F7) beteiligt. Programmierung geht einfach über die Arduino 
IDE (mit allen Macken und Vorteilen) aber low level ist ebenso möglich. 
Developer Boards mit I2s (STM32F103RET bzw. VET haben 72Mhz, 256-512Kb 
Flash bzw. 48-64kb RAM) gibt es auf aliexpress für unter 10 Euro (zahlte 
für ein gutes RET board gerade mal 6 Euro!) Für alle STM32F103 gibt es 
eigene Bootloader, so Code Upload ist über die USB-Schnittstelle der 
Boards möglich. Den Bootloader bekommt man mit einem einfachen 
USB-Serial Adapter gebrannt bzw. mit einem ST-Link Adapter (~3 Euro)

Soviel habe ich schon geschafft (bin selbst erst recht am Anfang):
"echtes" MIDI-USB: d.h. dev board wird über USB als Midi Device erkannt. 
(Übertragung inkl. Midi Clock,Sysex, etc.. funktioniert!)
Ansteuerung eines spottbilligen PT8211 16-bit DAC's über I2s mittels 
DMA: Da die größeren STM32's über drei SPI besitzen, wo 2 davon als I2s 
verwendet werden können sind praktisch insg. 4 individuelle Outputs 
möglich!
Hab mir sogar einen Code geschrieben, wo ich "on the fly" Waldorf 
Blofeld Wavetable (auch die Multiwavetables!) direkt über MIDI in den 
STM32 bekomme.
So kann folgendes mit nur einem STM32 gemacht werden (ist mein Projekt):
4 individuelle Outputs (jeweils 2 Multiwavetable Oszillatoren pro Stimme 
inkl. FM/AM...)
massenhaft LFO's, ADSR's
wenn beide I2s Schnittstellen für DAC's verwendet werden, bleibt noch 
SPI1 übrig: Ansteuerung eines TFT's (SPI ILI9341 TFT Modul (weit unter 
10 Euro) mit DMA support in unserer Library), SPI-Flash (die Winbond mit 
2-4MB), SPI octal(!) DAC's wie LTC1665 (8-bit...) oder LTC1660 (10-bit)
Encoders, Buttons, Potis
USB-Midi
Serial-Midi
massenhaft Timer und PWM's

Nachteil der STM32F103 Serie: Keine FPU (ist ein Cortex M3), d.h. fix 
point maths notwendig (wie beim AVR ;) )
Falls es dich interessiert, schau dir mal unser Forum an: 
http://www.stm32duino.com/index.php

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Danke für die vielen Infos. Super :)

von Rolf D. (rolfdegen)


Lesenswert?

So.. Aussteuerungsanzeige fast fertig. Fehlt noch das Abspeichern des 
Spitzenwertes für 1-2 Sekunden :)

Youtube: https://www.youtube.com/watch?v=dQZtQsm15a0&feature=youtu.be

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Freunde der Musik..

Für die Sample Aufnahme habe ich einige neue Funktionen integriert u.a 
auch Threshold. Die Aufnahme kann durch einen Tastendruck am Synthesizer 
sowie durch ein Midi Note ausgelöst werden. Mit Threshold startet die 
Aufnahme ab einem bestimmten Signal Pegel (siehe Video).

Bild: Sample Aufnahmefunktion

Youtube: https://www.youtube.com/watch?v=2Vn8oYqZZrc

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Zur Zeit arbeite ich an der Optimierung der MiniScope Funktion in meinem 
Synth. Ziel der Optimierung ist das schnelle Zeichnen von Wellenform 
Kurven auf dem SainSmart TFT 3.2

Allerdings habe ich bei der LCD Orientierung im Landscape Mode noch ein 
kleines Problem. Bei schnellen Schreibvorgängen im Landscape Mode kommt 
es zum flackern des LCDs. Das liegt vermutlich an den vertauschten XY 
Koodinaten und dem
Überlauf der Schreibregister 0x4E und 0x4F im LCD-Controller. Die 
Störungen sind sehr deutlich im Video beim Zeichnen von nicht gefüllten 
Kreisen zu sehen.



Youtube SainSmart TFT 3.2: https://youtu.be/T4p6Wr_8Pcc

SSD1289 Lib: http://www.rinkydinkelectronics.com/library.php?id=51

Gruß Rolf

: Bearbeitet durch User
von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Kann mir kaum vorstellen, dass ein AVR einen Displaycontroller 
überfordern kann. Möglicherweise sind in der UTFT Library längere 
Waitsteps notwendig?
Meine Idee wäre wieder einmal recht unorthodox: Maple mini über China 
ordern (3.5Euro) und das komplette TFT auf den Mini auslagern. Würde den 
AVR enorm entlasten und du hättest Platz für mehr Features. Abgesehen 
geht beim STM32 + TFT die Post ab (von wegen Geschwindigkeit).
BTW: Bei meinem Synthprojekt habe ich nun komplett (aus Performance and 
Usabilitygründen) auf ein TFT verzichtet und gegen
a) ein großes 128x64 LCD und
b) gegen ein 0.96 OLED ausgetauscht
Interfacetest hier ---> 
https://www.youtube.com/watch?v=TVV4jb7tQec&feature=youtu.be

maple mini + ILI9341 (DMA mode + hardware scrolling) DEMO: 
https://www.youtube.com/watch?v=bv_LYtYQCmk
LG
Matthias

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Hi Mathias

Danke für deine Tips. Dein DIY Synth schaut recht interessant aus. Gibt 
es eventuell mehr Infos darüber.

Die Probleme mit dem Display hab ich jetzt behoben. Lag an einer 
fehlerhaften Berechnung des Window Address Area für das GDDRAM im 
Display.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Ich habe mir jetzt für ca. 9 Euro ein kleines 2.2" TFT gekauft (siehe 
Link). Das soll als Anzeige für ein kleines MiniScope im 19" Synthesizer 
Einschub dienen. Zum ersten Mal werde ich das Projekt mit einem kleinen 
ARM Prozessor entwickeln. Muss mal schaun welcher ARM Prozessor dafür 
geeignet ist.

Link: https://www.roboter-bausatz.de/29/2-2-tft-lcd-modul

Gruß Rolf

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Super, dass du die Probleme behoben hast! Ich gebe es ja ehrlich zu, 
dass ich mir nicht so ganz vorstellen kann, dass ein AVR soviel leistet, 
aber du beweist ja eindeutig das Gegenteil! (Gebe auch zu, dass du mit 
Sicherheit der bessere Programmierer bist, deswegen würde es mich ja so 
interessieren, was du mit einem STM32 anstellen könntest!)
Es gibt ein paar Infos zu meinem Synth im STM32duino Forum. Am besten 
von hinten nach vorne lesen, in der Mitte ist sehr viel Gerede bezüglich 
RTOS und DMA (eher weniger spannend). Fakt ist, dass das Projekt gerade 
ein bisschen pausiert, da ich ein neues "Spielzeug" (sprich 3d-Drucker) 
habe, mit dem ich auch ein ordentliches Case bauen will.
http://stm32duino.com/viewtopic.php?f=19&t=533&start=40

Liebe Grüße
Matthias

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Ha, da war auf einmal noch ein Beitrag und:
BINGO!
Das ist ein ILI9341 TFT, dies läuft unter SPI mit DMA Unterstützung 
hervorragend mit unserer Arduino IDE Adaption für STM32. Sogar mit einem 
kleinen Mini Clone wunderbare Leistung mit wenig Kabeln!
Hier ein Link zu einem Mini Clone (die BAITE bevorzuge ich sowieso):
5 Stück "Vorteilspackung" um fulminante 3.74 Euro pro Stück 
(Versandkostenfrei)
http://www.aliexpress.com/item/5PCS-LOT-leaflabs-Leaf-maple-mini-ARM-STM32-compatibility/1400682373.html?spm=2114.01020208.3.13.ZyJwFm&ws_ab_test=searchweb201556_2_79_78_77_91_80_61,searchweb201644_5,searchweb201560_9
Unser ganzes Forum kauft beim BAITE Aliexpress-Shop mit höchster 
Zufriedenheit!

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo Matthias..

Mich würde brennend interessieren, wie du deine Programme für den ST 
Prozessor entwickelst. Ich habe mal vor zwei Jahren mit der Coocox IDE 
etwas programmiert. Aber das wars auch schon, weil ich an meinem 
Synthesizer Projekt weiter arbeiten musste. Habe mir für das MiniScope 
Projekt auf ST Basis schon das kleine 2.2" TFT und bei Reichelt ein 
Nucleo-Entwicklerboard für die STM32 F4-Serie bestellt. Hab aber noch 
keine Ahnung, welche freie Entwicklungsumgebung ich benutzen sollte. 
Vieleicht kannst du mir ein paar Tips geben.

Gruß Rolf

: Bearbeitet durch User
von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Lieber Rolf,

du wirst lachen, ich verwende die Arduino API!
www.stm32duino.com ist die Projektseite, die (als Nachfolgeprojekt von 
Leaflabs Maple) sich die Aufgabe gestellt hat. STM32 Prozessoren mit der 
Arduino API zum Laufen zu bekommen. Ich bin seit Entstehung mit dabei 
beim Projekt und habe etliche Libraries konvertiert (bzw. das NucleoF103 
Board adaptiert).
Wirklich gut unterstützt wird z.Z. nur die Reihe STM32F103xxx (dafür die 
komplette Palette und mit allen(!) Features). F4 ist in Entwicklung, 
wird aber noch ewig dauern, da wir von leafmaple auf HAL umsteigen 
müssen (bin dabei nicht/kaum involviert, da ich kein F4 Board habe).
Witz an der Sache: Wenn du oben genannten Mini Clone bestellst, brauchst 
du sonst nichts dazu, ist alles "on board". Programmiert wird über 
Serial USB hat auch einen eigenen Bootloader (Wir haben Bootloader für 
alle STM32F103xxx MCU's) Dein Nucleo Board kannst du übrigens 
herrvorragend als ST-Link verwenden - auch für andere STM32 MCU's!

edit: Bezüglich Nucleo F4: Da gibt es doch einige Fortschritte:
http://stm32duino.com/viewforum.php?f=39&sid=a235ddc603a62e90905de2a6666bd775

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Hallo

So.. ich hab mir jetzt zwei Nucleo Kits bei Reichelt bestellt. Das 
NUCLEO F411RE mit einem STM32F411RET6 Prozessor und das NUCLEO F103RB 
mit einem STM32F103RBT6 Prozessor. Werde mit beiden Board ein wenig 
rumspielen um die ARM Prozessoren ein wenig kennen zu lernen. Bin 
gespannt..

Zum Synth Project. Zur Zeit arbeite ich an der Edit Funktion für die 
Samples. Danach folgt die komplette Midi Implementierung, so das auch 
eine CC Steuerung über Midi möglich ist.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Falls ihr euch fragt, was ich gerade mache...

Ich verbessere gerade das Datei System auf der 4GB SD Karte meines 
Synthesizers. Dazu gehört das abspeichern oder löschen von Samples und 
Presets.
Das hört sich jetzt nicht gerade kompliziert an, aber die Arbeit steckt 
mal wieder in den Details. Die Abbildung zeigt die Ordner Stuktur auf 
der SD Karte.

Auf der SD Karte gibt es drei Ordner mit der Bezeichnung PRESET, SAMPLE 
und SYSTEM. Im Ordner 'Preset' sind die gesamten Sound Parameter, 
UserWave-Table und ggf das Sample-File für den Sound abgespeichert. Der 
Ordner 'SAMPLE' beinhaltet die gesamte Sample Library. Hier kann man 
Samples laden, speichern oder löschen, ohne eine Beeinflussung auf die 
Preset Sounds. Dadurch kann man z.B. die komplette Sample Library auf 
der SD Karte ändern oder austauschen, ohne Gefahr zu gehen, dass sich 
die Preset Sounds verändern. Falls ein Preset ein Sample-File besitzt, 
wird dieses immer im Preset Ordner mit abgespeichert.
Im Ordner 'SYSTEM' befinden sich System relevante Daten wzB Bilder, 
Sequenzer-Daten, USERWAVE-Table und die aktuelle Midi CC Tabelle. Die 
USERWAVE-Table besteht aus 128 festen Wellenformen mit 256 Byte Größe 
und kann beliebig ausgetauscht werden. Damit stehen dem Benutzer 
unendlich viele Möglichkeiten der Soundgestaltung zur Verfügung.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hoh hoh hoh.. Bald ist Weihnachten und die Leute kaufen wie verrückt. 
Ich auch  großes Grinsen

Zum DE:GENERATOR:
Hab die 1.Menü Seite jetzt komplett überarbeitet. Zu jedem Sound 
Programm werden jetzt die Datei Größe und Wellenform (Sample-File oder 
Wellenform) angezeigt.
Das laden eines Sound Programms funktioniert jetzt doppelt so schnell 
wie vorher.

Damit man beim Suchen eines Sounds in anderen Sound Bänken die 
Orientierung nicht verliert, wird das aktuelle (geladene) Sound Programm 
grau markiert und unterm MiniScope nochmal angezeigt.

Bild: Menüseite 'Sound Program'

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Die Zeit rast dahin und man hat das Gefühl, nicht mehr viel Zeit zu 
haben, für die Dinge die man noch machen will. So gehts mir im Moment.

Am DE:GENERATOR gibt es einige Änderungen. Um die Bedienung zu 
vereinfachen sind jetzt 8 Taster vorhanden. Zusätzlich gibts auf dem 
Front Panel zwei Potis. Diese können für Modulationszwecke frei 
programmiert werden. Damit das Ganze noch etwas bunter wird, gibts für 
die Kontrolle der LFO's jetzt drei LED-Lampen. Geplant ist noch die 
Beleuchtung der DATA Encoder mit blauen LED's.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Ho ho ho.. Ich wünsch euch allen ein schönes und gemütliches 
Weihnachtsfest.

Ich habe testweise mal einen Encoder mit den blauen LED's bestückt. Wenn 
jetzt noch die Löcher in der Frontplatte etwas größer gemacht werden, so 
das Knopf das Loch nur knapp abdeckt, sollte etwas blaues Licht an den 
Seiten austreten. Hier mal zwei Pics..

Bild: LED Beleuchtung für Encoder

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

So.. die "Weihnachstbeleuchtung" ist jetzt komplett ;)

Bild: LED Beleuchtung der Encoder

Jetzt wird noch ein wenig an der Soundengine gearbeitet um die Bedienung 
zu verbessern.


Gruß Rolf

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?


von Rolf D. (rolfdegen)


Lesenswert?

Hallo Matthias.

Danke für den Hinweis. Der Knopf sieht interessant aus.

von Matthias D. (Firma: ESRA) (madias)


Lesenswert?

Knöpfe sind nur ein bisschen größer als die "normalen" (lt. meiner 
Schätzung sollte es bei deinem Aufbau kein Problem ergeben). Verwende 
diese selbst bei meinem Synth -> die vom ersten Link kann ich 
bedenkenlos empfehlen, wurden einzeln verpackt (bzw eingewickelt) 
verschickt und sind 1A für den Preis. Natürlich würden diese sich auch 
für einen LED Kranz eignen, aber das tu ich mir mit Lochraster sicher 
nicht an :)

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Was ich zur Zeit mache..

Ich arbeite noch ein wenig an der Loop-Funktion (siehe Bild).


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Ich hoffe Ihr seit alle gut ins neue Jahr gerutscht und habt keinen 
Kater bekommen. Wenn ich an die Bowle denke... man die war so lecker 
holy-willi

Mein Kollege Andre war in den letzten Tagen auch sehr fleißig und hat 
die ersten Platinen und Gehäuse Entwürfe gezeichnet. Wegen der besseren 
Abstimmung untereinander,
habe ich beschlossen, die ganzen Schaltpläne von Eagle nach Target 3001 
zu importieren. Andre entwirft mit Target 3001 dann die Platinen für den 
DE:GENERATOR.
Target 3001 gibts auch als Freeware von distrelec mit der Einschränkung 
auf maximal 700 Pins. Hier der Link: 
http://www.distrelec.de/de/cad-freeware/...ice_cadfreeware


1.Bild: Gehäuse Entwurf DE:GENERATOR
2.Bild: Hardwareaufbau

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Von mir gibts einen neuen Gehäuse Entwurf..

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

So ein Digi Scope ist doch eine feine Sache wie ich finde. Es hilft doch 
sehr bei der Fehlersuche  ebueb

Die Tage hatte ich ein Problem mit einem Encoder. Bei der Dateneingabe 
hatte ich öffters Zahlensprünge. Ich dachte zuerst an ein Problem in 
meiner Software, weil diese immer wieder weiterentwickelt und geändert 
wird. Aber Test brachten mich nicht weiter. Die Encoder und Tasten 
werden im DE-GENERATOR alle 500msec abgefragt. Das ist auch für eine 
schnelle Umdrehung der Encoder schnell genug. Das Problem musste also an 
der Hardware liegen. Hab dann mein Digi Scope "angeschmissen" und mal an 
die Kontakte des Encoders angeschlossen. Und siehe da.. viele nette 
Impulsefolgen und noch viel mehr. Das auf dem Bildschirm sah so gar 
nicht nach einem Gray-Code von einem Encoder aus. Die beste Software 
kann dieses Prellen nicht beseitigen.

1.Bild: Ich hab dann einen neuen Encoder eingelötet und alles 
funktioniert jetzt fehlerfrei.

2.Bild: Signalverlauf am alten Encoder. Man sieht deutlich wie die 
Signalflanken prellen

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Ich hab den externen Audio-Eingang im DE-GENERATOR etwas abgeändert. Man 
hat jetzt die Möglichkeit das Stereosignal am Eingang als Summensignal 
zu sampeln. Ferner ist das Eingangssignal auch auf die Filtereingänge 
geschalten. Für die MiniScope-Funktion wird der Stereoausgang auf den 
gleichen ADC-Eingang geschaltet. Das spart Bauteile und Platz auf der 
Platine.

Bild: Stereo Eingang im DE-Generator

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Damit das Sampeln von Audio-Signalen noch etwas störungsfreier 
funktioniert, habe ich den ADC-Eingang im Xmega Prozessor als 
Differenzial-Eingang beschaltet. Der ADC im Xmega Prozessor sampelt mit 
12Bit und einer Abtastrate von 44.1KHz. Intern wird der 12Bit Wert dann 
auf 8Bit herunter gerechnet und ins 1MByte große Sample-Ram geschrieben. 
Der Operationsverstärker IC 15c+15d erzeugen aus dem Audio-Signal ein 
Differenzsignal für den ADC-Eingang.

ATMEL Notes ADC im Xmega128A1: 
http://www.atmel.com/images/atmel-8032-using-the-atmel-avr-xmega-adc_application-note_avr1300.pdf



Bild: ADC mit Differenzial-Eingang

Initialisierung des ADC im Xmega128A1 Prozessor
1
// 12Bit / differencial mode / ext.VRef 2.5V PortA0 / Prescaler 64 / positive Input PortA3 / negative Input PortA1
2
    ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc | ADC_FREERUN_bm;
3
    ADCA.REFCTRL = ADC_REFSEL_AREFA_gc;        
4
    ADCA.PRESCALER = ADC_PRESCALER_DIV64_gc;
5
    ADCA.CH0.CTRL = ADC_CH_INPUTMODE_DIFF_gc;
6
    ADCA.CH0.MUXCTRL |= ADC_CH_MUXPOS_PIN3_gc | ADC_CH_MUXNEG_PIN1_gc;
7
    ADCA.INTFLAGS = 0x00;
8
    ADCA.CTRLA = ADC_ENABLE_bm;        // ADC enabled

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Im DE:GENERATOR habe ich für die Sample Aufnahme eine Noise Shaper 
Function integriert. Der ADC-Eingang arbeitet mit einer Auflösung von 12 
Bit. Für die weitere Bearbeitung werden die Samples im DE:GENERATOR auf 
8Bit herunter gerechnet. Beim normalen Herunterrechnen von 12 auf 8Bit 
(4* rechts Shiften) entsteht bei leisen Signalen ein sehr störendes 
pumpartiges Rauschen. Der Noise Shaper verschiebt dieses Rauschen in 
einen höheren Frequenzbereich, so dass unser Ohr das Rauschen als 
weniger störend wahrnimmt.

Programmcode
1
//*************************************************************************
2
// Test noise-sharping 12Bit 44.1KHz 
3
//*************************************************************************
4
ISR(TCC0_OVF_vect)
5
{
6
    
7
    // Noise Shaper function
8
    int16_t sample_x = ADCA_CH0RES;
9
    int16_t sample_16 = sample_x * 12;
10
    sample_16 += quant_error;
11
    if (sample_16 < -32768){sample_16 = 32768;}
12
    else if (sample_16 > 32767){sample_16 = 32767;}
13
    int8_t sample_8 = sample_16 >> 8;
14
    quant_error = sample_16 - ((int16_t)(sample_8) << 8);
15
    
16
    /* convert 12Bit into 8Bit
17
    uint16_t sample_16 = ADCA_CH0RES;
18
    uint8_t sample_8 = sample_16 >> 4;
19
    */
20
21
    // DAC out
22
    DACA.CH0DATAH = sample_8;
23
    DACB.CH0DATAH = sample_8;
24
25
}

Um das zu demonstrieren habe ich ein paar Klangbeispiele aufgenommen. 
Jeweils ohne und mit der Noise Shaper Funktion. Am deutlichsten hört man 
es bei Sound 3+4. Ohne Noise Shaper versinkt das Piano quasi im 8Bit 
Rauschen.

"Sound 1 without NS":
https://drive.google.com/file/d/0BxbpDqwYdkvER2RMM2lyRkRFWFE/view?usp=sharing
"Sound 2 with NS":
https://drive.google.com/file/d/0BxbpDqwYdkvEVFVZZDdQTDhrdlk/view?usp=sharing
"Sound 3 without NS":
https://drive.google.com/file/d/0BxbpDqwYdkvEN3ZRMVVxbWRJeWc/view?usp=sharing
"Sound 4 with NS":
https://drive.google.com/file/d/0BxbpDqwYdkvEa1pReEhOTGdIR2M/view?usp=sharing
"Sound 5 without NS":
https://drive.google.com/file/d/0BxbpDqwYdkvEREF2WkV4YWEyY00/view?usp=sharing
"Sound 6 with NS":
https://drive.google.com/file/d/0BxbpDqwYdkvEZXZwdGJTaVN4S00/view?usp=sharing

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Von Andre gibts eine nächste Beta fürs DE:GENERATOR Gehäuse

Bild Gehäuse Entwurf Beta15

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Es gab einen kleiner Fehler im Programmcode vom NoiseShaper
1
//*************************************************************************
2
// Test noise-sharping 12Bit 44.1KHz 
3
//*************************************************************************
4
ISR(TCC0_OVF_vect)
5
{
6
    
7
    // Noise Shaper function
8
    int16_t sample_x = ADCA_CH0RES;
9
    int16_t sample_16 = sample_x * 16;    // alt int16_t sample_16 = sample_x * 12;
10
    sample_16 += quant_error;
11
    if (sample_16 < -32768){sample_16 = 32768;}
12
    else if (sample_16 > 32767){sample_16 = 32767;}
13
    int8_t sample_8 = sample_16 >> 8;
14
    quant_error = sample_16 - ((int16_t)(sample_8) << 8);
15
    
16
    /* convert 12Bit into 8Bit
17
    uint16_t sample_16 = ADCA_CH0RES;
18
    uint8_t sample_8 = sample_16 >> 4;
19
    */
20
21
    // DAC out
22
    DACA.CH0DATAH = sample_8;
23
    DACB.CH0DATAH = sample_8;
24
25
}

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Der Schaltplan für das Frontpanel ist jetzt fertig. Insgesamt gibt es 
jetzt 13 Tasten, fünf Drehimpulsgeber und 3 Potis. Für die indirekte 
Beleuchtung der Drehimpulsgeber und Potis sorgen 32 LED's. Für spezielle 
Statusinformationen wzB Midi-Empfang und laufende LFO gibt es noch 
zusätzliche rote LED's. Die LED-Farbe kann aber bei der 
Bausatzbestellung selber ausgewählt werden.

Das LCD-Display wird über einen 8Bit breiten Datenbus vom Xmega 
Prozessor angesteuert. Mit dem Latch IC1a werden die oberen Adress- und 
Datenleitungen DB8-DB15 für das LCD erzeugt. Die 
LED-Hintergrundbeleuchtung liegt über R67 1.5 Ohm direkt an der 
Versorgungsspannung von +3.3 Volt.

Die Drehimpulsgeber und Tasten werden mit Hilfe eines Schieberigster 
IC3a, IC4a und IC5a über die SPI-Schnittstelle am Xmega Prozessor 
abgefragt. Über die gleiche SPI-Schnittstelle steuert das 
Schieberegister IC6a die roten Status LED's an.

Pot1+2 sind über zwei ADC-Eingänge am XMega verbunden und werden jede 
Millisekunde abgefragt. In der Modulationsmatrix kann diesen Potis ein 
oder auch mehrere Modulationsziele zugewiesen werden. Das Volum-Poti ist 
ein Stereo-Poti und steuert die Lautstärke am Audioausgang.

Bild 1: Schaltplan Frontpanel
Bild 2: Schaltplan Prozessor Board

Link Bild 1: 
https://photos.google.com/share/AF1QipOzxUJT_nnlkRyNHtbHf85fpViZE3womQwTsWFHssgqgSv8d8l3uQEc8k6EdGwLtw?key=azhUOEVrblRYVkI2dnF2M0lZWTJyOXhHX1F5Zlpn
Link Bild 2: 
https://photos.google.com/share/AF1QipOx4YGPVw4SKU2MrA6VtxQln3-C_vUnRaZQTQRoKlPJn6UWMzaTNaybrb1q-jFiBg?key=eWhkT0tGTENYdndxc3FXWjBTcFJISTIyWkM0U21n

Gruß Rolf

von Doitschlehra (Gast)


Lesenswert?

Rolf D. schrieb:
> Das LCD-Display

So so, das LCD-Display ....

.... oder auch die sogenannte "LCD-Display-Anzeige"

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

@Doitschlehra
Ja.. eigentlich müsste es LC-Display heißen. Aber die meisten Kollegen 
sagen auch LCD-Display ;)

Hallöchen..

Andre aus unserem Team hat den ersten Entwurf für die Prozessor-Platine 
gemacht. Da die Platine mit einigen SMD-Bauteile bestückt ist und wir 
den Kunden diese Lötarbeit nicht zumuten wollen, werden wir diese selber 
löten und getestet ausliefern. Der Preis steht noch nicht fest.


Bild: Prozessor Board im DE-GENERATOR

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo ihr Lieben!

Da die Entwicklung der Platinen noch etwas andauert, habe ich die Zeit 
genutzt und an der Verbesserung der Menüoberfläche gearbeitet. Damit man 
die Menüseiten besser unterscheiden kann, haben diese jetzt farbige 
Frames, die nach Funktionsgruppen sortiert sind. So haben zum Beispiel 
die Menüseiten für den Oszillator alle einen blauen Frame und die LFO's 
einen grünen Frame.

Bild 1:
Die Menüseite für den Filter wurde auch überarbeitet. Entsprechend der 
eingestellten Filterfunktion wird der Frequenzverlauf und die Resonanz 
als grafische Filterkurve dargestellt. Ein kleines Scope Fenster auf der 
rechten Seite zeigt die Wellenform des Filterausganges in Echtzeit an.

Bild 2:
Das MiniScope hat jetzt eine bessere Triggerfunktion erhalten. Der 
Triggerlevel kann jetzt auch auf negative Amplitudenwerte eingestellt 
werden. Auf der linken Seite zeigt ein kleiner gelber Pfeil auf den 
eingestellten Pegel. Wird der Triggerlevel auf 0 eingestellt, ist die 
Triggerfunktion ausgeschaltet.

Als nächstes steht die Oszillator Engine auf dem Programm. Ich will das 
Bedienkonzept etwas vereinfachen. Dadurch wird die ganze Sachen dann 
etwas überschaubarer.

Bis zum nächten Post und ein schönes Wochenende.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Andre hat das CPU-Board jetzt fertig entwickelt. Ich muss es jetzt auf 
Fehler überprüfen und wenn alles gut ist werden diese Woche die ersten 
Platinen in China bestellt. Bin gespannt..

Die zwei Pfostenleisten K3 und K4 verbinden das CPU-Board über zwei 
Flachbandkabel mit dem Bedienpanel für die LCD-Anzeige, Tasten und 
Encoder. Die restlichen Pfostenleisten sind mit dem Motherboard 
verbunden und zuständig für Stromversorgung, Audio- und Steuerleitungen. 
Die zwei 8 poligen Pfostenleisten auf der linken Seite des CPU-Boards 
sogen für einen sicheren und festen Halt der SD Karte Buchse.

Bild 1-3: DE-GENERATOR CPU-Board

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo.. ich schon wieder  Augenzwinkern

Um den DE-GENERATOR in seiner "unbegrenzten" Möglichkeit der 
Klangerzeugung noch zu steigern, können jetzt die 128 festen 
Wellenformen als Wellenform Bank von der SD Karte geladen werden. 
Insgesamt besteht dann die Möglichkeit auf 128*100 Waveforms und 128*100 
Sample-Files zu zugreifen . Eine Wellenform Bank besteht aus 128 
einzelnen 256 Byte großen Wellenformen. Diese können zB am PC mit einem 
Audioeditor (Audacity) hergestellt und auf die SD Karte kopiert werden. 
Im Oszillator Menu kann dann der Benutzer auf die verschiedenen 
Wellenform Bänke und Sample-File Bänke zugreifen. Eine Editierung der 
Wellenform Bank ist im DE-GENERATOR momentan noch nicht vorgesehen.

Mit dem Mode Schalter kann zwischen der Auswahl von Wellenform oder 
Sample-File umgeschaltet werden.

Bilder: Auswahl von Waveforms und Sample-Files

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen. Was ich zur Zeit mache.. nix  Augenzwinkern

Das war gelogen. Ich arbeite zur Zeit an ein paar Midi-Routinen für den 
DE:GENERATOR. Bei einer Routine handelt es sich um eine kleine Midi 
Noten Verwaltung (NoteStack).

Der NoteStack macht folgendes: Wenn ich eine Midi Note spiele, wird die 
Noten Nummer auf Platz 1 im NoteStack gespeichert und der Ton vom 
Synthesizer gespielt. Lasse ich die Taste wieder los, so wird die Note 
im NoteStack gelöscht und der Ton wird ausgeschaltet. Simpel..

Jetzt drücken wir aber zwei Noten. Fast passiert: Zuerst wird die 1.Note 
auf Platz 1 im NoteStack gespeichert und der Ton gespielt. Danach wird 
die 2.Note auf Platz 2 im NoteStack gespeichert und der Ton für die 
2.Note gespielt. Damit befinden sich jetzt zwei Noten im NoteStack. Die 
1.Note auf Platz 1 und die 2.Note auf Platz 2. Lasse ich jetzt die 
2.Note los, so wird im Stack die 2.Note auf Platz 2 gelöscht und der Ton 
für die 1.Note gespielt.

Änliches passiert wenn die 1.Note losgelassen wird und die 2.Note noch 
gespielt wird. Dadurch wird dann die 1.Note auf Platz 1 im NoteStack 
gelöscht und die 2.Note auf Platz 1 verschoben. Der Ton für die 2.Note 
wird ohne Unterbrechung weiter gespielt. Insgesamt können 16 Noten im 
NoteStack verwaltet werden.


Bild: NoteStack Schema

C-Code Beispiel
1
uint8_t NoteStack_pool[10];
2
uint8_t NoteStack_ptr = 0;
3
uint8_t NoteStack_size = 10;
4
5
//-------------------------------------------------------------------------
6
// NoteOn
7
//-------------------------------------------------------------------------
8
void midi_NoteOn(void)
9
{
10
    uint8_t midi_note_temp = midi_data[0];                        // load midi_note
11
    
12
        if (NoteStack_ptr < NoteStack_size)
13
        {
14
            midi_note = midi_note_temp;
15
            NoteStack_pool[NoteStack_ptr] = midi_note;        // write current note into notestack_pool
16
            NoteStack_ptr++;
17
            midi_sync_flag = 1;                                // start envelopes
18
        }        
19
}
20
21
22
//-------------------------------------------------------------------------
23
// NoteOff
24
//-------------------------------------------------------------------------
25
void midi_NoteOff(void)
26
{
27
    // load current note
28
    uint8_t midi_note_temp = midi_data[0];
29
    uint8_t last;
30
    
31
    // search current note into notestack_pool
32
    for (uint8_t i = 0; i < NoteStack_size; i++)
33
    {
34
        if (NoteStack_pool[i] == midi_note_temp)
35
        {
36
            // clear current note into notestack_pool
37
            NoteStack_pool[i] = 0xFF;
38
            NoteStack_ptr--;
39
            last = i;
40
            
41
            // sort notes into notestack_pool
42
            for (last; last < NoteStack_size;last++)
43
            {
44
                NoteStack_pool[last] = NoteStack_pool[last+1];
45
            }
46
            
47
            // playing previous note
48
            if (NoteStack_ptr > 0)
49
            {
50
                last = NoteStack_ptr-1;
51
                midi_note = NoteStack_pool[last];
52
                frequency_tune();
53
            }
54
            else
55
            {
56
                // stop envelope if no note into notestack_pool
57
                midi_gate_flag = 0;
58
            }
59
            break;
60
        }
61
    }        
62
}

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Heute sind die CPU Platinen für den DE:GENERATOR aus China eingetroffen. 
Wir haben insgesamt 10 Stück bestellt. Jetzt gehts ans SMD löten. Bin 
gespannt ob wir's hinbekommen.

Bilder: CPU Platine für den DE:GENERATOR

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Wir planen jetzt das Motherboard. Auf dem Motherboard (siehe Bild) sitzt 
die Spannungsversorgung, Midi Schnittstelle, VCA, Fx (Delay Schaltung) 
und Audio Ein/Ausgang. Das Filter- und CPU-Board werden später auf das 
Motherboard gesteckt. Da auf dem CPU-Board einige SMD Bauteile sitzen, 
wird sie von uns gelötet und getestet ausgeliefert. Jetzt gibt es noch 
ein paar Details zu klären, die den externen Audio Eingang auf dem 
Motherboard betreffen. Dann wird Andre mit dem Layouten beginnen.

Das Audiosignal kann Filtereingang oder Sampleeingang geroutet werden. 
Um eine Rückkopplung bei der Sampleaufnahme mit eingeschalteter 
Monitorfunktion zu vermeiden, muss der Filtereingang stumm schalten 
werden.

Bild: DE:GENERATOR Motherboard und externer Audio-Input

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Die Speicherverwaltung im DE:GENERATOR

Hallöchen zusammen. Heute will ich euch etwas über Speicherverwaltung im 
DE:GENERATOR erzählen. Wie ihr vermutlich schon wisst, besitzt der 
DE:GENERATOR einen 1MByte großen Sample Speicher. Dieser ist über das 
EBI-Speicherinterface mit dem ATxmega Prozessor verbunden. Dort wird ein 
geladenes Sample-File gespeichert und jeweils eine Wellenform-Bank für 
Oszillator 1+2. Ein kleiner Teil des Speichers wird noch für die 
Darstellung der Wellenform auf dem Display benötigt. Das 8KByte große 
SRAM im Xmega Prozessor wäre für die großen Sample-Files viel zu klein. 
Außerdem benötigt das Betriebsystem des DE:GENERATOR schon 5KByte im 
SRAM für Systemdaten und Variablen.

Die ersten beiden 4K Speicherblöcke sind für Bandlimitierte Wellenformen 
von Osc1+2 reserviert. Danach folgt der Speicherblock für das 
Sample-File. Im hinteren Teil des Speichers werden die geladenen 
Wellenform-Bänke von Oszillator 1+2 gespeichert. Jeder Oszillator kann 
dadurch unabhängig auf eine eigene Wellenform-Bank zugreifen oder auf 
das geladene Sample-File. Eine Verwaltung von zwei Sample-Files für 
beide Oszillatoren ist zur Zeit nicht vorgesehen und hätte den Nachteil, 
dass sich der Speicherplatz dafür halbieren würde.

Bis zum nächsten Mal. Gruß Rolf

Sample-Speicher

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen.. Live aus Wuppertal

Zur Zeit bin ich leider nicht in Berlin auf der SUPERBOOTH 16 sondern in 
Wuppertal und arbeite an den letzten Feinheiten für den DE:GENERATOR. 
Mein Kollege Andre Laska aus Oer Erkenschwick ist als Vertreter unseres 
DE:GENERATOR Teams vor Ort und schaut sich mal um was die Konkurrenz so 
treibt. Aus Kostengründen haben wir uns entschieden, keinen Stand zu 
mieten. Herr Schneider als Geschäftsführer und Mitorganisator der 
SUPERBOOTH 16 hatte uns freundlicherweise noch ein Plätzchen 
freigehalten. Aber vielleicht klappt's ja dann beim nächsten Mal..

Für alle Liebhaber der Elektronischen Musik und der Musikelektronik ist 
die SUPERBOOTH das Highlight des Jahres in Berlin. Ein Tag wäre viel zu 
kurz um die Vielfalt der Technik und die ganzen Möglichkeiten der 
Elektronischen Musik zu zeigen und zu hören. Aus diesem Grund findet die 
SUPERBOOTH ab Heute volle drei Tagen lang statt. Das gebotene Programm 
ist reichhaltig. Von Gesprächskonzerten, Workshops, Klanginstallationen 
bis zu DIY Workshops wird viel geboten. Namhafte Aussteller wzB Dieter 
Doepfer, Steinberg, Yamaha, Waldorf Musik uvm sind vor Ort.

Für "Stubenhocker" wie mich Augenzwinkern oder Leute die keine 
Möglichkeit haben nach Berlin zu fahren, gibt auf der SUPERBOOTH Website 
die Möglichkeit per Livstream dabei zu sein.

Link SUPERBOOTH Livestream: https://www.superbooth.com/de/

Bild: SUPERBOOTH 16 in Berlin

Bis dahin liebe Grüße aus Wuppertal. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Zur Abwechslung habe ich am DE:GENERATOR mal wieder etwas rumgeschraubt 
bzw etwas rumgelötet. Die Schaltung für den externen Audioeingang und 
Mikrovonverstärker wurden optimiert.
Ferner ist eine Audio-Clipping Schaltung für den ADC-Eingang integriert 
worden.

Schaltungsbeschreibung

Für die Oszilloskop Funktion im DE:GENERATOR wird das Ausgangssignal 
beider VCAs auf den Operationsverstärker IC15a geführt. Dieser summiert 
das Signal und führt es anschließend auf den Eingang von IC14a das hier 
als Signal-Umschalter für den ADC Eingang dient. Über den Trimmer R73 
wird der maximale Pegel für den ADC-Eingang eingestellt.

Um Übersteuerungen am ADC-Eingang zu begrenzen, ist eine 
Clipping-Schaltung mit IC16a realisiert worden. Die Transistoren T1 und 
T2 begrenzen das Ausgangssignal von IC16a auf ca. 1.2 Volt. Anschließend 
wird das Signal mit IC16b noch etwas verstärkt um die volle Dynamik des 
ADC auszunutzen. Um die systembedingten Störungen in der Sample Aufnahme 
zu verringern, ist der ADC-Eingang als Differenzial Eingang geschaltet. 
Mit IC16c wird das Signal negiert und an den negativen ADC-Eingang 
geführt. Für eine weitere Verbesserung der Aufnahme sorgt eine externe 
Referenzspannungsquelle mit IC17. Der Komperatoreingang am Xmega 
Prozessor dient als externe Trigger-Eingang für die 
Oszilloskop-Funktion.

Für den Mikrofonverstärker habe ich einen rauscharmen 
Operationsverstärker vom Typ NE5532 genommen. Laut Datenblatt liegt das 
Rauschen bei 5nV/Hz. Als Schaltungsvariante habe ich einen 
Nichtinvertierenden Operationsverstärker mit hohem Eingangswiderstand 
und 100 facher Verstärkung benutzt. Der hohe Eingangswiderstand hat den 
Vorteil, dass bei Anschluss von hochohmigen Mikrofonen die 
Ausgangsspannung des Mikrofons nicht zusammenbricht. Im DE:GENERATOR 
verwende ich ein preisgünstiges Elektret Mikrofon mit einer 
Ausgangsimpedanz von 2.2 KOhm. Der Widerstand R92 versorgt das Elektret 
Mikrofon mit der notwendigen positiven Versorgungsspannung.

Der externe Audio-Eingang gelangt über das als Summierer geschaltet 
IC15d an den Signal-Umschalter IC14a und von da an den ADC-Eingang. 
Ferner kann das externe Audio-Signal auch auf den Filter-Eingang 
geschaltet werden. Bei Sample-Aufnahmen wird der Filter-Eingang durch 
IC14a gesperrt bzw an GND gelegt um eine Signalrückkoplung zu vermeiden.

Auf aufwendige Aliasing-Filter am ADC-Eingang wurde hier verzichtet, da 
die Samplerate mit 44,1kHz sehr hoch ist und die Aufnahmen trotz 
fehlender Aliasing-Filter gut klingen.

Externer Audioeingang im DE.GENERATOR


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Die CPU-Platine für den DE:GENERATOR ist fertig gelötet. Wir habe eine 
kleine Elektronik Firma gefunden, die uns die Platinen kostengünstig 
löten kann. Somit entfällt das zeitaufwendige Löten der SMD-Bauteile. 
Ich habe es Gestern selber versucht und ca. eine Stunde für die 
komplette Bestücken und das Löten benötigt.

Ich baue jetzt einen kleinen Testadapter mit einem TFT-Display und 
programmiere ein paar Testroutinen. Dann muss das gute Teil nur noch 
funktionieren und ich wäre happy  ebueb

Der nächste Arbeitsschritt ist das Layouten des Motherboards. Diese 
Platine wird etwas aufwendiger sein und doppelt so groß werden wie die 
CPU-Platine.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen..

Gestern traf ich mich mit dem Kollegen Andre aus Oer-Erkenschwick. Er 
brachte zwei fertig bestückte Muster Platine des CPU-Boards zum testen 
mit. Um die CPU Platinen zu testen, habe ich einen kleinen Testadapter 
mit LED's und Display gebaut (siehe Bild). Der Test überprüft alle 
Port-Leitungen der CPU mittels LED. Um das Display zu testen, wird ein 
Bild von der SD-Karte geladen und an das Display übertragen. Zum Schluss 
wird das 1MByte große SRAM überprüft.

Bei dem Test für die Port-Leitunge viel mir auf, dass 4 Port-Leitungen 
(PB4 - PB7) nicht richtig funktionierten. Schuld war die JTAG Funktion 
im Xmega Prozessor. Diese ist ab Werk eingeschaltet und muss per 
Umprogrammierung der Fuses ausgeschaltet werden (siehe Bild). Damit 
stehen die 4 Port-Leitung zur freien Verfügung.

Lieben Gruß aus Wuppertal. Rolf

von Rolf D. (rolfdegen)



Lesenswert?

Hallo ihr Lieben..

Die Tage hat mich etwas schockiert... aber nur ein wenig Augenzwinkern
Unsere holländischen Kollegen von Tasty Chips Electronics bauen seit 
geraumer Zeit auch an einem Synthesizer namens ST4 und haben damit eine 
erfolgreiche Kickstarter Kampagne absolviert. Nicht das ich neidisch 
bin, weil einige Dinge am ST4 zufällig ähnlich aussehen wie am 
DE:GENERATOR und die Kollegen schon viel weiter sind als wir... Nein ich 
finde es immer wieder gut, dass es in der Synthi Scene kreative und 
kluge Menschen gibt von denen man positiv überrascht wird und viel 
lernen kann  ebueb

Bild 1: ST4 Synthesizer von Tasty Chips

So auch die Sache mit den externen Netzteilen. Tasty Chips Electronics 
beschreibt auf der eigenen Website, dass sie ihr AC-Steckernetzteil für 
den ST4 Synthesizer nicht mehr in die EU importieren dürfen. Daraufhin 
mussten sie die Stromversorgung für ihren ST4 Synthesizer redesignen um 
ein Schaltnetzteil zu verwenden . Das wollte ich jetzt aber genauer 
wissen, denn ich verwende für den DE:GENERATOR auch ein 
AC-Steckernetzteil. Auf der Suche nach der entsprechenden EG-Richtlinien 
wurde ich in der "Netzteil-Verordnung (EG) Nr. 278/2009: Vorgaben zur 
Leistungsaufnahme und Effizienz" fündig. Mit der Verordnung zur 
sogenannten Ökodesign-Richtlinie begrenzt die Europäische Kommission die 
Leistungsaufnahme von elektrisch betriebenen Geräten für private 
Haushalte. Die Leistungsaufnahme muss im vermeintlichen „Aus“-Zustand 
auf 0,5 bis 1 Watt sinken. Dadurch soll elektrischer Energie eingespart 
werden, die ungefähr dem jährlichen Landesverbrauch von 129.400 kWh in 
Schweden entspricht.

Hier ausführliche Informationen zum nachlesen: 
http://www.it-recht-kanzlei.de/externe-n...richtlinie.html

Für unseren DE:GENERATOR verwenden wir auch ein AC-Steckernetzteil. Es 
ist leider nicht möglich, das AC-Steckernetzteil gegen ein 
DC-Schaltnetzteil auszutauschen, da im DE:GENERATOR einige Baugruppen 
eine negative Versorgungsspannung benötigen. Da mein Kollege Andre mit 
der Entwicklung des Motherboards noch nicht begonnen hat, hab ich mich 
sofort auf meinen Hosenboden gesetzt und die Stromversorgung im 
DE:GENERATOR geändert.

Die Stromversorgung soll jetzt über ein handelsübliches 12 Volt 
DC-Schaltnetzteil erfolgen. Im DE:GENERATOR werden drei Spannungen 
benötigt. Zum einen eine 3.3 Volt Spannung für das CPU-Board und +8 
Volt/ -8Volt für die VCA's und das Filter-Board. Die -12V Spannung wird 
durch zwei parallel geschaltete TL1054 IC's erzeugt. Der TL1054 arbeitet 
nach dem Prinzip einer Ladungspumpe und ist in meiner Schaltung als 
Spannungs-Inverter geschaltet. Der TL1054 liefert an seinem Ausgang 
maximal 100mA Strom. Da wir für die negative Versorgungsspannung einen 
Strom von maximal 150mA benötigen, müssen zwei TL1054 parallel 
geschaltet werden. Bei einer Belastung von 150mA sinkt die 
Ausgangsspannung am TL1054 auf ca. -10,8 Volt was für den 7908 aber noch 
ausreicht um stabile -8 Volt zu erzeugen.

Bild 2: Neue Spannungsversorgung im DE:GENERATOR
Bild 3: Alte Spannungsversorgung im DE:GENERATOR
Bild 4+5: Neue -12V Spannungsversorgung

Was mir in der Schaltung noch nicht ganz gefällt, ist der hohe 
Energieverlust am LM1086 Spannungsregler. Dieser verheizt ca. 2 Watt und 
muss über einen kleinen Kühlkörper gekühlt werden. Das könnte man 
eventuell mit einem kleinen Schaltregler wzB dem LM2574 oder LM2575 
verbessern. Ich werde das mal ausprobieren. Ein "grüner Engel" ist mir 
dann bestimmt sicher  holy-willi

Liebe Grüße aus dem sonnigen Wuppertal. Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo an einem sonnigen Sonntag in Wuppertal smile

Hier die Schaltungsvariante mit einem Schaltregler LM2575 für die 3.3 
Volt Spannungsversorgung.
Ich will hoffen das der LC-Filter (L3 und C7) die 52KHz Schaltfrequenz 
am Ausgang des Schaltreglers soweit unterdrückt, dass es keinen 
Störeinfluss auf den ADC-Eingang und DAC-Ausgang im Xmega Prozessor 
gibt. Diode D3 und D5 dienen als Verpolungs- und Überspannungsschutz.

Bild: Stromversorgung mit Schaltregler LM2575

Durch den Schaltregler verringert sich die Verlustleistung um ca. 2.6 
Watt. Eventuell kann ich sogar auf einen Kühlkörper am LM2575 verzichtet 
und ein 12V DC-Netzteil mit weniger Leistung anstatt 1000mA eines mit 
600mA verwenden. Ferner reduziert das ein wenig die Kosten des 
Bausatzes. Bauteile sind jetzt bei Reichelt bestellt und dann wird 
wieder gebastelt.

Gruß Rolf

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Schaltung klappt. Hatte noch einen LM2574 in meiner Bastelkiste liegen. 
Der LM2574 ist der kleine Bruder vom LM2575 und kann nur 0.5A Strom.
Der Rippel am 3.3 Volt Ausgang liegt unter 20mV und ist weder am ADC 
noch am DAC des Xmega Prozessors hörbar. Der kleine LM2574 muss jetzt 
200mA auf der 3.3 Volt Spannungschiene liefern und wird dabei nur 
handwarm. Aus Kostengründen nehmen wir aber den leistungsstärkeren 
LM2575. Dieser ist etwas billiger und kann 1A.

Die Gesamtstromaufnahme des DE:GENERATOR's liegt jetzt bei 12V/375mA. In 
der alten Schaltung lag er noch bei 470mA. Die aktuelle Leistungsmessung 
am Netzteil ist 5.6 Watt. Damit ist die Stromversorgung im DE:GENERATOR 
optimal gelöst. Es gibt keine heißen Bauteile mehr und klobige 
Kühlkörper die wertvollen Platz auf der Platine verschwenden. Die 
Europäische und Internationale Gemeinschaft kann sich jetzt über ein 
Energieeffizentes Musikinstrument freuen  ebueb

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hier ist die Final Version meiner Netzteilschaltung im DE:GENERATOR. Ich 
habe noch ein paar Filterspulen an den Eingängen der Schaltregler 
integriert um die hochfrequenten Störungen auf der +12V 
Versorgungsleitung zu verringern.

Bild: Netzteilversorung im DE:GENERATOR

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Das ist ein Blockschaltbild vom DE:GENERATOR

von Audiomann (Gast)


Lesenswert?

Sounds, wir wollen Sounds. Gibt es irgendwo Tracks zum hören?

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Audiomann

Leider gibts noch keine komplette Sound Bibliothek. Auf soundcloud kann 
man sich aber schon einiges anhören.

Sound Beispiele auf Soundcloud:
https://soundcloud.com/rolfdegen/sound-xxl
https://soundcloud.com/rolfdegen/wave-sounds-from-my-diy-synth-diywa
https://soundcloud.com/rolfdegen/wavedemo-01
https://soundcloud.com/rolfdegen/wavesound-from-my-new-1mbyte
https://soundcloud.com/rolfdegen/halloween-sound
https://soundcloud.com/rolfdegen/avr-synthesizer-wave-1-stereo

Abropo Sounds: Für die Final Version des DE:GENERATORS wird es 
vermutlich noch einen besseren Stereo Multimode Filter geben.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Das Thema Stromversorgung im DEGENERATOR ist leider noch nicht ganz 
abgeschlossen. Da der LT1054 Baustein doch recht teuer ist, habe ich 
mich dazu entschlossen, eine andere Variante mit zwei Schaltreglern vom 
Typ LM2596 auszuprobieren. Die Schaltregler arbeiten mit einer höheren 
Schaltfrequenz von 150KHz und benötigen kleineren Spulen. Für die beiden 
LM2596 gibts bei Reichelt noch einen günstigen Vergleichtypen mit der 
Bezeichnung P3596. Diesen habe ich gleich mitbestellt und werde die 
Schaltung mit beiden Typen mal testen. Ferne besitzen beide Schaltregler 
eine Verzögerungsschaltung für die Strombegrenzung beim Einschalten an 
Pin 5 (on/off). Am negativen Schaltregler IC X4 sorgt die Diode D8 
dafür, das der Ausgang im Einschaltmoment nicht positiv wird.

Bild: Stromversorgung mit zwei Schaltreglern

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Leider gibts auch in der Elektronikentwicklung Probleme die erst später 
auffallen. So auch bei der Entwicklung der Netzteilversorgung in meinem 
Synthesizer. Ich musste die Schaltung mit einer Unterspannungserkennung 
(Undervoltage Lockout) erweitern, da mein kleines 12V DC-Steckernetzteil 
(Reichelt SNT 1000 12V Goobay) mit dem hohen Einschaltstrom der 
Schaltregler nicht klar kam und jedesmal die Spannung im Einschaltmoment 
zusammengebrochen ist.

Bemerkt hatte ich den Fehler, als ich das stromlose Steckernetzteil mit 
dem Synthesizer verbunden hatte und es dann über die Steckdosenleiste 
eingeschaltet habe. Vorher war das Steckernetzteil schon in Betrieb und 
ich hatte nur den DC-Stecker vom Netzteil mit dem Synthesizer verbunden.

In der geänderten Schaltung (Bild 1) startet der Schaltregler erst, wenn 
die Versorgungsspannung vom Steckernetzteil auf über 11 Volt angestiegen 
ist. Es funktioniert jetzt fehlerfrei mit allen 12V Steckernetzteilen 
die ich hier so rumliegen habe smile

Für die Unterspannungserkennung sorgen Transistor T1 und die Z-Diode 
D10. Solange die Versorgungsspannung unter 11 Volt liegt sperrt 
Transistor T1 und der ON/OFF Pin5 des Schaltreglers liegt auf high 
Potential. Steigt die Versorgungsspannung über 11 Volt wird T1 leitend 
und schaltet den ON/OFF Pin des Schaltregler auf low Potential womit der 
Schaltregler seine Arbeit aufnimmt (kann man sehr gut in Bild 3 sehen).

Die negative Ausgangsspannung von Schaltregler X4 wird durch die 
Widerstände R1, R2 und R5 auf -10,6V bestimmt. Für den dahinterliegenden 
Festspannungsregler 7908 sollte diese Spannung ausreichend sein um eine 
stabile -8V Spannung auch bei höherer Belastung zu liefern.

Aus Kosten- und Platzgründen auf dem Motherboard haben wir uns 
entschlossen die +5 Volt und +3.3V Versorgung über zwei 
Festspannungsregler zu machen.

Bild 1: DEGENERATOR Power supply

Bild 2: Spannungsverlauf
gelb: Spannungsverlauf 12V DC-Netzteil
blau: -10,6V Spannungsverlauf am Eingang Festspannungsregler 7908

Bild 3: Undervoltage Lockout on P3596
gelb: Spannungsverlauf 12V DC-Netzteil
blau: Schaltsignal an Pin2 von P3596


Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Ups.. kleiner Fehler im Schaltplan. Die Diode D9 ist verpolt gezeichnet 
und lässt so keinen Strom zum Schaltregler X4 fließen  ebueb Hier die 
Korrektur.

Bild 1: DEGENERATOR Power supply


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hab mal den Strom in der Schaltung gemessen (siehe Bild).

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Alle guten Dinge sind 3... So auch mit der Stromversorgung im 
Degenerator. Man sollte erst den Schaltplan zeichnen und dann nach 
diesem Plan löten. Dann würden Fehler in der Zeichnung direkt auffallen 
und nicht hinterher. So gibts jetzt die 3.Korrektur  Augenzwinkern

PS: Das hätte dann aber auch Nachteile... wzB ein Nichtfunktionieren der 
Schaltung oder vielleicht einen Kurzschluss oder sogar den Tod von 
Bauteilen  geschockt

Bild: Degenerator Power Supply


In der letzten Schaltung sind die Widerstände R1, R2 und R5 vertauscht 
gezeichnet. Zusätzlich wird laut Herstelle in der Adjustable Output 
Version des Schaltreglers X4 ab einer Ausgangsspannung von 10V ein 
kleiner Kondensator C18 für eine bessere Stabilität der Regelschleife 
empfohlen. Da der Schaltreglers X4 an seinem Ausgang zukünftig mit nur 
wenige 100mA belastet wird, habe ich die Kondensatoren C7 u. C15 von 
470uF auf 220uF verringert. Das mindert den Einschaltstrom fürs Netzteil 
und garantiert dennoch eine stabile -8V Spannungversorgung.

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

In der Netzteilschaltung muss ich doch die Dioden vom Typ 1N5818 nehmen 
(D3, D7, D8, D11). In der Zeichnung hatte ich die 1N5822 geplant, die 
hat aber eine UF von 0,525 Volt. Am Schaltregler lägen dann weniger als 
11V an und das könnte fürs Einschalten des Schaltreglers etwas knapp 
werden.

Die kleinere 1N5818 hat eine UF von 0,33V und einen Spitzenstrom von 
25A. Für den Einschaltmoment sollte der Dioden-Spitzenstrom von der 
1N5818 groß genug sein. Momentan benutze ich diese Diode in der 
Schaltung und es funktioniert problemlos.

PS: Das war jetzt aber wirklich die letzte Korrektur. Hoffe ich  ;)

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen miteinander!

Soeben hat mir Andre die ersten Entwürfe vom Motherboard Designe des 
Degenerators geschickt. Oben rechts neben der Netzteilbuchse befindet 
sich der Schaltregler P3596 für die negative Betriebspannung. Darunter 
die Bauteile für die Spannungsüberwachung des Schaltregler. Diese 
Bauteile werden ein wenig vom CPU-Board überdeckt. Rechts neben dem 
Schaltregler befinden sich die 4 Festspannungsregler für die 
Betriebsspannung von +3.3V +5V +8V -8V Für den +5V Regler wird es einen 
Kühlkörper geben.

Oben rechts neben den Festspannungsreglern sind die Midi-Buchsen und die 
Audio-Buchsen geplant. Auf der Freifläche werden VCA und 
Effekt-Schaltung platziert.

Bild: DEGENERATOR Motherboard


Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Es geht voran... Andre ist am layouten und ich programmiere noch :)

Wenn nichts dazwischen kommt, ist das Motherboard in ein bis zwei Wochen 
fertig und kann in China bestellt werden. Die Bilder zeigen die 
Stromversorgung mit +3.3V +5V +8V -8V +12V. Es wird eine Masse-Fläche 
geben, die von den Festspannungsreglern LV33, 7805, 7808, 7908, zu den 
einzelnen Baugruppen führt. Der 7805 besitz einen Kühlkörper.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo
Es geht schnell voran  großes Grinsen
Unter dem Filterboard befindet sich der VCA. Die Leitungen zum 
Filterboard sind dadurch sehr kurz und weniger störanfällig. Oben rechts 
befindet sich der Audioausgang. Darunter der Steckkontakt K4. An diesem 
wird das Lautstärke-Poti auf der Frontplatte verbunden. Ferner befinden 
sich oben die Midi-Buchsen und der obligatorische Optokoppler. 
Audioinput und Delay Schaltung fehlen noch.

Bild1: Degenerator Motherboard PCB

Ach.. hab noch etwas vergessen. In Bezug auf die Wiederauferstehung der 
Synthesizer Chips von Curtis gibts auf Muso talk einen interessanten 
Video Beitrag.

It moves quickly !
Pic1: Degenerator Motherboard PCB

Oh ..'ve forgotten something. With the resurrection of the Synthesizer 
chip from Curtis gives an interesting video on Muso Talk.

Muso Talk Link: 
http://www.musotalk.de/video/synthi-talk-curtis-chips-are-back-weitere-news/

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hi zusammen...

Wir haben die Audio-Buchsen etwas abgeändert. Zwei Mono Klinkenbuchsen 
für den Ausgang und
eine Stereo Eingangsbuchse für Filter und Sampling. Für eine MidiThru 
Buchse ist leider keinen Platz
mehr unglücklich

Rechts unter dem Filterboard befindet sich die VCA-Schaltung. Die 
Delay-Schaltung wird unterhalb
der Audio-Buchsen ihren Platz bekommen. Unter der CPU-Platin befinden 
sich die Schaltungsteile für
den Scope- und ADC-Eingang sowie der Mikrofon-Verstärker. Der freie 
Bereich unterhalb des Filter-
boards wird für die Umschaltungelektronik des Audioeingangs benötigt.


Bilder: Degenerator Motherboard 3.9

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

So... geschafft. Motherboard ist fertig. Jetzt gibts eine Endkontrolle 
und dann werden in China ein paar Platinen für eine Vorserie bestellt. 
Bin gespannt ob das alles so funktioniert  ebueb

Zur Zeit arbeite ich noch an dem Oszillator Menü. Ich habe jetzt einige 
Ozcillator Funktionen vom Shruthi Synthesizer implementiert zB. 
Phase-distortion sawtooth with filter sweep, Phase-distortion sawtooth 
with resonant filter sweep, Phase-distortion resonant triangle monster, 
Phase-distortion trapezoidal creature,Phase-distortion/self-sync trick, 
Stack of 4 detuned sawtooth waves, 2-operators FM, bit-crushed sine and 
triangle wave, PWM, Filtered noise generator u.a.

Gruß Rolf

Bild: Degenerator Motherboard

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

Zur Zeit arbeite ich noch an den Oszillatoren. Hier eine kleine 
Kostprobe mit einem Oscillator. Sound und Effekte kommen vom 
Degenerator. LFO1 moduliert Oscillator Parameter1, LFO2 moduliert VCA 
Panorama und ein wenig Delay mit Feeback.

Soundcloud: 
https://soundcloud.com/rolfdegen/cz-waveform-from-degenerator

von Rolf D. (rolfdegen)


Lesenswert?

Hallöchen..

So.. der zweite Oscillator steht. Hier eine kleine Live Performance mit 
zwei Oscillatoren und ein wenig Modulation am Degenerator.

Hi guys..

The second Oscillator is right now. Here an little live performance from 
my Degenerator with two oscillators.

soundcloud: https://soundcloud.com/rolfdegen/two-oscillators-live

Osc1 Saw, Osc2 change waveforms, LFO1 mod VCA Pan, a little Delay from 
PT2399 in Degenerator

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Zur Zeit arbeite ich noch an den Oszillatoren. Auf Soundcloud gibts ein 
paar Testsounds.

Soundcloud:https://soundcloud.com/rolfdegen/wavessounds2-from-degenerator
Soundcloud:https://soundcloud.com/rolfdegen/two-oscillators-live

Youtube:https://www.youtube.com/watch?v=_-mXarRyn80&feature=youtu.be
Youtube:https://www.youtube.com/watch?v=cz4JQCi9O9M



Gruß Rolf

: Bearbeitet durch User
von Hi-Tech-Progger S. (Gast)


Lesenswert?

Ist da ein professineller Verkauf im Verlauf?

von Rolf D. (rolfdegen)


Lesenswert?

Ja. Der Synthesizer/Sampler ist als Baussatz in verschiedenen 
Ausbaustufen mit Gehäuse geplant.

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Mein Freund Andre aus Oer-Erkenschwick (TubeOhm Instruments) hat mich 
heute mit einer guten Nachricht überrascht. Die Motherboard Platinen für 
den Degenerator sind eingetroffen. Die Qualität ist gut. Jetzt werden 
Bauteile bestellt und am Freitag zwei Platinen bestück. Dann wird 
getestet. Bin gespannt obs läuft...

Bild: Degenerator Motherboard

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Bin fleißig am löten und bald (fix und) fertig...  Augenzwinkern

Was jetzt noch fehlt ist das Filter- und Panel-Board. Für einen 
bestimmten Filter haben wir uns noch nicht entschieden. Jetzt werden 
erst mal zwei Filtertypen (12dB LP/HP/BP in Stereo und 4pol Mission 
ähnlich wie im Shruthi Synthesizer) aufgebaut und im Degenerator 
getestet.

Bild: Degenerator Motherboard mit CPU-Board

: Bearbeitet durch User
von Thomas (kosmos)


Lesenswert?

Interessantes Projekt. Zu dem Punkt mit der JTAG Fuse, dies kann man per 
Software mittels JTAG Disable Bit deaktivieren. Hat den Vorteil das man 
noch per JTAG Zugriff hat. Man warten also beim Start eine kurze Zeit ab 
um einen JTAG Zugriff zu ermöglichen wenn nicht passiert schaltet man 
dann JTAG per Software nach ein paar Sekunden ab.

von Rolf D. (rolfdegen)


Lesenswert?

Danke für den Tip :)

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen Miteinander!

Midi, VCA und MircoAmp funktionieren wunderbar sowie die 
Delay-Schaltung. Jetzt löte ich die Filter-Schaltung. Bevor die 
Filter-Platinen layouted wird muß diese noch einmal aufgebaut und 
getestet werden. Platzmäßig sollte es funktionieren (siehe Bild).

Bilder: Degnerator Motherboard mit CPU- und Filter-Board

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo zusammen...

Das Filterboard für den Degenerator ist fertig. Es handelt sich um einen 
12dB Stereo-Multi-Filter mit Umschaltung auf LP/HP/BP. An dem zweiten 
Filterboard (SMR4-Pole mixing) wird noch gearbeitet.

Bilder: Degenrator mit Filterboard

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Die drei LFO-Led's auf dem Front Panel werden jetzt über ein 
Schieberegister 74HC595 im PWM-Mode angesteuert und verändern ihre 
Helligkeit je nach eingestellter Wellenform und Amplitude.

LFO-Leds am Degnerator: 
https://www.youtube.com/watch?v=bMUaGmoW2oY&feature=youtu.be

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen miteinander!

Nach einer kleinen (Kaffee) Pause gehts jetzt weiter Augenzwinkern

Mein ein Jahr altes 70MHz Oszilloskop Siglent SDS1072CML ist defekt. Die 
Hintergrundbeleuchtung
flackert und gibt vermutlich irgendwann ganz den Geist auf. Die Ursache 
laut Hersteller ist vermutlich
ein defekter Elko auf der Netzteil Platine. Da ich das Oszilloskop vor 
ca. einem Jahr über Amazon
gekauft hatte, konnte ich Dank freundlicher Unterstützung eines Service 
Mitarbeiters das defekte
Gerät an Amazon zurückschicken. Da der Hersteller Siglent die Produktion 
dieses Modells ein-
gestellt hat, habe ich mich für ein neueres 100MHz Scope von Siglent 
entschieden. Es ist das
SDS1102CML+. Die Plus Versionen haben eine verbesserte Displayauflösung 
(800 x 480), ein
Redesign der Bedienelemente, eine LAN Schnittstelle und eine 
Speicheroptimierung (mehr
Speicher für die Aufnahmefunktion, weniger Speicher für intern 
gespeicherte Signale).


Fazit: Das einzige was mich etwas stört, ist die violette Anzeige für 
den zweiten Kanal. Die ist mir
etwas zu dunkel. Mein altes Scope hatte für den zweiten Kanal eine 
hellblaue Farbe und war
desshalb etwas besser abzulesen. Aber ansonsten kann ich mich nicht 
beklagen. Für knapp 355,-
Euro bekommt man aus China ein gute Qualität geliefert.

Bild: Oszilloskop Siglent SDS1102CML+

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen miteinander!

Bekanntlich kommt nach jede Lösung eines Problems ein neues Problem 
dazu. So auch im
Degenerator. Im Degenerator arbeiten zwei Oszillatoren deren Werte in 
zwei 64 Byte großen
Zwischenspeichern geschrieben werden und in einem Timer Interrupt an den 
DAC Ausgang
gesendet werden. Dabei traten bei kurzen Attack-Werten störende 
Klickgeräusche auf (Bild 2).
Eine Analyse der Programmabläufe und Betrachtung auf dem Oszilloskop 
brachte mich dann auf
den Pfad der Erleuchtung  holy-willi

In einem Timer Interrupt wird jede Millisekunde geprüft, ob Midi-Daten 
im Empfangsbuffer
vorhanden sind und ggf die neuen Notenwerte für die beiden Oszillatoren 
berechnet.

Danach fülle ich die beiden Zwischenspeicher mit jeweils 64 neuen 
Oszillator Werten.

Danach aktualisiere ich die beiden Envelopes und die CV-Outputs für VCA 
und VCF.

In einem Timer Interrupt mit höchster Priorität, werden alle 25usec 
jeweils ein Werte aus den
beiden Zwischenspeichern gelesen und an den DAC Ausgang gesendet (Bild 
1).

Zuvor hatte ich die Notenwerte für die beiden Oszillatoren in der 
Envelope Routine aktuallisiert.
Das führte dazu, dass sich von der alten Note noch Reste im 
Zwischenspeicher befanden und
dies zu Störungen am Audioausgang führte (Bild 2).

Bild 1: Midi-Input (gelb) und störungsfreier Audioausgang (violett)


Bild 2: Audioausgang mit Klickgeräusch am Anfang


Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen miteinander smile

Heute gehts um Puffergröße und CPU Ressourcen

Im Degenerator wird viel gerechnet zB Echtzeitberechnung von zwei 
Oszillatoren, Sampling, 3 LFO's, 2 Envelopes, Modulationsmatrix, 
Grafisches Benutzerinterface, Oszilloskop Funktion uvm. Die 
Prozessorressourcen in so einer 32MHz "schnellen" ATMEL MCU (Xmega128AU) 
sind leider sehr knapp und ich musste nach intelligenten Lösungen suchen 
damit alles schnell und fehlerfrei funktioniert. Für eine spätere 
Weiterentwicklung die eventuell mehr CPU Leistung benötigt, ist der 
Austausch der CPU-Platine gegen eine Platine mit einem 
leistungsstärkeren ARM Prozessor gedacht.

Im Degenerator benötigt die Berechnungsroutine für die Oszillatoren 
(violett) ca. 41% der gesammten Rechenleistung eines Xmegas. Alle 25usec 
werden zwei Oszillatorwerte (gelb) aus einem Puffer an die beiden DAC 
Ausgänge gesendet. Das dauert ca. 1 usec und entspricht einer Samplerate 
von 40KHz. Da es sehr uneffizent wäre die Oszillatorwerte alle 25usec 
neu zu berechnen (so habe ich es füher gemacht), benutze ich eine 
Pufferroutine, in der vorab 2x40 Oszillatorwerte berrechnet und in einem 
Puffer zwischen gespeichert werden. Alle 25usec werden dann die Werte 
aus dem Puffer gelesen und an den DAC gesendet. Das hört sich einfach an 
ist es aber nicht. Der Buffer besteht eigentlich aus zwei Doppelpuffer 
mit jeweils 80 Byte für beide Oszillatoren. Um die Funktionsweise der 
Pufferroutine zu erläutern beziehe ich mich aber nur auf einen 
Doppelpuffer.

Bild 1: Doppelpuffer


Funktionweise des Doppelpuffers
Bild 1: Der geschlossene Kreis verdeutlicht den Ablauf, da in einer 
ständigen Wiederholung nach dem zweiten Puffer wieder der erste folgt. 
Jeder Puffer fasst hier 40 Samples, entsprechend einer Latenz von ms. 
Wie diese 1 ms entstehen ist einfach nachzuvollziehen. Beim Start der 
Wiedergabe befindet sich der Positionszeiger an der mit 0 bezeichneten 
Stelle. Da beim Start der Wiedergabe der erste Puffer bereits abgespielt 
wird kopiert die Software alle Daten zunächst in den zweiten Puffer. 
Stellen Sie sich (in Zeitlupe) vor, wie sich der Zeiger im Uhrzeigersinn 
fortbewegt. Bei einer Samplefrequenz von 40 kHz werden die 40 Samples in 
nur 1 ms abgearbeitet. Sobald der Zeiger die Grenze zwischen den Puffern 
erreicht hat (Position 1) wird ein Interrupt ausgelöst, und die Software 
berechnet die nächsten 40 Samples und speichert diese in den (nunmehr 
abgearbeiteten) ersten Puffer. Der zweite Puffer wird nun abgespielt, am 
Ende (Position 0) wieder ein Interrupt ausgelöst, Sampels werden wieder 
berechnet und in den zweiten Puffer kopiert.. Das ganze Pufferspiel 
wiederholt sich unendlich.


Bild 2: Zeitintervall der Pufferfunktion


Gelb: 25 usec Intervall für Sampleausgabe auf den DAC (Dauer ca. 1usec)
Violett: 1 ms Intervall für die Berechnung von 80 Samples (Dauer ca. 
412usec)

Im nächsten Beitrag gehts ums Thema Puffer und Midi Latenz

Bis dahin liebe Grüße aus Wuppertal. Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo liebe Freunde smile

Ich habe die "Optimierung" in Atmel Studio 7 von -OS zu -O1 geändert. 
Das Ergebnis ist ein schnellerer Code und ein wenig mehr Code im 
Programmspeicher des Xmega Prozessors.
Durch die geänderte Optimierung ist der Code für die Berechnung und 
Speicherung der Oszillatorwerte wesentlich schneller geworden. Ferner 
werden die Menüseiten schneller aufgebaut. Die Prozessorauslastung liegt 
jetzt bei ca. 31%.

Bild 1:Berechnung von 2x40 Oszillatorwerten und speichern in den Puffer 
in 514 usec mit optimize -OS

Bild 2: Berechnung von 2x40 Oszillatorwerten und speichern in den Buffer 
in 308 usec mit optimize -O1

Gelb: 25 Mikrosekunden Intervall. Es werden zwei Samples aus dem Puffer 
gelesen und an die beiden DACs gesendet
Violett: Berechnet 2x40 Oscillatorwerte und speichert diese in einen 
Puffer

Jetzt ist alles super schnell und fluppt schön  großes Grinsen

Ich habe aus Interesse mal die max Zeit für das Berechnen und 
abspeichern der Oszillatorwerte in den Puffer gemessen. Je nach Art der 
Synthese ergeben unterschiedliche Zeiten für die Berechnung bis maximal 
352 usec. Im Video kann man das schön verfolgen. Gelb die errechnete 
Wellenform und voilett die benötigte Zeit.

Youtube: https://www.youtube.com/watch?v=AbtCYI0X_TI&feature=youtu.be

Gruß Rolf

von Hi-Tech-Progger S. (Gast)


Lesenswert?

Nicht übel!

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Für die Wiedergabe von Samples stehen im Degenerator 982KB externes SRAM 
zur Verfügung. Das SRAM ist in verschiedenen Blockgrößen unterteilt. Der 
erste Block ist für zwei Sample-Files reserviert. Der freie 
Speicherplatz für einen zu ladenden Sample verringert sich in 
Abhängigkeit von der Größe des zu erst geladenen Samples. Der 2. und 3. 
Speicherblock ist für zwei 32KB Wellenform Bänke für Oszillator 1 und 
Oszillator 2 vorgesehen. Beim Umschalten auf eine andere Wellenformbank 
werden die Daten von der SD Karte in das SRAM geladen. Der 
4.Speicherblock dient als Zwischenspeicher für die Grafische Darstellung 
des Sample-Files.

Bild 1: 1MB XRAM im Degnerator
Bild 2: Oszillator-Menü

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Um die Warterei auf den Degenerator etwas zu überbrücken, hab ich ein 
paar aktuelle Demo-Sounds vom Degenerator auf soundcloud.de hochgeladen. 
Die Sounds bestehen aus verschiedene Samples die über Oszillator 1+2 
wiedergegeben werden. LFO1 moduliert das Delay-Panorama. Viel Spaß beim 
anhören.

Soundcloud: https://soundcloud.com/rolf-degen/wav-sounds-from-degnerator

von Klopper (Gast)


Lesenswert?

Rolf D. schrieb:
> Youtube: https://www.youtube.com/watch?v=AbtCYI0X_TI&featur...

Bellt da bei 0:28 ein Hund?

von Rolf D. (rolfdegen)


Lesenswert?

Hi Klopper.
Du meinst vermutlich diesen Link:
Soundcloud: https://soundcloud.com/rolf-degen/wav-sounds-from-degnerator

Nein..das ist in Chor Sample :)

Gruß Rolf

: Bearbeitet durch User
von Klopper (Gast)


Lesenswert?

Rolf D. schrieb:
> Du meinst vermutlich diesen Link:
> Soundcloud: https://soundcloud.com/rolf-degen/wav-sounds-from-degnerator
>
> Nein..das ist in Chor Sample :)

Ich meinte schon
https://www.youtube.com/watch?v=AbtCYI0X_TI&featur

Zwei Mal nach ~0:28, hört sich an wie "Wuff wuff"; Abstand etwa 0,6 bis 
0,7s und natürlich ziemlich leise im Vergleich zum eigentlichen Sound.
Ist ja nicht so wichtig, mich hatte nur interessiert, ob das irgendein 
"Nebeneffekt" ist oder tatsächlich Bellen.

von Rolf D. (rolfdegen)


Lesenswert?

Ok. In diesem Video sind die Klänge alles Oszillator Synthesen die in 
Echtzeit berechnet werden. Ab 0:28 ist das Shape "OSC_ZPULS_LP". 
Grundlage für diesen Klang ist eine 256 Byte große Sinus-Wellenform.

1
//*************************************************************************
2
// OscRender: CzPulsReso
3
//*************************************************************************
4
void OscRender_CZPULS(uint8_t osc_nr)
5
{
6
  uint8_t block_size = 40;
7
  uint8_t shape;
8
  uint8_t parameter;
9
  uint8_t *buffer;  // pointer name
10
  uint8_t i = 0;
11
  uint16_t phase_2 = Osc.data_secondary_phase[osc_nr];
12
  
13
  if (osc_nr == 0)
14
  {
15
    shape = Osc.shape[0];
16
    parameter = Osc.prm_value[0];
17
    if (Voice.buffer_nr == 0)
18
    {
19
      buffer = Voice.Buffer2a;
20
    }
21
    else {buffer = Voice.Buffer1a;}
22
  }
23
  else
24
  {
25
    shape = Osc.shape[1];
26
    parameter = Osc.prm_value[1];
27
    if (Voice.buffer_nr == 0)
28
    {
29
      buffer = Voice.Buffer2b;
30
    }
31
    else {buffer = Voice.Buffer1b;}
32
  }
33
  
34
  // calc integral
35
  uint16_t phase_increment_integral = Osc.phase_increment[osc_nr] >> 8;
36
  uint16_t increment = phase_increment_integral + (
37
  (phase_increment_integral * (uint32_t)(parameter)) >> 2);
38
  
39
  while (block_size--)
40
  {
41
    // update Phase
42
    Osc.phase[osc_nr] += Osc.phase_increment[osc_nr];
43
    
44
    // Osc sync
45
    if (osc_nr == 0){Osc12.syncbuffer[i] = Osc.phase[osc_nr] < Osc.phase_increment[osc_nr] ? 1:0;}
46
    else{if (Osc.op_value == OP_SYNC){if (Osc12.syncbuffer[i]) Osc.phase[osc_nr] = 0;}}
47
    
48
    uint16_t phase_integral = Osc.phase[osc_nr] >> 8;
49
    
50
    if (Osc.phase[osc_nr] < Osc.phase_increment[osc_nr]) // if carry
51
    {
52
      phase_2 = (shape == OSC_ZPULS_LP) ? 0 : 32768;
53
    }
54
    
55
    phase_2 += increment;
56
    uint8_t carrier = pgm_read_byte (&(wav_res_sine[phase_2 >> 8]));
57
    if (shape == OSC_ZPULS_PK)
58
    {
59
      carrier >>= 1;
60
      carrier += 128;
61
    }
62
    uint8_t window = 0;
63
    if (phase_integral < 0x4000)
64
    {
65
      window = 255;
66
      } else if (phase_integral < 0x8000) {
67
      window = ~(phase_integral - 0x4000) >> 6;
68
    }
69
    if (shape == OSC_ZPULS_HP) {
70
      // write sample in sound-buffer
71
      buffer[i] = ~(S8U8MulShift8(carrier + 128, window) + 128);
72
      i++;
73
    }
74
    else
75
    {
76
      buffer[i] = ~U8U8MulShift8(carrier, window);
77
      i++;
78
    }
79
  }
80
  
81
  // update secondary phase
82
  Osc.data_secondary_phase[osc_nr] = phase_2;
83
    
84
}

Gruß Rolf

: Bearbeitet durch User
von Hi-Tech-Progger S. (Gast)


Lesenswert?

Das sind aber nicht viele Stützstellen, um mit verschiedenen Frequenzen 
in die Tabelle zu gehen. Gute DDS-Bausteine arbeiten mit 2Mio grossen 
Tabellen.

von Rolf D. (rolfdegen)


Lesenswert?

Hi Reinhard

Ja das stimmt. Im Degenerator wird für die Berechnung der Notenfrequenz 
eine 24Bit DDS benutzt. Der 12dB VCF glättet die Ausgangswerte am DAC. 
So sind Frequenzen bis zu 8KHz spielbar. Für Musikalische Anwendungen 
völlig ausreichend.

Gruß Rolf

von Rolf D. (rolfdegen)



Lesenswert?

So soll er mal aussehen... Der DEGENERATOR. Am Designe wird aber noch 
gearbeitet.

Das Pannelboard ist fertig. Ich überprüfe jetzt noch einmal Schaltbild 
und PCB Layout. Sollten es keine Fehler haben dann wird's zusammen mit 
dem Filterboard bestellt. Andre feilt noch ein wenig am Gehäuse. Auf das 
Endergebnis bin sehr gespannt.

Ich für mein Teil arbeite noch an ein paar Baustellen in der Software. 
Zum Beispiel an der Schnitt- und Loop-Funktion für Samples. Übrigens 
klingen die 8Bit Samples in Verbindung mit den festen 
Oszillatorwellenformen total geil. Hier ein kleines Beispiel: 
Oszillator1 spielt einen Chor-Sample und Oszillator2 eine Sinusartige 
Wellenform mit leichtem Frequenzversatz (siehe Bild Osc-Page). 
Echo-Effekt kommt ebenfalls vom Degenerator.

Sound: https://soundcloud.com/rolfdegen/degenerator-choir-01

: Bearbeitet durch User
von Hi-Tech-Progger S. (Gast)


Lesenswert?

Geht ja zügig voran. Würde gern mal was Hören. leider gibt weder 
soundcloud noch youtube über die links einen ton ab.

von Dieter F. (Gast)


Lesenswert?

Reinhard S. schrieb:
> leider gibt weder
> soundcloud noch youtube über die links einen ton ab.

Ton eingeschaltet? :-) Funktioniert alles prima ...

von Rolf D. (rolfdegen)


Lesenswert?

Ja super. Freut mich das es klappt. Gruß Rolf

Hier mein Blog: 
http://www.cczwei-forum.de/cc2/thread.php?threadid=5878&page=29

: Bearbeitet durch User
von Horst M. (horst)


Angehängte Dateien:

Lesenswert?

Rolf D. schrieb:
> Sound: https://soundcloud.com/rolfdegen/degenerator-choir-01

Rolf, da sind Klicks im Output.
Zwei Beispiele im Bild.
Im Original (nicht mp3) womöglich noch deutlicher zu hören.

von Rolf D. (rolfdegen)


Lesenswert?

Hallo Horst..

Das mit den Klicks liegt daran, dass der Chor-Sample keinen Loop-Punkt 
besitzt und einmal komplett durch läuft. Bei jeder neuen Note wird der 
Chor-Sample neu gestartet.

von Hi-Tech-Progger S. (Gast)


Lesenswert?

Mit welcher Software ist denn das design entworfen worden? Ist das was 
Spezielles für Elektronik?

von Rolf D. (rolfdegen)


Lesenswert?

Meinst du das Gehäuse ? Wenn ja, das hat ein Bekannter entworfen. 
Software weis ich nicht.

von Hi-Tech-Progger S. (Gast)


Lesenswert?

Ja, sieht ziemlich realistisch aus.

Der Synthie scheint in jedem Fall mal was anderes zu sein, als das 
langweilige Sinus-Rechteck-Dreieck-Zeugs, von dem niemand so richtig 
erklären kann, warum man es immer einsetzt.

Wieviele Samples kannst du gleichzeitig laden und spielen?

von J. S. (engineer) Benutzerseite


Lesenswert?

Re. S. schrieb:
> langweilige Sinus-Rechteck-Dreieck-Zeugs, von dem niemand so richtig
> erklären kann, warum man es immer einsetzt.

Rechteck und Dreieck sowie Sägezahn repräsentieren jeweils getrennt 
voneinander die mathematisch möglichen Oberwellen vom jeweiligen Sinus 
und zwar einmal die ungeraden und einmal die geraden. Man kann mit 
diesen drei vergleichsweise einfach zu erzeugenden Wellenformen, somit 
ein weites Spektrum von Klangfarben darstellen und zurechtfiltern.

Das Einzige ist, dass das Oberwellenspektrum im Verlauf festliegt. Das 
hört sich aber sehr angenehm an, wenn die Harmonischen nach oben hin 
auslaufen - zudem lässt sich das mit geeigneten Methoden auch ändern und 
einstellen. Ich verwende bei meinem Synth ein glattes 
Oberwellenspektrum.

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

@Re.Sa.  Ich habe zwei Oscillatoren die jeweils einen Sample oder eine 
berechnete Wellenform, oder eine feste Wellenform wiedergeben können.

Zum Projekt: Die bestellten Platinen für Pannelboard und Filter werden 
erst am 26.Dezember ausgeliefert. Also müssen wir uns noch etwas 
gedulden. Der weilen arbeite ich noch etwas an der Software. Für 
Sample-Aufnahmen gibts jetzt eine Schnittfunktion um Störungen oder 
andere Dinge herauszuschneiden.

Bild: Sample-Editor im DE-GENERATOR
Der invertierte Bereich zwichen A und B wird mit betätigen der Taste 
"Delete" gelöscht. Die 6stelligen Ziffern über den Reglern zeigen die 
aktuelle Sample-Adresse von Punkt A und Punkt B an.

Es gibt einen neuen Soundtrack vom DE-GENERATOR. Die CD gibt's 
allerdings noch nicht im Handel ;) Viel Spaß beim anhören...

Link: https://soundcloud.com/rolfdegen/demo7

Gruß Rolf

: Bearbeitet durch User
von J. S. (engineer) Benutzerseite


Lesenswert?

Hoi, hoi, so langsam wird es richtiger Synthie. Einige Tipps:

Bei dem Sample-Schnitt sollte es möglich sein, den Offset auf Null zu 
bringen. Denn muss man ausrechnen und anzeigen, oder es automatisieren. 
Bei meinem "beat morph" im drum computer hat sich das sehr bezahlt 
gemacht. Ansonsten hast Du ein überlagertes Rechteck drin.

Wenn es geht, muss das Sample oversampelt werden, um die Frequenzen 
richtig zu treffen. Am Besten, man macht das offline und schiebt es in 
irgendein RAM.

Idealerweise kann man für verschiedene Frequenzen verschiedene 
Samplestartpunkte definieren, um sich den Phasen anzupassen. Weiss aber 
nicht, ob das mit dem AVR geht.

von Rolf D. (rolfdegen)



Lesenswert?

Es ist geschafft...

Kurz vor dem Jahreswechsel kann ich verkünden, dass der DE-GENERATOR bzw 
die Elektronik fertig ist und alles funktioniert. Die nächsten Tage und 
Wochen werden wir noch am Gehäuse und an der Software arbeiten.

Bilder: DE-GENERATOR

Mehr Info auf: 
http://www.cczwei-forum.de/cc2/thread.php?threadid=5878&threadview=0&hilight=&hilightuser=0&sid=97cfc2568c979f331518db43aaf4e597&page=1

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Mein Freund Andre Laskar aus Oer-Erkenschwick war wieder sehr fleißig 
und hat mal ein Video gedreht und präsentiert seine ersten Eindrücke vom 
DE-GENERATOR.

Youtube: https://www.youtube.com/watch?v=GiG0H_HVuZs

Pic: TubeOhm Instruments

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Halli.. hallo..

Es gibt wieder Neuigkeiten zu berichten. Das 2.Filterboard für den 
DE-GENERATOR ist fertig.
Es handelt sich um einen stereophonen 4-Pole Mision Filter mit folgenden 
Eigenschaften:
 * Lowpass 6dB
 * Lowpass 12dB
 * Lowpass 18dB
 * Lowpass 24dB
 * Bandpass 12dB
 * Hochpass 12dB
 * Lowpass + Hochpass 12dB

Bild1: SMR4 Filter im DE-GENERATOR
Bild2: Schaltplan

Es gibt ein kleines Video zum Filter: 
https://www.facebook.com/tubeohm.tubeohminstruments/videos/1227302477354296/
Info: Lautstärke einschalten!

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Je größer der Programmcode um so mehr Fehler macht man. Diese 
Erkenntniss teile ich warscheinlich
auch mit vielen anderen Programmierern. Hier ein kleiner Bug report aus 
dem DE-GENERATOR.

Bild1+2: Bug-Report DE-GENERATOR

Gruß Rolf

von Rolf D. (rolfdegen)



Lesenswert?

Hallöchen..

Ein kleiner Bericht woran ich am "DE-GENERATOR" zur Zeit noch arbeite 
bzw gearbeitet habe:

- Fehler in der Encoder-Routine beseitigt. Fehler verursachte 
Software-Abstürzen im Oszillator Menü.
- Fehler bei der Editierung von Parametern im Oszillator Menü beseitigt.
- Notenhänger im Envelope Menü beseitigt. Globale Variablen ersetzt 
durch static Variablen in Real-Env Routine.
- Audioausgänge im SMR4 Filter sind vertauscht (Links & Rechts). Lösung: 
DAC Ausgänge in der Software getauscht.
- Fehler bei der Editierung von Parametern in der Modulationsmatrix 
beseitigt.
- Modulationsfehler wenn LFO den VCA moduliert beseitigt. Ursache: Es 
wurden falsche Incrementwerte berechnet. Incrementwerte werden jetzt aus 
einer Log. Tabelle geladen
- Noise (rosa Rauschen bis 20KHz) im Osc funktioniert wieder
- Änderung im LFO Menü: jetzt 17 Wellenformen + S&H. Die Sync und 
OneShot Funktion ist jetzt im LFO Mainmenü einstellbar.
- LFO Frequenz von 0.015 Hz bis 120 Hz einstellbar.
- VCA Pan & Fx Pan in Modulationsmatrix aktiviert.
- Key Track Funktion im OSC Menü implementiert. Feste Note (A6 ~ 440Hz) 
kann mit Range Parameter in Halbtöne von +12 bis -36 geändert werden.

Bild1: Neues LFO Menü
Bild2: Oszillator Menü
Ein kleiner Fehler im Bild2: Range ist +24 bis -36

Das Oszillator Menü hat einen zusätzliche Funktion erhalten (siehe 
Bild). Es handelt sich um eine
Key Track Funktion. Ist die "Ktrack" Funktion eingeschaltet, dann 
verändert sich die Tonhöhe des
Oszillators wie gewohnt über die Tastatur. Ist Ktrack ausgeschaltet, 
kann der Oszillator auf eine
bestimmte Note A (~ 440 Hz) fixiert werden. Mit dem "Range" Regler kann 
dieser Notewert in
einem Bereich von +24 bis -36 Semitones geändert werden.

Hierzu ein kleines Klangbeispiel vom DE-GENERATOR: 
https://soundcloud.com/rolfdegen/key-track-example-from-de-generator

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Woran ich zur Zeit arbeite..

an einer neuen Sequencer- und Arpeggiator-Funktion im DEGENERATOR. Das 
alte Sequencer
Menü sah zwar schick aus, hatte aber eine schlechte Einteilung für die 
Stepps und keine Arpeggiator-
Funktion. Aus diesem Grund habe ich das ganze Menü noch einmal neu 
gestaltet. Alle Funktionen
finden jetzt auf einer Menüseite ihren Platz und die 16 Stepps sind in 
zwei Gruppen zu jeweils 8
Stepps im oberen Teil des Bildschirms aufgeteilt. Mit "Mode" kann 
zwischen Sequencer und
Arpeggiator umgeschaltet werden. Mit "BPM" (Beats per Minute) kann die 
Taktgeschwindigkeit von
1- 250 verändert werden. Mit "Note" kann die Notenlänge von 1/2 bis 1/16 
eingestellt werden. Mit
"DIR" die Spielrichtung. Die Menüseite ist noch nicht fertig. Weitere 
Parameter werden folgen.

Bild1: Neues Sequencer-ArpeggiatorMenü
Bild2: Altes Sequencer Menü

Ein kleiner Arpeggio Test mit dem DEGENERATOR und Shruthi Synthesizer im 
Duett. Viel Spaß beim anhören: 
https://soundcloud.com/rolfdegen/shruthidegeneratorinarp2

Gruß Rolf

von Ulrich B. (ulrich_b665)


Lesenswert?

Hallo Rolf,

ich bin gerade bei den Vorüberlegungen für einen DIY-Midicontroller und 
suche dafür gute Drehencoder. Welche verwendest du denn in deinem Synth?

Danke & Grüße,
Ulrich

von Rolf D. (rolfdegen)


Lesenswert?


von Ulrich B. (ulrich_b665)


Lesenswert?

Danke Rolf, die werde ich mir mal ansehen.

:) Ulrich

Beitrag #4974510 wurde vom Autor gelöscht.
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallöchen..

Es tut mir leid wenn ich zur Zeit wenig schreibe. Aber wir stecken
mitten in der Vorbereitung für die Superbooth Messe in Berlin. Andre hat
für unseren
Prototyp auf die Schnelle ein Gehäuse aus Plexiglas und Holzseitenteilen
gebaut. Es ist noch nicht ganz fertig, aber sieht doch schon gut aus wie
ich finde.

Bild 1+2: Das DE-GENERATOR Gehäuse


Zur Superbooth:
Die Superbooth 17 findet vom 20 - 22.April in Berlin im FEZ (Kinder-,
Jugend- und Familienzentrum) statt. Insgesammt 167 Aussteller sollen
dort sein. Hab mal gekuckt wer da noch so da ist zB die Firma Kurzweil,
Yamaha, Steinberg, Nativ Instruments, Roland, Moog Music, Ableton,
Doepfer uvm
Wer uns besuchen möchte findet uns am Stand 0503 von Sonic Potions im
2.OG (siehe 3.Bild gelber Pfeil).

Bild 3: Unser Stand in der Superbooth 17

: Bearbeitet durch User
von J. S. (engineer) Benutzerseite


Lesenswert?

Modernes Weiss-Blau gepaart mit Holzverkleidung wie beim Virus. Sieht 
nicht schlecht aus. :-)

Würde Ich mir schon mal ansehen, aber nach Berlin komme Ich momentan 
nicht.

Geht der auch in den Verkauf?

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Danke. Ja.. ist angedacht. Es gibt noch ein paar Bilder von Andre..

: Bearbeitet durch User
von min (Gast)


Lesenswert?

sieht gut aus!

von Rolf D. (rolfdegen)


Lesenswert?

Hallo liebe Freunde..

Zur Zeit arbeite ich am Code im DE-GENERATOR und versuche diesen etwas 
zu verkleinern. Der
Programmspeicher (Flash) im ATXmega128 hat eine maximale Größe von 128 
KByte. Meine Code-
Größe lag bei 110 KByte. Durch das Anlegen eines großen String-Arrays im 
Flash und das Ändern
von Optimierungs Flags von -OS (Standarteinstellung) auf -O1 in einigen 
Funktionen konnte ich
die Code-Größe von 110 KByte auf 99 KByte reduszieren.

String-Array im Flash
1
gui.c
2
//*************************************************************************
3
// string table
4
//*************************************************************************
5
const char string_000[] PROGMEM = "SOUND PATCHES";
6
const char string_001[] PROGMEM = "PATCH.NR";
7
const char string_002[] PROGMEM = "BANK";
8
const char string_003[] PROGMEM = "PAT:";
9
const char string_004[] PROGMEM = "BNK:";
10
const char string_005[] PROGMEM = "PRG:---";
11
const char string_006[] PROGMEM = "BNK:---";
12
const char string_007[] PROGMEM = "Shape";
13
const char string_008[] PROGMEM = "Prm.";
14
const char string_009[] PROGMEM = "Op.";
15
...
16
17
18
PGM_P const String_Tab[] PROGMEM = {
19
    
20
    string_000,
21
    string_001,
22
    string_002,
23
    string_003,
24
    string_004,
25
    string_005,
26
    string_006,
27
    string_007,
28
    string_008,
29
    string_009,
30
    ...
31
};
32
33
gui.h
34
// string tabel
35
extern PGM_P const String_Tab[];

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Leider ist mir am Wocheende ein kleines Missgeschick passiert. Ich habe 
von meinem Freund Andre
Laska aus Oer-Erkenschwick ein kleines Päckchen mit Bauteilen für einen 
dritten DE-GENERATOR
bekommen und bei der Post abgeholt. Unter anderem war auch ein neues 
TFT-Display für den
DE-GENERATOR enthalten, dass ich am Wochenende mal testen wollte. Beim 
Aussteigen aus dem Bus
habe ich das verdammte Päckchen dann auf meinem Sitzplatz liegen 
gelassen. Ein sofortiger Anruft
bei der hiesigen Bus-Leitzentrale informierte den Busfahrer, dass er auf 
der Rücktour nach dem
Päckchen ausschau halten sollte. Leider hat er nichts gefunden.

Werde am Montag dann mal zum Fundbüro fahren und nach dem Päckchen 
forschen. Aber vielleicht
hats ja jemand gefunden und baut sich jetzt einen singenden 
Weihnachtsbaum daraus  holy-willi

Bild 1+2: Neues TFT-Display (ER-TFTM032-3)

von Rolf D. (rolfdegen)



Lesenswert?

Habs Päckchen im Fundbüro abhohlen könne. War noch alles drin. Echt 
nette Fahrgäste in Wuppertal  ebueb


Ach herrje..

Ich tüfftel jetzt schon seit einige Stunden an einer Anpassung für das 
neue Display am DE-GENERATOR herrum. Leider musste ich nach geraumer 
Zeit feststellen, dass das neue TFT Display defekt ist. Beim Zeichnen 
einer Linie wird nur an jeder geraden XY-Koordinate ein Pixel gesetzt. 
Bei ungeraden Koordinaten werden die Pixel an ganz anderen Stellen zB am 
Displayrand gesetzt  verwirrt (Bild2).

Da die Initialisierung des Display richtig funktioniert, ist ein Defekt 
am Datenbus oder ein Übertragungsfehler ausgeschlossen. Auch 
Softwareseitig scheint alles ok zu sein. Beim initialisieren ist 
allerdings ein Streifenmuster auf dem Display zu erkennen (Bild 1).

Bild 1: Streifenmuster nach der Initialiesierung des Displays
Bild 2: Nur gerade Pixeladressen werden richtig gezeichnet

Display Initialisierung
1
void init_LCD(void)
2
{
3
    
4
// init ILI9341 TFT Controller --------------------------------------------
5
    // set LCD Reset and CS
6
    SET_RESET;
7
    _delay_ms(10);
8
    CLR_RESET;
9
    _delay_ms(10);
10
    SET_RESET;
11
    CLR_CS;
12
    _delay_ms(10);
13
    
14
    // write command and data
15
    
16
    write_com(0xCB);  //Power control A
17
    write_data(0x39); 
18
    write_data(0x2C); 
19
    write_data(0x00); 
20
    write_data(0x34); 
21
    write_data(0x02); 
22
23
    write_com(0xCF);  //Power control B
24
    write_data(0x00); 
25
    write_data(0XC1); 
26
    write_data(0X30); 
27
28
    write_com(0xE8);  //Driver timing control A
29
    write_data(0x85); 
30
    write_data(0x00); 
31
    write_data(0x78); 
32
33
    write_com(0xEA);  //Driver timing control B
34
    write_data(0x00); 
35
    write_data(0x00); 
36
 
37
    write_com(0xED);  //Power on sequence control
38
    write_data(0x64); 
39
    write_data(0x03); 
40
    write_data(0X12); 
41
    write_data(0X81); 
42
 
43
    write_com(0xC0);    //Power control 
44
    write_data(0x23);   //VRH[5:0] 
45
 
46
    write_com(0xC1);    //Power control 
47
    write_data(0x10);   //SAP[2:0];BT[3:0] 
48
49
    write_com(0xC5);    //VCM control 
50
    write_data(0xF0);   //Contrast
51
    write_data(0xF0); 
52
    
53
 
54
    write_com(0xC7);    //VCM control2 
55
    write_data(0x86);   //--
56
 
57
    write_com(0x36);    // Memory Access Control 
58
    write_data(0x48);   
59
60
    write_com(0x3A);    // Pixel format   
61
    write_data(0x55); 
62
63
    write_com(0xB1);    // Frame Rate Control (In Normal Mode/Full Colors)
64
    write_data(0x00);  
65
    write_data(0x18); 
66
 
67
    write_com(0xB6);    // Display Function Control 
68
    write_data(0x08); 
69
    write_data(0x82);
70
    write_data(0x27);  
71
72
    write_com(0x11);    //Exit Sleep 
73
    _delay_ms(130); 
74
                
75
    write_com(0x29);    //Display on
76
}

Hab jetzt an den Lieferanten BuyDisplay.com geschrieben und ein neues 
Muster angefordert. Mal schaun ob es dann funktioniert.

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo liebe Freunde..

Mit viel Geduld und Mühe ist es mir gelungen das Display doch noch zu 
einer richtigen Anzeige von Linien und Texten zu bewegen. Ursache war 
eine falsche Adressierung der Pixel Koordinaten in den entsprechenden 
Registern des ILI9341 Controllers.

Adressierung der XY Koordinaten
1
//*************************************************************************
2
// set  xy for TFT (ILI9341 or SSD1289)
3
//*************************************************************************
4
void TFT_set_xy(uint16_t x1, uint8_t y1, uint16_t x2, uint8_t y2)
5
{
6
    
7
    // SSD1289 ------------------------------------------------------------
8
    TFT_write_com_data(0x44,(y2 << 8) + y1);
9
    TFT_write_com_data(0x45,x1);
10
    TFT_write_com_data(0x46,x2);
11
    TFT_write_com_data(0x4e,y1);
12
    TFT_write_com_data(0x4f,x1);
13
    TFT_write_com(0x22);
14
    
15
16
    //  ILI9341 -----------------------------------------------------------
17
    TFT_write_com(0x2a);
18
    TFT_write_data(x1);
19
    TFT_write_data(x2);
20
    TFT_write_com(0x2b);
21
    TFT_write_data(y1);
22
    TFT_write_data(y2);
23
    TFT_write_com(0x2c);    
24
}
25
26
//*************************************************************************
27
// write command and data (SSD1289)
28
//*************************************************************************
29
void TFT_write_com_data(uint8_t addr, uint16_t num)
30
{
31
    // set Com-Register
32
    LCD_CLR_RS;
33
    // write Addr-Register
34
    VPORT0.OUT = addr;
35
    // WR-Puls
36
    CLR_WR;
37
    SET_WR;
38
39
    // Set Data-Register
40
    LCD_SET_RS;
41
    // send 16Bit Data
42
    VPORT0.OUT = num >> 8;
43
    SET_LE;
44
    CLR_LE;
45
    VPORT0.OUT = num;
46
    // WR-Puls
47
    CLR_WR;
48
    SET_WR;
49
}
50
51
52
//*************************************************************************
53
// write command TFT
54
//*************************************************************************
55
void TFT_write_com(uint8_t data)
56
{
57
    // set Com-Register
58
    LCD_CLR_RS;
59
    // write Addr-Register
60
    VPORT0.OUT = data;
61
    CLR_WR;
62
    SET_WR;
63
}
64
65
//*************************************************************************
66
// write 16 Bit Data TFT
67
//*************************************************************************
68
void TFT_write_data(uint16_t data)
69
{
70
    // set Data-Register
71
    LCD_SET_RS;
72
    // set high Byte to LCD Port
73
    VPORT0.OUT = data >> 8;
74
    SET_LE;
75
    CLR_LE;
76
    
77
    // set low byte to LCD Port
78
    VPORT0.OUT = data;
79
    // wr-puls
80
    CLR_WR;
81
    SET_WR;
82
}

Bild 1: Menüseite auf neuem TFT Display
Großes Bild: 
https://plus.google.com/photos/photo/114442997071623735927/6422198826292846738?icm=false&authkey=CL6X6ovG7fix7gE&hl=de

Gruß Rolf

: Bearbeitet durch User
von Rolf D. (rolfdegen)


Lesenswert?

Die Bug-Liste vom DE-GENERATOR

Software Versionen DE-GENERATOR
Version Datum Änderung

Vers. 3.001 05.01.17
- Fehler bei der Encoder-Entprellung beseitigt

Vers. 3.002 09.01.17
- Fehler bei der AD-Wandlung (Sampling) beseitigt
- Zoom-Funktion im Sample-Editor implementiert (noch nicht fertig)

Vers. 3.004 12.01.2017
- Encoder Dynamic (Beschleunigung) in Systempage einstellbar

Vers. 3.006 21.01.2017
- Im Sample Editor kann man jetzt Loop-Punkte setzen. Werden aber z.Z. 
noch nicht im Sample gespeichert. Ferner kann man einen markierten 
Bereich löschen, Stille einführen oder revers machen. Sample-Files 
können jetzt gezoom werden. Bei hohen Zoom-Werten funktioniert die 
Darstellung des markierten Bereichs noch nicht.
- Threshold funktioniert jetzt ohne Fehler.
- Fehler beim Abspeichern von aufgenommenen Samples beseitigt

Vers. 3.007 22.01.2017
- lineare Attack-Phase

Vers. 3.008 29.01.2017
- Systemabsturz in Monitorfunktion im Sample Editor beseitigt
- es können jetzt Loop points in Wav-Files gespeichert und geladen 
werden
- Samples könne jetzt im Osc-Menü editiert werden (cut,silence,loop 
function)
- Osc werden jetzt über "Mode" im Osc Menü ausgeschaltet (Früher nur 
über Shape möglich)
- Auswahl von Filtertyp (DEG/SMR4) in Systempage möglich

Vers. 3.009 01.02.2017
- Fehler bei der Editierung von Loop-Punkten im Osc-Menü beseitigt
- Page Encoder im Sample-Edit Menü gesperrt. Man muss erst wieder zurück 
ins Main-Menü um Page Encoder zu entsperren
- Osc-Menü wird grau wenn Osc im Off Modus. Subpages sind im Off Modus 
gesperrt

Vers. 3.010 03.02.2017
- Fehler beim Laden und Speichern von Sample-Files im Oscillator 
beseitigt (Knackser)

Vers. 3.011 11.02.2013
- Dateizugriffsfehler bei der Bankauswahl von Waves und Samples 
beseitigt wenn Bank nicht existiert. Der Fehler verursachte das Löschen 
kompletter Ordnerinhalte. Jetzt wird eine Info "File not found" 
eingeblendet und der Dateizugriff ordnungsgemäß beendet.
- Für bessere Entprellung der Encoder wurde die Abtastgeschwindigkeit am 
74HC165 geändert. Von 1 msec auf 2 msec.
- Fehler beim Speichern von Samples beseitigt, wenn kein Ordner 
vorhanden ist. Es wird dann automatisch ein neuer Ordner erstellt.

Vers. 3.012 16.02.2017
- Änderung Filteransteuerung PB5 und PB6 sind im Schaltplan vertauscht

Vers. 3.013 21.02.2017
- Fehler in der Encoder-Routine beseitigt. Fehler verursachte 
Software-Abstürzen im Oszillator Menü.
- Fehler bei der Editierung von Parametern im Oszillator Menü beseitigt.
- Notenhänger im Envelope Menü beseitigt. Globale Variablen ersetzt 
durch static Variablen in Real-Env Routine.
- Audioausgänge im SMR4 Filter sind vertauscht (Links & Rechts). Lösung: 
DAC Ausgänge in der Software getauscht.
- Fehler bei der Editierung von Parametern in der Modulationsmatrix 
beseitigt.
- Modulationsfehler wenn LFO den VCA moduliert beseitigt. Ursache: Es 
wurden falsche Incrementwerte berechnet. Incrementwerte werden jetzt aus 
einer Log. Tabelle geladen
- Noise (rosa Rauschen bis 20KHz) im Osc funktioniert wieder
- Änderung im LFO Menü: jetzt 17 Wellenformen + S&H. Die Sync und 
OneShot Funktion ist jetzt im LFO Mainmenü einstellbar.
- LFO Frequenz von 0.015 Hz bis 120 Hz einstellbar.
- VCA Pan & Fx Pan in Modulationsmatrix aktiviert.
- Key Track Funktion im OSC Menü implementiert. Feste Note (A6 ~ 440Hz) 
kann mit Range Parameter in Halbtöne von +24 bis -36 geändert werden.
- init Preset implementiert. Ist der Systemparameter "Autoload" im 
Systemmenü auf off, dann wird nach einem Neustart ein init Preset 
geladen. Ist "Autoload" on, dann wird der zuletzt geladene Preset 
geladen.

Vers. 3.014
- Im Envelope Menü werden jetzt in der Headline die Modulationsziele 
angezeigt.
- Fehlerbeseitigung: Falsches Grafik Symbol für Wellenform oder Sample 
in der Patchliste.

Vers. 3.015 06.03.2017
- Fehler beim speichern von Ktrack Paramter im Patch beseitigt.
- Fine pich Paramter für beide Oscillatoren in der Modulationsmatrix 
ergänzt.

Vers. 3.016 06.03.2017
- Fehler in Modulationsmatrix beseitigt.

Vers. 3.017 07.03.2017
- Im Osc-Menü zusätzliche Shape Waveform "Nois" implementiert. Das 
Rauschspektrum kann für jeden Oszillator getrennt mit dem Prm. Regler 
von dunkel auf hell eingestellt werden.
- Modulationsmatrix: Sources: Offset hinzugefügt. Destinations: VCA-BAL 
, VCF-BAL und Fx-PAN hinzugefügt.

Vers. 3.018a 09.03.2017
- Vorabversion Sequencer/Arpeggiator Funktion

Vers. 3.018b 03.04.2017
- Arpeggiator: Octave Funktion hinzugefügt.

Build 3.19a 11.04.2017
- Arpeggiator: Range auf 4 Octave erweitert und Notenbegrenzung 
hinzugefügt
- Arpeggiator: Notenhänger beim ausschalten beseitigt
- Loop Fehler in Osc1&2 beseitigt

Build 3.20 15.04.2017
- Arpeggiator: Direction Fehler verursachte Systemabsturz. Läuft jetzt 
problemlos
- Fehler beim automatisches Anlegen von Preset und Sample Ordnern 
beseitigt
- und ein paar Kleinigkeiten

Build 3.20a 16.04.2017 -
Fehler bei der inversen Anzeige von Loop-Punkten im Editor beseitigt

Build 3.20b 16.04.2017
- Ein Fehler in der Speicherverwaltung der Samples beseitigt

Build 3.20c 16.04.2017
- Fehler in der Modulationmatrix. Slot Werte verändern sich willkürlich 
beim scrollen. Lag an doppelt Zuweisung von Enc.Values

Build 3.21 17.04.2017
- Fehler im Datei System: Alte Sample-Files und Data.bin Dateien wurden 
im Sound Ordner nicht gelöscht sondern nur überschrieben.
Das hat beim Abspeichern von neuen Presets manchmal mehrer Sekunden 
Wartezeit verursacht.


Build 3.22 17.04.2017
- Tasten- und Encoder Sperre bei verschiedenen Funktion nicht richtig

Build 3.23 18.04.2017
- Ordner Fehler beim Abspeichern von Samples beseitgt.

Build 3.27 30.04.2017
- Warnhinweise im Code in Atmel Studio 7 beseitigt (noch 556 
Warnhinweise vorhanden)
- Fehler beim laden von 1.Sample beim Umschalten auf andere Bank 
beseitigt

Build 3.27a 01.05.2017
- Warnhinweise im Code in Atmel Studio 7 beseitigt (noch ca. 90 
Warnhinweise vorhanden). Ursache für die meisten Warnungen war ein 
falsches setzen der Operanten in den static inline functionen. Die 
restlichen Warnungen beziehen sich auf falsche Übergabe von 
Namen-Strings an das Fat-Filesystem. Fat-Arbeitet mit uint8_t und nicht 
mit char.

Build 3.28 05.05.2017
- Große String Tabelle im Programmspeicher (Flash) angelegt. Spart Code 
im Flash und SRAM
- Optimierungseinstellung in ATMEl STUDIO 7 in oscillators.c und voice.c 
auf -O2 gesetzt. Rest ist -OS

Build 3.31 21.05.2017
- Display Treiber für ILI9341 und SSD1289 angepasst
- Save Dialog jetzt mit kleiner ASCII Tabelle für die Auswahl von 
Zeichen
- Einige Verbesserungen in der GUI
- Sample Editor: Nach der Editierung eines Sample wurde die 
Wellenformdarstellung im Osc-Menü nicht neu gezeichnet (redraw). Fehler 
beseitigt
- OscMix Value wurde beim Umschalten auf Osc-Page nicht aktualliesiert. 
Fehler beseitigt
- Wenn Shape nicht auf "USER" steht und es wird versucht auf die SubPage 
"User Waveform" zu schalten, dann erscheint ein Warnhinweis.
- LCD Flacker Problem beseitigt. Lösung: XY Register (0x44 - 0x46) 
müssen vor dem Setzen eines Pixel gelöscht werden.
- Jetzt nur noch 44 Warnhinweise in ATMEL Studio übrig. Die meisten 
stammen vom SD Karten Treiber



.. und noch kein Ende  Augenzwinkern

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Hallo liebe Freunde..

Andre und ich sind noch fleißig am arbeiten. Das neue TFT Display hat im 
Vergleich zum alten
Display leider keinen externen Anschluss für die 
LED-Hintergrundbeleuchtig. Diese ist über die
3.3Volt Versorgungsspannung auf dem Display fest verdrahtet. Dies führte 
aber zu einer höheren
Belastung des 7805 Festspannungsregler auf dem Motherboard und zu höhren 
Temperaturen im
Gerät (> 64C). Der Kühlkörper des 7805 war im geschlossenen Gehäuse am 
kochen. Aus diesem
Grund haben wird den 7805 durch einen Schaltregler ersetzt.

Wir haben einen DCDC-Konverter TRACO TSR 1-2450 verwendet. Er ist nicht 
billig, hat aber einen
hohen Wirkungsgrad von 94%. Die Schaltfrequenz des Konverter liegt bei 
500KHz. Ein integrierter
Filter sorgt für einen niedrigen Ausgangsrippel und Noise von 50mVp-p. 
Der max. Ausgangsstrom
liegt bei 1A.

Günstiger ist der R-78W5.0-0.5 von RECOM. Die Effizienz und 
Ausgangsrippel ist fast gleich.
Allerdings ist die Schaltfrequenz im Vergleich zum Traco Regler etwas 
niedriger und liegt bei
330KHz. Der max. Ausgangsstrom ist 500mA.

In meiner Grabbelkiste hatte ich noch einen Traco TSR 1-2450 rumliegen 
den ich sofort in den DE-
ENERATOR gelötet habe. Die Gehäusetemperatur lag jetzt unter 30C. Ripple 
und Noise am Audio-
ausgang betrug weniger als 5mVp-p. Da der Traco Regler nicht ganz billig 
ist ( ca. 4,42 bei Völkner)
werden wir den etwas günstigen Regler von RECOM mal antesten.


Bild 1: Motherboard mit Traco TSR 1-2450 DCDC Konverter
Bild 2: Ripple und Noise am Audioausgang mit Traco TSR 1-2450

Gruß Rolf

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Temperaturmessung mit ATxmega

Hallöchen. Im DE-GENERATOR werkelt bekanntlich ein ATxmega128A1AU 
(ältere Version) bzw ein
ATxmega128A1U (neuere Version). Beide Prozessoren besitzen von Hause aus 
einen internen
Temperatur Sensor. Dieser Sensor kann über die ADC Register im ATxmega 
ausgelesen werden.
Das habe ich mir zu nutze gemacht, um festzustellen, wie hoch die 
ungefähre Gehäuseinnen-
temperatur im DE-GENERATOR ist. Nach ein paar "komplizierten" 
Berechnungen wird die Tempe-
ratur im Systemmenü in Grad Celsius angezeigt.

Bild 1: Systemmenü & ATxmega CPU auf dem CPU Board

Code Beispiel im DE-GENERATOR
1
//*************************************************************************
2
// init temperature sensor in CPU
3
//*************************************************************************
4
void init_temp_sensor(void)
5
{
6
    // init ADC for CPU temperature measurement ---------------------------
7
    ADCA.CTRLB = ADC_CONMODE_bm | ADC_RESOLUTION_12BIT_gc | ADC_FREERUN_bm;
8
    ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_TEMPREF_bm;
9
    ADCA.EVCTRL = ADC_SWEEP_0_gc;
10
    ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc;
11
    ADCA.CAL = ADCon.temp_calval;
12
    ADCA.CH0.CTRL = ADC_CH_GAIN_1X_gc | ADC_CH_INPUTMODE_INTERNAL_gc;
13
    ADCA.CH0.MUXCTRL = ADC_CH_MUXINT_TEMP_gc;
14
    ADCA.CTRLA = ADC_ENABLE_bm;
15
    ADCA.CH0.CTRL = ADC_CH_START_bm;
16
}
17
18
//*************************************************************************
19
// read adc calibrate values
20
//*************************************************************************
21
void read_ADC_calval(void)
22
{
23
    #define ADCACAL0_offset 0x20  // read ADC Calibration Byte 0
24
    #define ADCACAL1_offset 0x21  // read ADC Calibration Byte 1
25
    
26
    #define TempCAL0_offset 0x2E  // read Temp.Sensor Calibration Byte 0
27
    #define TempCAL1_offset 0x2F  // read Temp.Sensor Calibration Byte 1
28
29
    uint8_t cal_l = read_calibration_byte(PROD_SIGNATURES_START+ADCACAL0_offset);
30
    uint8_t cal_h = read_calibration_byte(PROD_SIGNATURES_START+ADCACAL1_offset);
31
    ADCon.calval = (cal_h << 8) | cal_l;
32
    
33
    cal_l = read_calibration_byte(PROD_SIGNATURES_START+TempCAL0_offset);
34
    cal_h = read_calibration_byte(PROD_SIGNATURES_START+TempCAL1_offset);
35
    ADCon.temp_calval = (cal_h << 8) | cal_l;
36
}
37
uint8_t read_calibration_byte( uint8_t index )
38
{
39
    uint8_t result;
40
41
    /* Load the NVM Command register to read the calibration row. */
42
    NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
43
    result = pgm_read_byte(index);
44
45
    /* Clean up NVM Command register. */
46
    NVM_CMD = NVM_CMD_NO_OPERATION_gc;
47
48
    return( result );
49
}
50
51
//*********************************************************************
52
// read case temperature
53
//*********************************************************************
54
uint8_t read_temperature(void)
55
{
56
    uint8_t temp_offset = 18; // CPU temperature offset
57
    uint16_t result_ = ADCA.CH0RES;
58
    uint16_t calval_ = (uint32_t)(ADCon.temp_calval-200)*2048/(4096-200);
59
    uint8_t temperature = (((uint32_t)358*result_)/calval_) - (273+temp_offset);
60
    
61
    return ( temperature);
62
}

Am Anfang wird der ADC initialisiert und die Calibration Bytes für den 
Temperatur Sensor gesetzt.
Danach folgt die Abfrage der 12Bit breiten Sensor Daten im ADC Daten 
Register und die Um-
rechnung in Grad Celsius. Da der Prozessor eigentlich nur seine Kern 
Temperatur misst, habe ich
bei meiner Berechnung einen Offset-Wert mit berücksichtigt um dann die 
ungefähre Gehäuse-temperatur zu berechnen. Man oder frau sollte 
beachten, dass der erste Temperaturwert nach
dem Start des ADC kein gültiger Messwert ist und in den Mülleimer gehört 
Augenzwinkern

Gruß Rolf

von Audiomann (Gast)


Lesenswert?

Welche Bedeutung hat die Temperatur im Bezug auf die Audioerzeugung? 
Oder sollte der thread woanders hin?

von Rolf D. (rolfdegen)


Lesenswert?

Danke für deine Frage. Aber die Temperaturanzeige ist Bestandteil der 
Software im Synthesizer. In meinem Synthesizer Projekt behandel ich ja 
alle Themen rund um die Elektronik und Softwareentwicklung. Ich finde so 
Rand-Themen sind da eine gute Abwechslung und machen den Blog sehr 
interessant.

Gruß Rolf

von H-G S. (haenschen)


Lesenswert?

Ich habe letztens DEN Tiefton-Sound schlechthin gehört  :-)
Von einer kleinen fahrenden Kehrmaschiene, die draussen die Strassen 
kehrt.


Der Ton bestand aus zwei gleichzeitigen "Brummgeräuschen", ähnlich wie 
Flügelschlagen einer riesigen Hummel oder sowas. Die zwei 
Flattergeräusche waren verschieden und resonierten irgendwie fantastisch 
im Körper und erzeugten Euphorie ...

von Rolf D. (rolfdegen)


Lesenswert?

Es ist schon sehr interessant in was für einem Klangkosmos wir leben. 
Man muss nur die Ohren spitzen ;)

von Rolf D. (rolfdegen)


Angehängte Dateien:

Lesenswert?

Der Synthesizer "Degenerator" ist fertig und wird offizell  als Bausatz 
auf tubeohm.com verkauft.

Hier mein "Degenerator" Block: 
https://www.sequencer.de/synthesizer/threads/avr-synthesizer-wave-1-de-generator.87599/page-19

Mein aktuelles Projekt ist ein Modularer Synthesizer 
https://www.sequencer.de/synthesizer/threads/memodular-modularer-diy-synth.148901/

Gruß Rolf

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.