- SF800 Solar Speicher Tutorial         
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


    wenn man als Menüpunkt/Aktion wählt "aufnehmen", dann nimmt man einen Sound ja über die Soundkarte als reinen Array auf.

    Wenn man ihn jetzt als Muster später wieder benutzen will, muss man ihn ja als .wav speichern.

    JA.wav
    NEIN.wav
    STOPP.wav

    Nur dann kann man ja später auch aktuelle Wörter mit allen bekannten gespeicherten Mustern vergleichen, um festzustellen, wie denn das Wort nun heißen mag...

    und wenn nichts annähernd identisches vorhanden ist an Mustern, z.B. bei
    VORWÄRTS!
    dann kann man es gleich als neues .wav Muster speichern, für künftige Vergleiche.
    VORWAERTS.wav

    und somit hat man dann ein weiteres, neues Wort in seinem Wortschatz.
    Und man kann jetzt auch direkt einzelne Wörter seines Wortschatzes abhören, wie sie klingen, und ob sie ggf. noch etwas von der Qualität her verbessert werden können/müssen.




    nach jeder Aktion im Programm könnte man also zum Menü zurückkehren:

    Kommando-Center:
    ==============
    0 Soundfile *.csv in Programm öffnen / laden (FileOpenDialog)
    1 Soundfile *.wav in Programm öffnen / laden (FileOpenDialog)
    2 Soundfile *.wav öffnen / abspielen + Plot (FileOpenDialog)
    3 Sound aufnehmen per Micro / SoundCard
    4 akt. Sound (Array im RAM) abspielen + Plot
    5 akt. Sound optimieren (noise/cut)
    6 akt. Sound (im RAM) als File speichern unter... (FileSaveDialog)
    7 akt. Sound an FFT + Plot
    8 akt. Sound cross correlation mit 1 wav File (FileOpenDialog)
    9 akt. Sound cross correlation mit allen *.wav Files (auto)
    ...
    Geändert von HaWe (16.06.2016 um 08:58 Uhr) Grund: opt.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Hier erstmal das Menü.

    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;
    
    string version = "2.0";
    
    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], m[3];
    
    	initOpenVG();
    
    	system("clear");
    	
    	cout << endl << "HaWe und Hirnfreis's Sound Experiment V " << version << endl << endl;
    	cout << "     1. Audio aufnahme" << endl;
    	cout << "     2. input.csv abspielen" << endl;
    	cout << "     3. waveBuffer.csv abspielen" << endl << endl;
    	cout << "     Bitte wählen: ";
    	
    	fgets(m, 2, stdin);
    	
    	if(strcmp(m, "1") == 0) 
    	{
    		cout << endl << "Starte Aufnahmne... " << endl << endl;
    		
    		audioCapture(waveBuffer, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    
    		cout << endl << "Aufnahmne beendet! " << endl << endl;
    	}
    	
    	if(strcmp(m, "2") == 0) 
    	{
    		cout << endl << "Spiele input.csv ab!" << endl << endl;
    		
    		datei.open("input.csv", ios::in);
    		
    		for(i=0;i<SHRT_MAX;++i)
    		{
    			datei >> waveBuffer[i];
    		}
    		
    		datei.close();
    	}
    	
    	if(strcmp(m, "3") == 0) 
    	{
    		cout << endl << "Spiele waveBuffer.csv ab!" << endl << endl;
    
    		datei.open("waveBuffer.csv", 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;
    }
    - - - Aktualisiert - - -

    Ich sehe aber keinen Grund da ein wave draus zu bauen. speichern und abspielen kann man auch mit meiner Variante und muss nicht erst noch Header erstellen und auslesen# Wäre in meinen Augen nur unnötiger Aufwand.

  3. #3
    HaWe
    Gast
    das ging ja super schnell!



    allerdings soll nicht csv geladen / abgespielt / gespeichert werden, sondern *.wav Dateien (ggf. ~auswahl wie im Filebrowser).

    Gespeichert werden sollen nur echte .wav Formate, keine reinen Arrays.



    das Konzept ist:

    im RAM befindet sich immer ein Array mit den reinen sound data,
    auf der SD befinden sich viele (!) .wav Dateien: die bilden den Wortschatz bekannter (zu erkennender) Wortbefehle.
    Sie müssen während der Testphase und auch später im Automatik-Betrieb nacheinander geöffnet, gespielt, bearbeitet und verglichen werden können.

    Zum Bearbeiten werden .wav Files geöffnet und die reinen sound data in einen array ins RAM kopiert,
    Per Micro wird auch nur ein Array im RAM belegt,
    bei Speichern wird aber wieder der komplette wav-Header davor geschrieben.



    dazu dienen unsere Werkzeuge, und die sind:

    a) record_wave(int32_t * array, int32_t length);
    b) save_wave2file(int32_t * array, char * filename);
    c) wavefile2Array(int32_t * array, char * filename);
    d) play_waveArray(int32_t * array, int32_t length);
    e) play_waveFile(char * filename);
    sowie
    f) plotArray(int32_t * array, int32_t length, int y0);
    g) analyseArray(int32_t * array, int32_t length);
    h) array2FFT(int32_t * array, int32_t length, double * fx, double * fy, int32_t FFT_length);
    i) cross_corr(int32_t * array, int32_t * pattern, int32_t length);
    ...usw...
    Geändert von HaWe (13.06.2016 um 17:49 Uhr)

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Wie im Filebrowser??????????????????????????? Der Aufwand wird etwas gross! Je nachdem wie viele Dateien das sind muss dann auch noch aufteilen und scrollen usw. rein. Also das ist mir dann doch zu viel des Guten.

    Aber nochmal. Was spricht gegen das Speichern des Array? Ich sehe keinen Sinn darin ein ganzes Wave da zu bauen.

  5. #5
    HaWe
    Gast
    wir sollten jederzeit immer einfach einen File im Browser abspielen können, um ihn jederzeit hören zu können.

    Und stell dir vor, wir haben einen Wortschatz von ein paar Dutzend Wörtern, und die Worterkennung klappt am Anfang nicht (wie sicher zu erwarten ist), dann muss man die Files einfach auswählen können, einzeln laden, und einfach mit anderen cross-correlieren.

    Wenn der Dateizugriff da nicht einfach per Auswahlmenü möglich ist (einfache Liste mit scroll-bar, wie früher im Norton Commander), dann tippt man sich ja nen Wolf und sitzt nächstes Jahr mit der paarweisen cross-correlation noch dran

    wenn du allerdings nur 2 oder 3 Wort-Befehle programmieren willst, und dabei bleibts dann auch, dann ist die Sache einfacher zu händeln...... aber sonst, mit mehr, wächst der Verwaltungsaufwand eben exponentiell....

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Hast du so ein Menü schon einmal selbst gebaut? In Secondlife habe ich solche Menüs mit Auswahlmenü gegen Geld programmiert,weil es sonst keiner machen wollte. Das ist schon ein fetter Aufwand. Wenn du das übernehmen möchtest freue ich mich auf das Ergebnis .

    Ich verstehe dich aber richtig. Eine Eingabe über das Mikro wird mit verschiedenen Dateien verglichen. Bzw. Eine ausgewählte Aufnahmen wird mit den Anderen verglichen. Soweit bin ich da noch richtig oder?

  7. #7
    HaWe
    Gast
    ich hatte damals bei NXC etwa 10 Wörter zu verwalten, und da war der Aufwand überschaubar, und es ging ja ohne FFT.
    Hast du dir das Programm einmal angeschaut?
    Auch einen Filebrowser ähnlich dem Norton Commander habe ich schon einmal selber programmiert, mit Maus- und Tastatursteuerung, auf der Basis von Pascal-File-Funktionen
    FindFirst(pattern),
    FindNext()
    unabhängig davon, in Turbo Pascal.

    Unterschätze den Aufwand nicht, der für Spracherkennung betrieben werden muss, dass ist kein Spaziergang im Park.
    Ohne bedienerfreundliche (programmiererfreundliche) Entwickler-, Hilfs- und insb. Dateizugriffswekzeuge, die wir alle selber erstellen müssen, sehe ich da kein Land am Horizont.

    Eine Eingabe über das Mikro wird mit verschiedenen Dateien verglichen. Bzw. Eine ausgewählte Aufnahmen wird mit den Anderen verglichen. Soweit bin ich da noch richtig oder?
    ja, das stimmt,
    dann wird der jeweilige Fehler ermittelt,
    und das mit dem kleinsten Fehler ist das am besten passendste Wort.
    Wenn der Fehler überall zu groß ist (bestimmter Schwellwert), oder das vorgeschlagene Wort falsch ist, dann kann das aktuelle Wort als neues Wort gespeichert werden.


    Bevor unser Programm irgendwann so weit ist, dass es die ganzen Analysen automatisch selber machen kann, müssen wir sie erstmal mühsam alle einzeln manuell durchführen, dann testen, optimieren, und erneut durchführen können.

Ä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
  •  

Labornetzteil AliExpress