mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP TI DSP wert kopieren


Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich weiß hört sich ebscheuert an aber wie kann ich einen Wert in c 
kopieren? Ich habe einen Uint32 mit daten vom audio codec wenn ich den 
wieder ausgebe funktioniert alles wunderbar und ich höre das signal, 
aber wenn ich das ganze in einen 2. Uint32 kopieren will (output = 
sample) und dann output ausgebe kommt auf einmal kein Ton mehr aus dem 
Lautsprecher,
wenn ich allerdings sample = sample *2 o.ä. mache gibts keine probleme.
Ich werd langsam noch wahnsinnig mit den Dingern.
Kennt jemand noch eine 2. möglichkeit einen Uint32 zu kopieren?

Autor: jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte schon den Effekt, daß der CCS-Compiler mir Variablen 
wegoptimiert hat, weil er der Meinung war, daß die nicht gebraucht 
werden.
Abhilfe: Variable als "volatile" deklarieren. Vielleicht hilft Dir das 
weiter.

Hast Du Dein DSK-Treiberproblem eigentlich gelöst?

Gruß, Jan

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abend,
Danke für die Hilfe jezt funtkioniert es, und nein ich habe mein 
Treiberproblem nicht gelöst ich bin wieder auf CCS 3.1 umgestiegen.

Ich stehe aber leider schon vor dem nächsten problem:
Ich habe probeweise einen Ringpuffer den mir jemand aus dem Board 
geschrieben hat in den Code eingebaut, das einzige Problem ist das das 
Signal geclippt und mit vielen Störgeräuschen wieder herauskommt
#include "dsk6416.h"
#include "dsk6416_aic23.h"


/* Codec configuration settings */
DSK6416_AIC23_Config config = {
    0x009F, // 0 DSK6416_AIC23_LEFTINVOL  Left line input channel volume
    0x009F, // 1 DSK6416_AIC23_RIGHTINVOL Right line input channel volume
    0x00d8, // 2 DSK6416_AIC23_LEFTHPVOL  Left channel headphone volume
    0x00d8, // 3 DSK6416_AIC23_RIGHTHPVOL Right channel headphone volume
    0x0075, // 4 DSK6416_AIC23_ANAPATH    Analog audio path control
    0x0000, // 5 DSK6416_AIC23_DIGPATH    Digital audio path control
    0x0000, // 6 DSK6416_AIC23_POWERDOWN  Power down control
    0x0043, // 7 DSK6416_AIC23_DIGIF      Digital audio interface format
    DSK6416_AIC23_FREQ_8KHZ, // 8 DSK6416_AIC23_SAMPLERATE Sample rate control
    0x0001  // 9 DSK6416_AIC23_DIGACT     Digital interface activation
};
Uint32 sample;
volatile Uint32 delay[8000];
volatile int i = 0;
volatile Uint32 output;
volatile int x = 0;
volatile int writepos = 0;
volatile int readpos = 0;

void main()
{
    DSK6416_AIC23_CodecHandle hCodec;



  


    /* Initialize the board support library, must be called first */
    DSK6416_init();
     
    /* Start the codec */
    hCodec = DSK6416_AIC23_openCodec(0, &config);

  for (i=0; i<8000; i++)
  {
     delay[i] = 0;
  }

  
  for(;;){
  while(!DSK6416_AIC23_read(hCodec, &sample));

  if(sample <= 1000)
  {
  sample = 0;
  }


  delay[writepos++] = sample;
  if (writepos >= 8000)
       writepos = 0;

  readpos = writepos - 1 - 7000;
  if (readpos < 0)
       readpos += 8000;

  sample = (sample + delay[readpos] + 1)/2;





     while(!DSK6416_AIC23_write(hCodec,sample));
  }
}
Wo steckt hier der Fehler? Ich stehe da gerade komplett aufm Schlauch 
weil ich den logik fehler nicht entdecke.

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas,

das folgende erzeugt wohl die Störungen:
  if(sample <= 1000)
  {
  sample = 0;
  }
Das sorgt ja dafür, dass das Signal, wenn es kleiner als 1000 ist, hart 
auf 0 gesetzt wird. Dieser Sprung hat erhebliche hochfrequente Anteile, 
die das Signal sehr unschön klingen lassen.

Und eine Delayschleife programmiert man besser anders:
volatile Uint32 delay[8000];
volatile int pos=0;

for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &sample));

  delay[pos] = sample;
  pos++;
  if (pos = 8000) pos = 0;

  sample = (sample + delay[pos])/2;    //wofür war das +1 da drin??? Das würde Gleichspannung erzeugen!
  while(!DSK6416_AIC23_write(hCodec,sample)); 
}
Ich hoffe, das funktioniert so, ich habs nicht ausprobiert...
Ob es richtig ist, dass die samples unsigned sind, weiß ich nicht 
(Uint32 delay...).

Viele Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,
Leider funktioniert dein Vorschlag auch nicht ich erhalte am Ausgang 
immer noch ein stark geclipptes Signal mit vielen Störgeräuschen, Habe 
auch schon den Input um 20db veringert das Ausgangssignal bleibt das 
selbe nur in leiser. Ich erhalte am Ausgang aber auch kein delay nur das 
Eingangssignal.

Autor: Peter Diener (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schaut es denn mit der Signalqualität aus, wenn du den ganzen 
Delayzauber weg lässt, also nur
for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &sample));
  while(!DSK6416_AIC23_write(hCodec,sample)); 
}

Und dann habe ich immer noch Bedenken, ob das Uint32 wirklich richtig 
ist. Und wenn, dann setze es doch auch mal volatile.

Peter

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist noch etwas aufgefallen.
Versuch doch mal an der Eingangs und Ausgangsverstärkung zu drehen, 
vielleicht clippt ja der Vorverstärker:
DSK6416_AIC23_Config config = {
    0x009F, // 0 DSK6416_AIC23_LEFTINVOL  Left line input channel volume
    0x009F, // 1 DSK6416_AIC23_RIGHTINVOL Right line input channel volume
    0x00d8, // 2 DSK6416_AIC23_LEFTHPVOL  Left channel headphone volume
    0x00d8, // 3 DSK6416_AIC23_RIGHTHPVOL Right channel headphone volume

Schreib doch mal irgendwas kleineres in die Volumeregister rein.
z.B.
0x000F,
0x000F
0x0008,
0x0008,

Viele Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das ganze ohne delay mache kommt ein schönes Signal dabei raus, 
das ich noch um das 10 fache verstärken kann bis es anfängt zu clippen 
daran liegt es meiner meinung nicht und ich habe die Vorverstärkung 
schon auf fast 0 zurückgedreht.

Das Uint32 ist der einzige Datentyp der geht da die read und write 
Methoden ihn benötigen und auch im mitgelieferten Beispielprogramm wird 
Uint32 verwendet

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann würde ich folgenden Code ausprobieren:
for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &delay[pos]));
  pos++;
  if (pos = 8000) pos = 0;
  while(!DSK6416_AIC23_write(hCodec,delay[pos])); 
}

Das sollte eine einfache Verzögerung sein, jetzt ist die Variable sample 
nicht mehr im Spiel und es gibt keine Kopiervorgänge mehr, von denen man 
nicht genau weiß, ob sie funktionieren. Das eingespiele Signal muss 
damit einfach unverändert, aber 8000 samples später wieder ausgespielt 
werden.

Wenn das nicht geht, würde ich versuchen, die 8000 weniger zu machen, 
sagen wir z.B. mal auf 20. Vielleicht ist es ein Problem der 
Speicherverwaltung.

Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,
Danke, dein Code aus dem lezten Beitrag funktioniert wunderbar ich 
bekomme das Signal ohne Störgeräusche vcerzögert wieder aus dem output, 
sobald ich aber versuche das Eingangssignal dazuzumischen kommt wieder 
kein gescheiter Ton heraus und auch die Verzögerung ist nicht mehr 
hörbar.
Kann es unter Umständen daran liegen das es sich um einen Festkomma DSP 
handelt?
Gruß
Andreas

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also funktioniert offenbar die Addition von den Uint32 Werten nicht wie 
sie soll. Vielleicht kannst du die Funktion DSK6416_AIC23_write finden 
und dort nachschauen, wie die Darstellung der samples in dem Uint32 
Format funktioniert und damit darauf schließen, warum die Addition nicht 
geht. Gibt es bei diesem Board kein Beispiel, wie man samples korrekt 
addiert?

Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider gibt es dazu kein Beispiel sonst hätte ich dieses schon längst 
umgesezt, es gibt zum write befehl folgendes Beispiel:
Uint32 data;data = 0x12345678;
// Write 0x12345678 to the codec, loop to retry if data port is busywhile
(!DSK6416_AIC23_write(hCodec, data));
Aus der BSL habe ich erfahren das alles durch eine Datenleitung 
geschoben wird und danach erst mal 10 nops kommen.
Habe den Tipp bekommen das es u.u an der Geschwindigkeit liegen könnte 
aber mir ist nicht ganz klar wie ich das ändern könnte
Gruß
Andreas

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist ein Stereocodec, oder? Ich kann mir nämlich irgendwie immer noch 
nicht vorstellen, dass ein Audiosample 32 bit benötigen soll und 
vorallem unsigned ist. Kann es sein, dass in der Uint32 Variable zwei 
samples mit 16 bit sind, nämlich der linke und der rechte Kanal? Dann 
macht eine Addition ein Problem, weil der eine Kanal beim Überlauf der 
16 bit in den anderen überspricht.

