- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 241

Thema: wav Dateien: Programieren von Wiedergabe und Aufnahme

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast
    ich kann kein ssh und werde es auch nie nutzen. Ist so ein Linux Ding, das ich einfach nicht mag.

    wir werden plotArray noch öfter brauchen, aber immer nur einfach, eins nach dem anderen, das oben war ja nur der Anfang.

    1. Aufruf: array unverändert
    2. Aufruf: Rauschen raus und Wort Grenzen ermittelt.
    3. Aufruf: Wort herausschneiden und ganz an den Anfang eines neuen Arrays setzen

    Probier mal bitte meine Funktion plotArray zu verwenden, deine ist mir völlig unklar, auch wegen der x-Achsen-Skalierung und der gezielten Ausgabe an bestimmten Stellen im Fenster, alleine oder zu mehreren.


    Dann geht es weiter wie hier skizziert:

    https://www.roboternetz.de/community...l=1#post628055


    wir können dann bald die veränderten wav files mit den unveränderten per FFT vergleichen.

    - - - Aktualisiert - - -

    ps,
    eigentlich würde es sogar reichen, nur Punkte zu setzen, keine Linien zu malen:

    statt
    void Line(VGfloat x1, VGfloat y1, VGfloat x2, VGfloat y2)
    jetzt
    void Point(VGfloat x, VGfloat y)

    ich finde aber keine entsprechende API Funktion.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    So ich bin schon am umbauen. Funktioniert soweit. Nur habe ich irgendwie so das Gefühl das man bei deiner Variante nicht so gut sieht wie bei meiner.

    Generell, warum ist die dieser von unten nach Oben zeichen Variante lieber wie die die ich genommen hate? Nach meiner Variante wird es doch auch in anderen Soundprogrammen angezeigt.

    Code:
    #include <iostream>
    #include <vector>
    #include <fstream>
    #include <string>
    
    #include <stdio.h>
    #include <limits.h>
    #include <math.h>
    
    #include <VG/openvg.h>
    #include <VG/vgu.h>
    #include <fontinfo.h>
    #include <shapes.h>
    
    #include "diaSound.hpp"
    
    bool ausgabe = true;
    
    int _width_=1024, _height_=600;
    
    void initOpenVG() 
    {
    	initWindowSize(0, 0, _width_, _height_);
    	init(&_width_, &_height_);               
    	Start(_width_, _height_);                   
    	Background(0, 0, 0);                             
    	StrokeWidth(1.0);
    	WindowClear();
    }
    
    void plotArray(int32_t *array, int32_t arrlength, int y0) 
    {
    	float xscale=1.0, border=100.0;
    	xscale = (float) (arrlength-border)/_width_;
    
    	int i;
    
     	Fill(0, 255, 255, 1); 
    	Stroke(0, 255, 255, 1);
    	     
    	for(i=0;i<arrlength;i++)
    	{		
    		Line((VGfloat)xscale*i, (VGfloat) y0, (VGfloat)xscale*i, (VGfloat)(y0+array[i]));
    	}
    	End();  
    }
    
    void analyse(int32_t *array, int32_t arrlength)
    {
    	int32_t     sbuf[128];
    	int32_t     bias, minr, maxr, baseline, 
    				signalstart, signalend;
    
    	int32_t maximum = array[0];
    	int32_t minimum = array[0];
    	
    	int32_t maxpos, minpos;
    	
    	int32_t i;
    
    	for(i=0;i<arrlength;i++)
    	{
    		if(array[i] > maximum)
    		{
    			maximum = array[i];
    			
    			maxpos = i;
    		}
    
    		if(array[i] < minimum)
    		{
    			minimum = array[i];
    			
    			minpos = i;
    		}
    	}
    	
    	maximum = array[0];
    	minimum = array[0]; 
    
    	for(i=0;i<arrlength; ++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=arrlength-100; i<arrlength; ++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<arrlength;++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=arrlength-1;
    
    	i=arrlength-1;
    
    	while((array[i]<=baseline + + 4*bias/3) && (i>signalstart)) --i;
    
    	signalend = i;
    
    	if(i<arrlength-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 waveBuffer[SHRT_MAX];
    
    	int32_t i;
    
    	char s[3];
    
    	initOpenVG();
    
    	if(argc <= 1) audioCapture(waveBuffer, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    	else
    	{
    		datei.open(argv[1], ios::in);
    		
    		for(i=0;i<SHRT_MAX;++i)
    		{
    			datei >> waveBuffer[i];
    		}
    		
    		datei.close();
    	}
    	
    	for(i=0;i<SHRT_MAX;i++)
    	{
    		waveBuffer[i] = waveBuffer[i] & 0x00ff;
    	} 
    	
    	plotArray(waveBuffer, SHRT_MAX, 0);
    
    	analyse(waveBuffer, SHRT_MAX);
    
    	plotArray(waveBuffer, SHRT_MAX, 255);
    
    	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);
    	}
    
    	fgets(s, 2, stdin);
    
    	finish();
    	
    	return 1;
    }
    Was ssh angeht. Ja es mag eine Linux Geschichte sein, nur verstehe ich dein Problem damit nicht ganz. Ich nehme mal stark an du startest das compilierte Programm jetzt auch in einem Terminal auf dem Raspi. Dann ist der Unterschied eigentlich super gering. Mittels Putty kannst du eine Verbindung zum Raspi aufbauen- Dabei hast du dann ja einen Terminal der eben nur auf deinem Windows läuft anstatt auf dem Raspi. Nicht einmal auf deinem Windows läuft sondern nur auf diesem angezeigt wird. Wenn du dort dann

    Code:
    geany &
    startet geany auf dem Raspi und leitet seine GUI auf dein Windows um. Es läuft also prinzipiell Alles genau so wie auf dem Raspi.Wäre ja zumindest für den Übergang sinnvoll.

  3. #3
    HaWe
    Gast
    ja, ich glaube ich habe inzwischen auch verstanden, was du machst, du verbindest die Oberkanten der Ausschläge, das gibt eine Art "Obere Umrandungslinie".
    Ich habe die Spikes verwendet, weil sie den Hintergrund komplett einfärben und damit kontrastreicher sind (siehe Arduino Plots).

    Zum Starten:
    nein, ich starte das programm entweder über Geany F5 oder ich starte es im Filemanager (was bei wiringPi nicht geht, wegen sudo-Pflicht) -
    oder ich lege einen Link auf den Desktop (Ausführen per sudo).
    Solange ich aber damit viel noch rumprogrammiere: immer nur per Geany F5.

    Ein Terminal verwende ich nie, diese Un-Toten lasse ich ruhen, und Putty ist für mich Teufelswerk

    Ab Mittwoch spätestens habe ich meinen großen Raspi Screen wieder und kann wieder lokal kompilieren

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Du willst also lieber die oberen Ausschläge haben?

    Für einen C Programmierer bist du aber ziemlich unflexibel .

    Ich sage es dir auch nur ungerne aber die Meisten die aktiv programmieren, sei es bei Google oder Microsoft oder wo auch immer, benutzen diese Un-Toten ^^.

  5. #5
    HaWe
    Gast
    moin!
    ich schätze die C-Syntax sehr, weil sie ungeheuer mächtig und perfekt prozedural strukturierbar ist, aber ich bin Hobby-Programmierer und IDEs und USB-p'n'p gewöhnt (wie bei der Arduino IDE oder der Lego BricxCC IDE), und ich würde mich niemals als "typischen" C-Programmierer bezeichnen (C++ beherrsche ich selber gar nicht). Mit der ganzen Linkerei und make, makefile, .so files, logins und IPs will ich nichts zu tun haben, auch nichts mit Terminals (außer automatisch per USB verbinden ohne weitere Einstellungen wie bei Arduino und Serial).
    IDE komplett installieren per setup.exe etc.
    Programm schreiben in einer IDE
    Compilieren per Tastendruck
    Hochladen per Tastendruck (falls nötig)
    Starten per Doppelklick oder Tastendruck
    - so einfach muss Hobbyprogrammieren gehen, das ist mein Level, und genau so funktioniert ja auch Arduino.

    was die Anzeige angeht: so wie bei meinem Code-Voschlag oben wäre es eigentlich perfekt, da auch auf kleinen Screens (5", 7") dann skalierbar und gut erkennbar.
    Code:
    void plotArray((int32_t *array, int32_t  arrlength, int y0) {
    
       float xscale=1.0, border=100.0;   // border anpassen !
       xscale =  (float) (arrlength-border)/_width_;  // Ausschöpfung der gesamten openVG-Window-Breite width samt Rand!
    
       Fill( CYAN, 1 );      
       for(i=0;i<arrlength;i++)
       {		
          Line((VGfloat)xscale*i, (VGfloat) y0, (VGfloat)xscale*i, (VGfloat)(y0+input[i]) );
       }
       End();  
    }

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Du teilst falsch. Du musst die Bildbreite durch die array Länge teilen, nicht umgekehrt.

    Code:
    #include <iostream>
    #include <vector>
    #include <fstream>
    #include <string>
    
    #include <stdio.h>
    #include <limits.h>
    #include <math.h>
    
    #include <VG/openvg.h>
    #include <VG/vgu.h>
    #include <fontinfo.h>
    #include <shapes.h>
    
    #include "diaSound.hpp"
    
    #define BLACK     0,   0,   0
    #define WHITE   255, 255, 255
    #define MAGENTA 255,   0, 255
    #define RED     255,   0,   0
    #define YELLOW  255, 255,   0
    #define LIME      0, 255,   0
    #define GREEN     0, 128,   0
    #define CYAN      0, 255, 255
    #define AQUA    102, 204, 204
    #define BLUE      0,   0, 255
    
    int   _width_=1024, _height_=600;
    int   _fontsize_ = 10;
    
    
    
    bool ausgabe = true;
    
    void initOpenVG() 
    {
    	initWindowSize(0, 0, _width_, _height_);
    	init(&_width_, &_height_);               
    	Start(_width_, _height_);                   
    	Background(0, 0, 0);                             
    	StrokeWidth(1.0);
    	WindowClear();
    }
    
    void plotArray(int32_t *array, int32_t arrlength, int y0) 
    {
    	float xscale=1.0, border=100.0;
    	xscale = _width_ / (float) (arrlength-border);
    
    	int i;
    
     	Fill(CYAN, 1); 
    	Stroke(0, 255, 255, 1);
    	     
    	for(i=0;i<arrlength;i++)
    	{		
    		Line((VGfloat)xscale*i, (VGfloat) y0, (VGfloat)xscale*i, (VGfloat)(y0+array[i]));
    	}
    	End();  
    }
    
    void analyse(int32_t *array, int32_t arrlength)
    {
    	int32_t     sbuf[128];
    	int32_t     bias, minr, maxr, baseline, 
    				signalstart, signalend;
    
    	int32_t maximum = array[0];
    	int32_t minimum = array[0];
    	
    	int32_t maxpos, minpos;
    	
    	int32_t i;
    
    	for(i=0;i<arrlength;i++)
    	{
    		if(array[i] > maximum)
    		{
    			maximum = array[i];
    			
    			maxpos = i;
    		}
    
    		if(array[i] < minimum)
    		{
    			minimum = array[i];
    			
    			minpos = i;
    		}
    	}
    	
    	maximum = array[0];
    	minimum = array[0]; 
    
    	for(i=0;i<arrlength; ++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=arrlength-100; i<arrlength; ++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<arrlength;++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=arrlength-1;
    
    	i=arrlength-1;
    
    	while((array[i]<=baseline + + 4*bias/3) && (i>signalstart)) --i;
    
    	signalend = i;
    
    	if(i<arrlength-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 waveBuffer[SHRT_MAX];
    
    	int32_t i;
    
    	char s[3];
    
    	initOpenVG();
    
    	if(argc <= 1) audioCapture(waveBuffer, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    	else
    	{
    		datei.open(argv[1], ios::in);
    		
    		for(i=0;i<SHRT_MAX;++i)
    		{
    			datei >> waveBuffer[i];
    		}
    		
    		datei.close();
    	}
    	
    	for(i=0;i<SHRT_MAX;i++)
    	{
    		waveBuffer[i] = waveBuffer[i] & 0x00ff;
    	} 
    	
    	plotArray(waveBuffer, SHRT_MAX, 0);
    
    	analyse(waveBuffer, SHRT_MAX);
    
    	plotArray(waveBuffer, SHRT_MAX, 255);
    
    	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);
    	}
    
    	fgets(s, 2, stdin);
    
    	SaveEnd("plott.raw");
    
    	finish();
    	
    	return 1;
    }
    sind noch weitere Änderungen im Code drin.

  7. #7
    HaWe
    Gast
    klar, stimmt ntl mit dem Teilen! :rolleyes:
    (das ist der Nachteil vom offline Programmieren ;) )

    mit dem if (ausgabe) und dem if(argc) komme ich allerdings nicht klar, denn ich starte ja aus geany heraus und nie von der Kommandozeile aus.

    Vielleicht könnten wir später ein Menü einbauen, im Moment ist es aber eh nicht wichtig, denn die nächsten Schritte wären ja laut
    https://www.roboternetz.de/community...l=1#post628055

    a) du nimmst eine Reihe von Wort-Samples auf:
    JA_raw.wav
    NEIN_raw.wav
    STOPP_raw.wav

    b) der Micro- bzw. file- input[] array wird als Plot angezeigt
    und dann direkt nach analyse geschickt und noise und Wort-Grenzen ermittelt.

    c) jetzt wird NUR das Wort innerhalb der Wort-Grenzen nach wavbuffer kopiert
    Code:

    memset(wavebuffer, 0, sizeof(wavebuffer) );
    memcpy(wavebuffer, input+(signalstart*sizeof(char)), (signalend-signalstart)*sizeof(int32_t) );

    d) Der wave-Puffer startet jetzt an Stelle 0 mit dem wav-Wortsignal, der Rest bleibt 0.
    Der neue wav-Puffer wird ebenfalls als Plot angezeigt.

    e) dann wird das "neue" wavebuffer-Muster als .wav Datei gespeichert.
    JA_opt.wav
    NEIN_opt.wav
    STOPP_opt.wav
    da wir das Plotten ja inzwischen mit variabler Basislinie machen können, könnte man alle 2-3 Plots für den Anfang immer untereinander im selben Fenster anzeigen:
    a) unverändert: y0=300-400
    b) ent-rauscht: y0=200 (kann entfallen)
    c) geschnitten: y0=1

    Das dient zur in-Prozess-Kontrolle bei den vorhergehenden und den folgenden Schritten...
    denn dann käme ja als nächstes eine kleine Erweiterung der alsa-API mit den vereinfachten Funktionen zum schnelleren abspielen, aufnehmen und um-kopieren von files und arrays nacheinander und ineinander:

    a) record_wave(int32_t * array, int32_t length); // Aufnahme von Tönen über Soundkarte => input-array
    ähnlich wie audioCapture(input, SHRT_MAX, "plughw:1,0", 1, 12000, 8 );

    b) save_wave2file(int32_t * array, char * filename); // speichern eines arrays als .wav File mit header
    => fehlt noch ?

    c) wavefile2Array(int32_t * array, char * filename); // lesen von einem .wav File => in input-array
    (extrahiert ohne header, nur data, ohne audio-Wiedergabe über Soundkarte)

    d) play_waveArray(int32_t * array, int32_t length); // abspielen eines arrays mit festen Parametern
    ähnlich wie playCaptured(wave, SHRT_MAX, "plughw:1,0", 1, 12000, 8 );

    e) play_waveFile(char * filename); // abspielen eines wav-files mit Parametern laut Header-Daten,
    ohne kopieren in einen temporären Array, ähnlich wie playwave(string waveDatei, string name)
    Soundkarten-Daten getrennt konfigurieren

    In die Sound-Lib sollte man dann noch zusätzlich aufnehmen diese 2 globalen #defines für Soundkarten:

    #define SoundCard_Intern "plughw:0,0"
    #define SoundCard_Extern "plughw:1,0"
    Geändert von HaWe (13.06.2016 um 16:49 Uhr)

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Du bist echt stur mit deinem Geany . Lieber ein Menü rein stricken wie ein Terminal öffnen ^^

    Ich bau dir was.

    Warum willst du das Ganze als Wave mit Header speichern??

Ähnliche Themen

  1. Video Aufnahme (+12std.)
    Von highdef im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 8
    Letzter Beitrag: 03.06.2011, 10:08
  2. led ein/aus programieren
    Von anthony im Forum PIC Controller
    Antworten: 6
    Letzter Beitrag: 15.07.2008, 17:44
  3. hex-dateien in bin-dateien umwandeln
    Von roboterheld im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 02.10.2007, 20:25
  4. Richtiges Drehen einer Flasche/Dose zur Aufnahme
    Von ähM_Key im Forum Mechanik
    Antworten: 2
    Letzter Beitrag: 06.10.2006, 15:43
  5. Automatische Audio-Aufnahme
    Von the_Ghost666 im Forum Software, Algorithmen und KI
    Antworten: 6
    Letzter Beitrag: 11.09.2005, 20:27

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen