nachdem wir mit den Vorarbeiten eigentlich soweit sind -
hast du dir das hier jetzt mal genauer angesehen...?
http://dsp.stackexchange.com/questio...es-are-similar
Schon. Aber dann brauche ich wieder Platz für noch einen Monitor, noch eine Tastatur und noch eine Mouse. Von daher.
nachdem wir mit den Vorarbeiten eigentlich soweit sind -
hast du dir das hier jetzt mal genauer angesehen...?
http://dsp.stackexchange.com/questio...es-are-similar
So. Code eingebaut, etwas angepasst, ausprobiert. Läuft!
Rauscht noch ein wenig, aber ich denke es ist schon um einiges besser!Code:#include <iostream> #include <vector> #include <fstream> #include <stdio.h> #include <limits.h> #include <math.h> #include "diaSound.hpp" bool debug = false; bool ausgabe = true; void filtern(int32_t *array) { int32_t sbuf[128]; int32_t bias, minr, maxr, baseline, maximum, minimum, maxpos, minpos, signalstart, signalend; uint16_t i; // dynamics: min, max maximum = array[0]; minimum = array[0]; for(i=0;i<SHRT_MAX; ++i) { if(array[i] > maximum) { maximum = array[i]; maxpos = i; } if(array[i] < minimum) { minimum = array[i]; minpos = i; } } // calculate baseline from last 100 array cells: // init vars baseline=(array[minpos] + array[maxpos]) / 2; // init baseline by (min+max)/2 minr=baseline - 1; maxr=baseline + 1; // auto-adjust: for(i=SHRT_MAX-100; i<SHRT_MAX; ++i) { // mean baseline baseline = round((0.5*(float)array[i] + 0.5*(float)baseline)) ; // smoothed out max noise if(array[i] >= baseline) maxr = round((0.6*(float)array[i] + 0.4*(float)maxr)) +1 ; // smoothed out min noise if(array[i] <= baseline) minr = round((0.6*(float)array[i] + 0.4*(float)minr)) -1 ; } bias = max(baseline-minr, maxr-baseline) +1; // noise reduction start/end // drop small noise for(i=0;i<SHRT_MAX;++i) { if((array[i]>baseline) && (array[i] <= baseline + bias)) array[i] = baseline ; // little higher value => drop to baseline else if((array[i]<baseline) && (array[i] >= baseline - bias)) array[i] = baseline ; // little lower value => rise to baseline } // signalstart, signalend: threshold = bias + (bias/2) signalstart = 0; i = 0; while((array[i]<=baseline + 4 * bias/3) && (i<SHRT_MAX-1)) ++i; signalstart = i; if(i > 0) signalstart -= 1; signalend=SHRT_MAX-1; i=SHRT_MAX-1; while((array[i]<=baseline + + 4*bias/3) && (i>signalstart)) --i; signalend = i; if(i<SHRT_MAX-1) signalstart +=1; } void analyse(int32_t *waveBuffer) { int32_t maximum = waveBuffer[0]; int32_t minimum = waveBuffer[0]; int32_t maxpos, minpos; int32_t i; for(i=0;i<SHRT_MAX;i++) { if(waveBuffer[i] > maximum) { maximum = waveBuffer[i]; maxpos = i; } if(waveBuffer[i] < minimum) { minimum = waveBuffer[i]; minpos = i; } } filtern(waveBuffer); } int main() { fstream datei; int32_t input[SHRT_MAX], waveBuffer[SHRT_MAX]; int32_t i; audioCapture(input, SHRT_MAX, "plughw:1,0", 1, 12000, 8); if(debug) datei.open("test.csv", ios::out); for(i=0;i<SHRT_MAX;i++) { waveBuffer[SHRT_MAX] = input[i] & 0x00ff; if(debug) cout << i << " -> " << input[i] << endl; if(debug) datei << input[i] << endl; } analyse(waveBuffer); if(debug) datei.close(); if(ausgabe) { uint8_t *wave; wave = (uint8_t *) malloc(SHRT_MAX+1); for(i=0;i<SHRT_MAX;i++) wave[i] = input[i] & 0x00ff; playCaptured(wave, SHRT_MAX, "plughw:1,0", 1, 12000, 8); free(wave); } return 1; }
Kannst du es noch nicht testen?
- - - Aktualisiert - - -
HALT! Kommando zurück!
Ich dussel habe vergessen die richtige Variable an playCaptured zu schicken .
Umbauen und testen!
- - - Aktualisiert - - -
Gerade versucht. Gibt nur zwei kurze Knacken
was ist, wenn du die Zeile
analyse(waveBuffer);
auskommentierst?
Dann bleibt ja der Sound in waveBuffer unverändert und müsste genau wie das Original klingen.
Spiel dafür zum Vergleich kurz mal hintereinander
a) input und
b) wavebuffer
über playCaptured ab.
zum selber ausprobieren:
ich habe keine Idee, wie ich diene csv datei in das Raspi programm als array reinbekommen soll, und ich habe ja auch keine line in Buchse um selber etwas aufzunehmen.
hilfreich wäre auch, einen wave-Plot zu sehen, so wie bei meinen Arduino-array-Plots:
a) input
b) wavebuffer ohne analyse
c) wavebuffer mit analyse
- - - Aktualisiert - - -
ps,
außerdem wäre es IMO sinnvoller, wenn die filter-Algorithmen direkt in analyse() drinstehen, nicht als extra filter Prozedur, und zwar wegen aller dort deklarierten lokalen Variablen.
Geändert von HaWe (09.06.2016 um 09:32 Uhr)
Ich bastel dir eine Funktion mir der du die Daten einlesen kannst. Das ist das kleinste Problem . Dachte das du vielleicht mittlerweile die Karte bekommen hast.
Gut, Analyse baue ich um, kein Problem.
Ich habe schon input und wavebuffer hintereinander abgespielt. input geht, wavebuffer nicht.
Plots mache ich nachher.
geht wavebuffer auch ohne analyse() nicht oder nur mit analyse() nicht ?
Habe ich auch schon versucht. Das bringt das selber Ergebnis.
wenn es mit Input geht, mit wavebuffer nach dem Kopieren aber nicht, heißt das aber, dass plötzlich schon das simple rüberkopieren der Werte nicht mehr abspielbar ist...?!
Hat es nicht früher schon mal funktioniert?
- - - Aktualisiert - - -
Fehler gefunden!
for(i=0;i<SHRT_MAX;i++) {
waveBuffer[SHRT_MAX] = (int32_t) input[i] & 0x00ff; <<<< hier ist ein Fehler!
// richtig:
for(i=0;i<SHRT_MAX;++i) {
waveBuffer[i] = input[i] & 0x00ff; <<<< richtig !
wenn es dann geht:
lass dir bitte mal anzeigen:
bias
maximal
minimal
signalstart
signalend
Wo du recht hast . Ist mir aber auch schon aufgefallen, damit geht es natürlich.Code:for(i=0;i<SHRT_MAX;i++) { waveBuffer[SHRT_MAX] = (int32_t) input[i] & 0x00ff; <<<< hier ist ein Fehler! // richtig: for(i=0;i<SHRT_MAX;++i) { waveBuffer[i] = input[i] & 0x00ff; <<<< richtig !
Die Bias... Ausgabe habe ich auch schon eingebaut, genau so wie im Falle eines Debug das Speichern von input und waveBuffer sowie die Möglichkeit eine gespeicherte Datei wieder zu laden.
Mit letzterem habe ich allerdings noch ein paar Schwierigkeiten.
Filtern ist auch in Analyse integriert.
Sobald das Laden funktioniert bau ich den Code hier ein.
- - - Aktualisiert - - -
Sooooo. 200x den Fehler übersehen. Dann doch gefunden
Jetzt bist du auch in der Lage eine vom programm erstellte Datei wieder zu laden abspielen zu lassen. Gib einfach hinter dem Programmnamen den Namen der Datei ein. Fertig. Dann umgeht er die Aufnahme und nimmt stattdessen den Input der Datei,Code:#include <iostream> #include <vector> #include <fstream> #include <string> #include <stdio.h> #include <limits.h> #include <math.h> #include "diaSound.hpp" bool debug = false; bool ausgabe = true; void analyse(int32_t *waveBuffer) { int32_t sbuf[128]; int32_t bias, minr, maxr, baseline, signalstart, signalend; int32_t maximum = waveBuffer[0]; int32_t minimum = waveBuffer[0]; int32_t maxpos, minpos; int32_t i; for(i=0;i<SHRT_MAX;i++) { if(waveBuffer[i] > maximum) { maximum = waveBuffer[i]; maxpos = i; } if(waveBuffer[i] < minimum) { minimum = waveBuffer[i]; minpos = i; } } maximum = waveBuffer[0]; minimum = waveBuffer[0]; for(i=0;i<SHRT_MAX; ++i) { if(waveBuffer[i] > maximum) { maximum = waveBuffer[i]; maxpos = i; } if(waveBuffer[i] < minimum) { minimum = waveBuffer[i]; minpos = i; } } // calculate baseline from last 100 waveBuffer cells: // init vars baseline=(waveBuffer[minpos] + waveBuffer[maxpos]) / 2; // init baseline by (min+max)/2 minr=baseline - 1; maxr=baseline + 1; // auto-adjust: for(i=SHRT_MAX-100; i<SHRT_MAX; ++i) { // mean baseline baseline = round((0.5*(float)waveBuffer[i] + 0.5*(float)baseline)) ; // smoothed out max noise if(waveBuffer[i] >= baseline) maxr = round((0.6*(float)waveBuffer[i] + 0.4*(float)maxr)) +1 ; // smoothed out min noise if(waveBuffer[i] <= baseline) minr = round((0.6*(float)waveBuffer[i] + 0.4*(float)minr)) -1 ; } bias = max(baseline-minr, maxr-baseline) +1; // noise reduction start/end // drop small noise for(i=0;i<SHRT_MAX;++i) { if((waveBuffer[i]>baseline) && (waveBuffer[i] <= baseline + bias)) waveBuffer[i] = baseline ; // little higher value => drop to baseline else if((waveBuffer[i]<baseline) && (waveBuffer[i] >= baseline - bias)) waveBuffer[i] = baseline ; // little lower value => rise to baseline } // signalstart, signalend: threshold = bias + (bias/2) signalstart = 0; i = 0; while((waveBuffer[i]<=baseline + 4 * bias/3) && (i<SHRT_MAX-1)) ++i; signalstart = i; if(i > 0) signalstart -= 1; signalend=SHRT_MAX-1; i=SHRT_MAX-1; while((waveBuffer[i]<=baseline + + 4*bias/3) && (i>signalstart)) --i; signalend = i; if(i<SHRT_MAX-1) signalstart +=1; if(ausgabe) { cout << "Bias: " << bias << endl; cout << "Maximal: " << maximum << endl; cout << "Minimal: " << minimum << endl; cout << "Signalstart: " << signalstart << endl; cout << "Signalende: " << signalend << endl; } } int main(int argc, char *argv[]) { fstream datei; int32_t input[SHRT_MAX], waveBuffer[SHRT_MAX]; int32_t i; if(argc <= 1) audioCapture(input, SHRT_MAX, "plughw:1,0", 1, 12000, 8); else { datei.open(argv[1], ios::in); for(i=0;i<SHRT_MAX;++i) { datei >> input[i]; } datei.close(); } if(debug) datei.open("input.csv", ios::out); for(i=0;i<SHRT_MAX;i++) { waveBuffer[i] = input[i] & 0x00ff; cout << i << " -> " << input[i] << endl; if(debug) datei << input[i] << endl; } if(debug) datei.close(); analyse(waveBuffer); if(debug) { datei.open("waveBuffer.csv", ios::out); for(i=0;i<SHRT_MAX;i++) datei << waveBuffer[i] << endl; datei.close(); } if(ausgabe) { uint8_t *wave; wave = (uint8_t *) malloc(SHRT_MAX+1); for(i=0;i<SHRT_MAX;i++) wave[i] = waveBuffer[i]; playCaptured(wave, SHRT_MAX, "plughw:1,0", 1, 12000, 8); free(wave); } return 1; }
- - - Aktualisiert - - -
Plotten kannst du, wenn du selbst experimentierst dann jetzt auch. Geh einfach auf http;//sound.projekt-hirnfrei.de/index.php, lade die Datei hoch und warte kurz. Schon wird dir das Ergebnis angezeigt.
danke, dann mach ich mich mal dran ("ASAP").
Jetzt am Wochenende bin ich unterwegs und kann wenig mit nem Pi machen, ich nehme ihn trotzdem mit inkl. was zum bedienen dazu gehört.
- Mich interessiert nun, wie es jetzt klingt,
- was misst du an "bias", .. (blödes Wort, ich hatte es zuerst für eine Schwelle benutzt, jetzt eigentlich besser: "noise"),
- Wie groß sind max und min Ausschlag des Wortes,
- welchen Bereich hat er als "Wort" markiert (signal start/end) ?
- und kann man dein Originalwort unverstümmelt (!) noch genau so erkennen wie vorher, nur jetzt eben ohne Rausch- Vor- und Nachspann?
Fürs Plotten muss noch openVG in dein Programm rein, damit man die Plots von Dateien und allen möglichen Arrays direkt auf dem Raspi-Screen anschauen kann, während der Programmierung, zum Debuggen, zur laufenden Kontrolle, und zur Optimierung von Filtern:
http://www.mindstormsforum.de/viewto...p=67838#p67774
on-line zu plotten macht nur ausnahmsweise mal Sinn, wenn alles andere versagt.
Wir brauchen dann demnächst die Plot-Möglichkeit (einfach senkrechte Linien nebeneinander setzen) vor allem auch für die Graphen der FFT.
(wie das openVG dann mit ssh funktioniert, weiß ich allerdings nicht)
Für die Initialisierung des openVG-Fensters würde ich in mindestens (BxH) 640x480 oder sogar 1024x600 nehmen, dann kann man Koordinatensysteme in 512er Breite (evtl. sogar 1024) darstellen, eben entsprechend "gestaucht" (vgl. Arduino-Plots).
OpenVG benötigt folgende Befehls-Wrapper um die eigentliche Grafik-Ausgabe herum:
Code:#include "VG/openvg.h" #include "VG/vgu.h" #include "fontinfo.h" #include "shapes.h" int width, height; initWindowSize(20, 20, 640, 480); init(&width, &height); // Graphics initialization, cut away overhead WindowOpacity(220); // define window opacity (0...255) Background(0, 0, 0); // Black background Start(width, height); // Start the picture // >>>> hier kommt der Plot- Code rein fürs aktuelle Bild Fill(255, 255, 255, 1); // White text (eigentlich besser: "TextColor()" ) StrokeWidth(1.0); // Zeichenstift-Breite (eigentlich besser: "BrushWidth()" ) Stroke(255, 255, 255, 1.0); // Zeichenstift-Farbe (eigentlich besser: "BrushColor()" ) // ... // ( ... more code for graphics) End(); // Put the picture to the screen (eigentlich: "showPicture()" ) // <<<< Ende des aktuellen Bildes finish(); // Graphics cleanup (end of program)
Geändert von HaWe (10.06.2016 um 14:20 Uhr) Grund: Zeichenstift-Methoden ergänzt
Lesezeichen