Gibt es eine Doku zum config Eintrag
0x0043, // 7 DSK6416_AIC23_DIGIF      Digital audio interface format
?

Vielleicht solltest du einfach mal probieren, das Uint32 als zwei 
Stereosamples aufzufassen, also etwa so verarbeiten:
Uint16 left, right;
Uint32 sample;
for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &sample));
  left  = (sample & 0x00FF);
  right = ((sample & 0xFF00) >> 16);

  sample  = right;
  sample |= (left << 16);

  while(!DSK6416_AIC23_write(hCodec,sample)); 
}

Wenn meine Vermutung stimmt, müsste mein code den linken und rechten 
Kanal vertauschen, also das was links rein kommt, kommt rechts wieder 
raus und mit rechts entsprechend andersrum.


Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,
ein stereo codecd ist es wirklich, aber leider funktioniert dein 
Vorschlag nicht, wenn ich den Code so übernehme geht leider gar nichts, 
der codec gibt nur das eingangssignal aus (was er normalerweise nur tut 
wenn der dsp nicht läuft), wenn ich sample verstärke höre ich im 
Hintergrund ein Rauschen => mit dem Veränderten Signal von sample kann 
er nichts mehr Anfangen. Wenn ich die beiden int werte vertausche geht 
es natürlich.

jop zu dem entsprechenden register gibt es eine Doku
http://img510.imageshack.us/img510/3024/dokuap7.jpg

danke für dein Engagement
Gruß
Andreas

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also,
0x0043, // 7 DSK6416_AIC23_DIGIF      Digital audio interface format
das stellt 16 bit Auflösung je sample ein.
Man kann bis zu 32 bit einstellen, also ist es wohl wahrscheinlich, dass 
die sample Variable doch nur ein Sample von einem Kanal enthält und die 
oberen 16 bit einfach Null sind. Aber wo ist eigentlich eingestellt, ob 
der linke oder der rechte Kanal gesampled wird, das ist mir noch 
überhaupt nicht klar, außerdem verwirrt es mich, dass eine einfache 
Addition von Integern nicht den gewünschten Effekt hat. Du hast 
geschrieben, dass du sample verstärken kannst, bedeutet das, dass eine 
Multiplikation mit einer Konstanten funktioniert?

DSK6416_AIC23_openCodec(0, &config);
Wofür steht hier eigentlich die 0 drin?

Wie kommt man dan den anderen Kanal (es soll ja stereo sein)?

Ich habe ein C6713 DSK von Spectrum Digital, bin aber noch nicht dazu 
gekommen, damit etwas auszuprobieren. Ich werde mal nachschauen, wie das 
dort gelöst wird.

Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,
Die 0 bei openCodec steht für die id des Codecs auf dem Board das mit 
der 0 ist also korrekt.

Ob ich samples vom linken, rechten oder von beiden Kanälen bekomme weiß 
ich selber nicht aber da ich momentan mit einem Mono Input arbeite macht 
das im Moment keinen Unterschied. Ich habe mir alle Register des Codecs 
angeschaut aber in keinem Infos darüber gefunden wie man den Kanal 
umschalten kann.

Das sample kann ich mit einer beliebigen Konstante oder mit sich selbst 
multiplizieren um es zu verstärken das funktioniert Problemlos.

