- Labornetzteil 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
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Ich nehme mal an, die eigentliche Einstellungen für das Mikrofon muss ich über den Alsa-Mixer machen. Denke ich zumindest mal. Habe jetzt mal noch nicht gesehen wo ich das in meinem Programm beeinflussen können sollte. Mal schauen.

    Was ich im Moment erkennen kann, es kommen Zahlen von 0 bis 255 an. Ich fange ich jetzt damit an? Bislang arbeite ich mit 1 Kanal. Sind das dann die Daten von nur diesem einen Kanal?

    Was die Variablen angehen, es kommt also ein vector<int> zurück. Da kannst du jetzt alles draus machen was du machen willst.

    Code:
    int16_t waveArray[xxx];
    
    for(i=0;i<input.size();i++)
    {
         waveArray[i] = input[i];
    }
    Mal als Beispiel. Hab das jetzt nicht versucht, aber dürfte so machbar sein.

    - - - Aktualisiert - - -

    So ich habe gebastelte!

    Die neue Header Datei:

    Code:
    #include <alsa/asoundlib.h>
    
    #include <iostream>
    #include <vector>
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <time.h>
    
    using namespace std;
    
    typedef struct _FILE_head
    {
    	unsigned char	ID[4];
    	unsigned int	Length;
    	unsigned char	Type[4];
    } FILE_head;
    
    typedef struct _FORMAT 
    {
    	short wFormatTag;
    	unsigned short	wChannels;
    	unsigned int	dwSamplesPerSec;
    	unsigned int	dwAvgBytesPerSec;
    	unsigned short	wBlockAlign;
    	unsigned short	wBitsPerSample;
    } FORMAT;
    
    typedef struct _CHUNK_head
    {
    	unsigned char ID[4];
    	unsigned int	Length;
    } CHUNK_head;
    
    snd_pcm_t *soundKarte;
    
    bool Init(string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	int err;
    	
    	snd_pcm_format_t bits;
    
    	unsigned int resample = 1;
    
    	switch(WaveBits)
    	{
    		case 8:
    			bits = SND_PCM_FORMAT_U8;
    			break;
    	
    		case 16:
    			bits = SND_PCM_FORMAT_S16;
    			break;
    	
    		case 24:
    			bits = SND_PCM_FORMAT_S24;
    			break;
    	
    		case 32:
    			bits = SND_PCM_FORMAT_S32;
    			break;
    	}	
    	
    	snd_pcm_hw_params_t *hw_params;
    
    	if(name.length() == 0)
    	{
    		err = snd_pcm_open(&soundKarte, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0);
    	}
    	else
    	{
    		err = snd_pcm_open(&soundKarte, name.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
    	}
    
    	if(err < 0)
    	{
    		cout << "Init: Kann die Soundkarte nicht öffnen! " << name << " (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
    	{
    		cout << "Init: Parameter können nicht initialisiert werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_any(soundKarte, hw_params)) < 0)
    	{
    		cout << "Init: Parameter können nicht ermittelt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	err = snd_pcm_hw_params_set_rate_resample(soundKarte, hw_params, resample);
    
    	if(err < 0)
    	{
    		cout << "Init: Resampling kann nicht eingeschaltet werden " << snd_strerror(err) << endl;
    
    		return err;
    	}
    
    	if((err = snd_pcm_hw_params_set_access(soundKarte, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
    	{
    		cout << "Init: Zugriffstyp kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_format(soundKarte, hw_params, bits)) < 0)
    	{
    		cout << "Init: Sample-Format kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_channels(soundKarte, hw_params, channels)) < 0)
    	{
    		cout << "Init: Anzahl der Kanäle kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_rate_near(soundKarte, hw_params, &actualRate, 0)) < 0)
    	{
    		cout << "Init: Sample-Rate kann nicht auf " << actualRate << " gesetzt werden (" << snd_strerror (err) << ")"  << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params(soundKarte, hw_params)) < 0)
    	{
    		cout << "Init: Parameters können nicht gesetzt werden(" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    	snd_pcm_hw_params_free(hw_params);
    
    	if((err = snd_pcm_prepare(soundKarte)) < 0)
    	{
    		cout << "Init: Audio kann nicht zur Nutzung vorbereitet werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	return true;
    }
    
    bool InitCapture(string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	int err;
    	
    	snd_pcm_format_t bits;
    
    	switch(WaveBits)
    	{
    		case 8:
    			bits = SND_PCM_FORMAT_U8;
    			break;
    	
    		case 16:
    			bits = SND_PCM_FORMAT_S16;
    			break;
    	
    		case 24:
    			bits = SND_PCM_FORMAT_S24;
    			break;
    	
    		case 32:
    			bits = SND_PCM_FORMAT_S32;
    			break;
    	}	
    	
    	snd_pcm_hw_params_t *hw_params;
    
    	if(name.length() == 0)
    	{
    		err = snd_pcm_open(&soundKarte, "plughw:1,0", SND_PCM_STREAM_CAPTURE, 0);
    	}
    	else
    	{
    		err = snd_pcm_open(&soundKarte, name.c_str(), SND_PCM_STREAM_CAPTURE, 0);
    	}
    
    	if(err < 0)
    	{
    		cout << "Init: Kann die Soundkarte nicht öffnen! " << name << " (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
    	{
    		cout << "Init: Parameter können nicht initialisiert werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_any(soundKarte, hw_params)) < 0)
    	{
    		cout << "Init: Parameter können nicht ermittelt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_access(soundKarte, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
    	{
    		cout << "Init: Zugriffstyp kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_format(soundKarte, hw_params, bits)) < 0)
    	{
    		cout << "Init: Sample-Format kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_channels(soundKarte, hw_params, channels)) < 0)
    	{
    		cout << "Init: Anzahl der Kanäle kann nicht gesetzt werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params_set_rate_near(soundKarte, hw_params, &actualRate, 0)) < 0)
    	{
    		cout << "Init: Sample-Rate kann nicht auf " << actualRate << " gesetzt werden (" << snd_strerror (err) << ")"  << endl;
    
    		return false;
    	}
    
    	if((err = snd_pcm_hw_params(soundKarte, hw_params)) < 0)
    	{
    		cout << "Init: Parameters können nicht gesetzt werden(" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	snd_pcm_hw_params_free(hw_params);
    
    	if((err = snd_pcm_prepare(soundKarte)) < 0)
    	{
    		cout << "Init: Audio kann nicht zur Nutzung vorbereitet werden (" << snd_strerror (err) << ")" << endl;
    
    		return false;
    	}
    
    	return true;
    }
    
    bool UnInit()
    {
      snd_pcm_close(soundKarte);
    
      return true;
    }
    
    int playwave(string waveDatei, string name)
    {
    	FORMAT format;
    	FILE_head head;
    	CHUNK_head chead;
    
    	char *wave;
    
    	register snd_pcm_uframes_t count, frames;	
    	
    	int datei;
    	
    	unsigned int WaveSize;
    	
    	datei = open(waveDatei.c_str(), 00);
    		
    	read(datei, &head, sizeof(FILE_head));
    
    	read(datei, &chead, sizeof(CHUNK_head));
    
    	read(datei, &format, sizeof(FORMAT));
    
    	wave = (char *) malloc(head.Length);
    	
    	read(datei, wave, head.Length);
    
    	WaveSize = head.Length * 8 / ((unsigned int)format.wBitsPerSample * (unsigned int)format.wChannels);
    
    	close(datei);
    
    	Init(name, format.wChannels, format.dwSamplesPerSec, format.wBitsPerSample);
    	
    	count = 0;
    	
    	do
    	{
    		frames = snd_pcm_writei(soundKarte, wave + count, WaveSize - count);
    
    		if (frames < 0) frames = snd_pcm_recover(soundKarte, frames, 0);
    		if (frames < 0)
    		{
    			printf("Kann wav nicht abspielen: %s\n", snd_strerror(frames));
    			break;
    		}
    
    		count += frames;
    
    	} while (count < WaveSize);
    
    	if (count == WaveSize) snd_pcm_drain(soundKarte);
    
    	free(wave);
    
    	UnInit();
    
    	return 0;
    }
    
    vector<int> audioCapture(int sek, string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	int err, zielzeit;
    	
    	char *puffer;
    	 
    	vector<int> input;
    	
    	time_t t;
    	
    	t = time(NULL);
    	
    	zielzeit = t + sek;
    	
    	puffer = (char *) malloc(1);
    	
    	cout << "Beginne Aufnahme von " << sek << " Sekunden!" << endl;
    	
    	if(InitCapture(name, channels, actualRate, WaveBits))
    	{
    		while(t < zielzeit)
    		{
    			err = snd_pcm_readi(soundKarte, puffer, 1);
    			
    			if(err < 0) cout << "Fehler bei der Aufnahme!" << endl;
    			
    			input.push_back(puffer[0]);
    
    			t = time(NULL);
    		}
    		
    		UnInit();
    	}
    	else cout << "Bei der Initialisierung ist ein Fehler aufgetreten!" << endl;
    	
    	cout << "Aufnahme beendet!" << endl;
    	
    	return input;
    }
    
    void playCaptured(char *wave, unsigned int WaveSize, string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	register snd_pcm_uframes_t count, frames;	
    	
    	Init(name, channels, actualRate, WaveBits);
    
    	WaveSize = WaveSize * 8 / WaveBits * channels;
    
    	count = 0;
    	
    //	for(int i=0;i<WaveSize-2;i++) printf("%d/%d -> %d\n", i, WaveSize, wave[i]);
    	
    	do
    	{
    		frames = snd_pcm_writei(soundKarte, wave + count, WaveSize - count);
    
    		if(frames < 0) frames = snd_pcm_recover(soundKarte, frames, 0);
    		if(frames < 0)
    		{
    			printf("Kann wav nicht abspielen: %s\n", snd_strerror(frames));
    			break;
    		}
    
    		count += frames;
    
    	} while (count < WaveSize);
    
    	if (count == WaveSize) snd_pcm_drain(soundKarte);
    
    	UnInit();
    }
    Die neue Main

    Code:
    #include <iostream>
    #include <vector>
    
    #include <stdio.h>
    
    #include "diaSound.hpp"
    
    int main()
    {
    	vector<int> input;
    
    	unsigned int i;
    
    	char *wave;
    	
    	input = audioCapture(5, "plughw:1,0", 1, 44100, 8);
    	
    	wave = (char *) malloc(input.size());
    	
    	for(i=0;i<input.size();i++)
    	{
    		wave[i] = input[i];
    	} 
    	
    	playCaptured(wave, input.size(), "plughw:1,0", 1, 44100, 8);
    	
    	free(wave);
    	
    	return 1;
    }
    Habe es jetzt extra für dich auf char * umgestellt .

    Interessant ist, bei 16 Bit rauscht es ohne Ende. Bei 32 Bit kommt überhaupt kein Sound, bei 8 Bit ist leichtes Rauschen und man hört das was man in das Mikro rein spricht ^^. Wieder ein Punkt erledigt.

    Jetzt geht es weiter!

  2. #2
    HaWe
    Gast
    wie wav files kodiert sind, weiß ich nicht, ich habe ja nur mit Lautstärke-Schwankungen experimentiert.
    Dass Werte von 0...255 ankommen wundert mich nicht, aber ich vermute, die sind gruppiert in int16-Blöcke (bei 16-bit-sampling), einmal rechter und einmal linker Kanal.

    wenn du allerdings mit 8 bit sampelst, sind es sicher einzelne Bytes, nicht int16.

    Bei ausschließlicher Verwendung von expliziten Datentypen hat man übrigens noch einen enormen Geschwindigkeitsvorteil
    (int32_t ist auch hier beim Raspi schneller als int16_t).

    sind nämlich sowohl wave als auch input vom selben Typ (switchen wir ruhig mal auf int32_t, das ist ja mit int auf ARMs meist identisch ...)
    int32_t wave[FESTE_LAENGE], input[FESTE_LAENGE];

    dann ist das hier nämlich -zigmal schneller als iterativ einzelne Zellen rüberzukopieren...:
    memcpy(wave, input, sizeof(input) );

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Was mir aufgefallen ist, wenn das Mikro wenig oder gar keine Geräusche wahr nimmt ist der Wert in der Regel um die 128 herum. Gehe ich davon aus das es sich dabei so gesehen um die 0 Linie handelt?

    Interessant dürfte aber auch sein, kann man mit einer Soundkarte auch wirklich von zwei Mikros Stereo aufnehmen? Das wäre bei einem Bot schon sinnvoll da man damit auch mehr oder weniger orten könnte von wo das Geräusch kommt.

  4. #4
    HaWe
    Gast
    vielleicht kann wer anderes helfen?
    Ich weiß auch nicht mehr als dieses hier:

    https://de.wikipedia.org/wiki/RIFF_W...0.9C-Abschnitt

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Das kenne ich doch irgendwo her .

    Ich werde nachher mal ein bisschen mit der Eingabe rum spielen. Lernen beim tuen oder wie das heisst ^^

    - - - Aktualisiert - - -

    Ich habe die Werte mal in einer CSV gespeichert und in LibreOffice geplottet. Sieht in der Tat so aus wie ich es erhofft hatte. Der grosse Ausschlag ist ein von mir gesprochenes Hallo und ich nehme an, diese dicke Linie davor und danach stellt das Rauschen dar. Ich denke das kann man raus filtern und das Wort ist ja auch sehr gut zu erkennen finde ich.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken soundtest.png  

  6. #6
    HaWe
    Gast
    die FFT wird dir die Frequenzen sehr genau zeigen, die das Rauschen verursachen.
    Dazu müsstest du den FFT-Plot von reinem Rauschen betrachten und dann den Plot, der in deinem Wort vorkommt.
    Die Spikes, die in beiden in identischer Weise vorkommen, sind unspezifisch, tragen keine Information.
    Ob man sie einfach isoliert aus dem FFT-Array herauslöschen kann, wäre ein Versuch wert: erzeugt man dann die FFT-Rücktransformation, müsste man nämlich ein bereinigtes Wave Signal hören können.

    das funktioniert natürlich nur bei identischen, reproduzierbaren Rauschquellen/-Arten und ist daher kein allgemeiner Lösungsweg.
    Aber immerhin kannst du die Rausch-Frequenz-Daten als Basis für statistische Rauschfilter verwenden wie ich sie oben genannt habe.

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Ich bin mir nur noch nicht ganz sicher, ob deine Idee den Input erst zu speichern eine gute Idee ist. Das Verzögert die Geschichte schon ganz Ordentlich!

    Ich versuche als Nächstes mal, was passiert wenn ich nur Daten über 138 und unter 118 an die Ausgabe gebe. Das sollte auf jeden Fall die Geschichte auf das Wesentliche verkürzen.

    Ein Gedanke der mir auch kam, letzten Endes muss sich das ja nicht mehr so anhören wie es original war. Solang es sich immer auf die selbe Art verändert sollte es ja egal sein. Hauptsache der Bot weiss was er damit anzufangen hat.

    Nächste Frage, wie sehr ähneln sich stimmen? Wenn ich ein Wort spreche und er es erkennt. Würde er es auch bei dir erkennen?

Ä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