Ich habe noch eine seltsame Erfahrung betreffs dem delay heute gemacht:
sinngemäß sah es etwa so aus (hab die Sachen gerade nicht hier):
for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &sample));
  for(i = 0 i<= 7999; i++)
  {
   delay[i+1] = delay[i];
  }
  delay[0] = sample;
  sample = (sample + delay[8000])/2;
 
  while(!DSK6416_AIC23_write(hCodec,sample)); 
}
Mit einem Code dieser Art ist das Signal nicht ganz so stark geclippt 
und auch die Störgeräusche waren weniger Intensiv dafür hat der delay im 
Gegensatz zu allen bisherigen Versuchen funktioniert sprich ich habe das 
Eingegebene Signal gehört (immer noch geclippt aber nicht mehr so stark 
und mit weniger Störgeräuschen) und das ganze 1s später nochmal.
Warum das besser geht als deine Lösung kann ich mir auch nicht erklären 
ich weiß nur das meine länger dauert also eigentlich schlechter ist, ich 
werde morgen wenn ich wieder am Board sitze noch einen nop befehl in der 
Schleife platzieren und schauen ob das etwas ändert.
Gruß
Andreas

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code aus meinem lezten Beitrag stimmt natürlich nicht ich war nicht 
so ganz fit als ich das ganze geschrieben habe muss antürlich so 
aussehen:
for (;;)
{
  while(!DSK6416_AIC23_read(hCodec, &sample));
  delay[7999] = sample
  for(i = 1 i<= 7999; i++)
  {
   delay[i-1] = delay[i];
  }
  sample+= delay[0];
 
  while(!DSK6416_AIC23_write(hCodec,sample)); 
}

Ich habe noch ein wenig mit dem Code experimentiert aber keine 
Verbesserungen erzielen können, merkwürdig ist jedoch das sobald ich das 
sample += delay[0] durch sample = (sample + delay[0]) ersetze nur noch 
sehr laute Störgeräusche aus dem Lautsprecher kommen, bei dem 
momenatanen Code ist das einzige problem das das Signal immer noch 
clippt, aber an der Lautsärke liegt es nicht.

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die beiden Zeilen liefern also unterschiedliche Ergebnisse?!
sample += delay[0]
sample = (sample + delay[0])

Dann würde ich mal gerne den Assemblercode sehen, den der Compiler 
daraus erzeugt. Entweder der baut da gewaltigen Unsinn, oder es ist so 
eine Sache mit Interrupts, die Register von einem Hardwareaddierer 
verändern, während dieser gerade die Addition bearbeitet. Versuch doch 
mal vor der nicht funktionierenden Addition alle Interrupts zu sperren 
und danach wieder freizugeben.

Grüße,

Peter

Autor: Andreas S. (nightmarevs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag,
Bei meinem lezten Beitrag habe ich mich leider ein wenig vertippt, ich 
meinte sample = (sample+delay[0])/2 liefert ein anderes Ergebniss als 
sample+=delay[0]; sample/=2;
Gruß
Andreas

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

guck mal ob die Daten wirklich unsigned sind! Nach dem beschriebenen
kann ich mir gut vorstellen das die signed herauskommen..
..beim einfachen kopieren ändert man ja nix, und die Daten werden also 
auch richtig vom DAC verstanden...)

Am besten mal mit CCS den "Delay speicher" angucken
(Menü->View->Graph->Time/Frequency; da dann single time einstellen und 
die startadresse des Buffers)

Um das ganze zu debuggen:
a) werte in array schreiben (z.b. 1000 Werte)
b) Breakpoint: angucken mit View
c) Wert[i] + Wert[i+n] in zweites Array
d) Breakpoint: angucken mit View

viel spaß noch dabei...

Autor: nightmarevs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatte jetzt am We noch mal ein wenig Zeit um weiter zu testen aber 
anstatt der Lösung näher zu kommen wirds für mich immer verwirrender: 
Wenn ich nur das verzögerte Signal ausgebe ist das auch schon nicht mehr 
das selbe wie das Eingangssignal man hört den Unterschied deutlich aber 
es ist ein erkennbares signal ohne störgeräusche. Wenn ich jezt direkt 
davor oder danach das Eingangssignal wieder Ausgebe hört sich das ganze 
wieder besch****n an.
Gruß
Andreas

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte generiere doch wirklich mal eine assembler Datei, damit wir 
wirklich sehen, was der Prozessor macht, oder versuch es mit dem 
Debugger, obwohl ich mir von einer asm Datei mehr Erfolg erwarten würde.

Dort sollte man mühelos erkennen können, was falsch läuft.
Weißt du, wie man einen asm output erzeugt, sonst kann ich es schnell 
nachschauen.

Grüße,

Peter

Autor: nightmarevs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich werde versuchen eine asm Datei zu erzeugen sobald ich die Zeit 
dazu finde, leider habe ich im moment viel um die Ohren so das es mir 
wahrscheinlich erst Donnerstag oder Freitag möglich sein wird.
Gruß
Andreas

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

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

Formatierung (mehr Informationen...)

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




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

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