- LiFePO4 Speicher Test         
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
    zu den ints: du wirst (irgendwann) 64-bit ints haben (Pi 3 = 64bit µC), ich aber weiterhin 32bit (Pi 2 = 32bit µC):
    dann stimmen die Arraygrößen auf unseren System nicht mehr überein.

    zu den char[] arrays:
    ich weiß nicht, was dein char[] array macht bzw was drin steht.
    Wenn die Aufnahmefunktion die Rohdaten in char[] speichern muss, muss man es dort erst so lassen, dann aber als nächstes in int32 arrays umkopieren, bevor man weitermacht.

    Aber dazu muss man wissen, wie die Datenpakete pro Einzelpaket kodiert sind.
    sind es immer 4 bytes, erst 2 bytes für li, dann 2 bytes für rechts?

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    audioCapture() läuft schon auf int32_t. So kommen auch die Daten an, eben als Vector, das ändert aber auch an der Grösse nichts.

    was mit playCaptured ist verstehe ich nicht. Das stürzt sofort ab wenn ich es aufrufe! In die Funktion kommt es gar nicht. Das stürzt beim Aufrufen schon ab.

  3. #3
    HaWe
    Gast
    gings denn vorher mit playCaptured?

    zum Daten-Record und Aufbereiten -
    vielleicht hast du mich falsch verstanden, und ich bin ja nicht auf denem Programmier-Level:

    Ich hatte mir vorgestellt, dass anstelle von
    string oder char* wasauchimmer
    jetzt
    uint8_t (!!) wasauchimmer (nicht int32_t !!)
    verwendet werden soll, aber mit festen array Grenzen;

    das gleiche gilt für vector<int> input etc,
    stattdesen
    int32_t input[FESTE_GROESSE]


    Das hätte den Sinn, dass man es immer mit identisch großen records zu run hat, was das Aufbereiten der Daten vereinfacht.
    Wenn du lieber erst mit Vektoren variabler Größe arbeitest, auch ok, dann muss es im nächsten Schritt eben in arrays von konstanter Größe verfrachtet werden, und zwar nur MONO (1 Kanal).

    Weil es nur MONO sein darf, muss man wissen, welche der ganzen Bytes genau die richtigen Töne darstellen, ohne die andere Spur mitzukopieren.

    Die konstante Größe ist wichtig, denn wie du sicher weißt, arbeitet ja die FFT nur mit arrays, die eine Länge haben, die sich als 2^n (hier: 2^16 == 65536) darstellen lässt.

    Für die Cross Correlation darf dafür nur höchstens die erste Hälfte mit Daten gefüllt sein, mindestens die 2. Hälfte ausschließlich mit Nullen.

    Daher bleibt für Daten dann maximal ((2^n)/2) -1 (== 2^15 -1 == 32767 ) übrig, und das muss die exakte Länge der int32-MONO-Records sein, die man erst cutted und filtert und dann (zu floats konvertiert) der FFT übergibt.


    Wann du also anfängst mit fixen arrays, ist prinzipiell egal, aber Vektoren taugen dazu nicht, und daher muss man vektoren auch erst wieder in fixe arrays umwandeln, bevor man mit der eigentlichen Arbeit anfangen kann, und daher: je früher, je besser.

    Ist dir klar, wie ich das meine?
    Geändert von HaWe (04.06.2016 um 11:45 Uhr)

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Ich nehm es doch mal an ^^.

    Ich bastel das nachher um. Allerdings kann es ein wenig dauern. Ich musste vorhin zum Essen meinen Bot (Also die Holzplatte auf dem die Platinen drauf geschraubt sind ^^) vom Tisch runter holen, bin hängen geblieben und hab mir da Kabel abgerissen. Demnach hat der arme Raspi zur Zeit keinen Strom . Sobald das geregelt ist baue ich das Programm nochmal etwas um.

    Mir kam da aber auch ein Gedanke. Du sprachst davon, die Aufnahme soll immer nur dann beginnen wenn eine gewisse Lautstärke überschritten ist. Da kam mir der Gedanke, ich habe noch ein Soundmodul für den Arduino. Das ist ja dafür da bei einer gewissen Lautstärke ein Signal zu geben. Das könnte man da ja für nutzen um das Ganze zu Automatisieren. Derzeit ist es ja so, das Programm startet, nimmt sofort auf und fertig. Mit dem Teil könnte mein Aruduino ja ein Signal an den Raspi schicken, die Lautstärke ist überschritten und der nimmt dann automatisch die feste Grösse lang auf.

    - - - Aktualisiert - - -

    So, der gute Raspi hat wieder Saft und wie versprochen hier eine char und vector bereinigte Main

    Code:
    #include <iostream>
    #include <vector>
    #include <fstream>
    
    #include <stdio.h>
    #include <limits.h>
    
    #include "diaSound.hpp"
    
    bool debug = false;
    
    int main()
    {
    	fstream datei;
    	
    	int32_t input[SHRT_MAX];
    
    	int i;
    
    	uint8_t *wave;
    	
    	audioCapture(input, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    	
    	wave = (uint8_t *) malloc(SHRT_MAX+1);
    	
    	if(debug) datei.open("test.csv", ios::out);
    	
    	for(i=0;i<SHRT_MAX;i++)
    	{
    		wave[i] = input[i];
    
    		cout << i << " -> " << input[i] << endl;
    
    		if(debug) datei << input[i] << endl;
    	} 
    	
    	if(debug) datei.close();
    
    	playCaptured(wave, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    	
    	free(wave);
    	
    	return 1;
    }
    und die Header dazu

    Code:
    #include <alsa/asoundlib.h>
    
    #include <iostream>
    #include <vector>
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.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;
    }
    
    void audioCapture(int32_t *input, int max, string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	int err, i=0;
    	
    	int32_t *puffer;
    	 
    	puffer = (int32_t *) malloc(1);
    	
    	cout << "Beginne Aufnahme" << endl;
    	
    	if(InitCapture(name, channels, actualRate, WaveBits))
    	{
    		while(i < max)
    		{
    			err = snd_pcm_readi(soundKarte, puffer, 1);
    			
    			if(err < 0) cout << "Fehler bei der Aufnahme!" << endl;
    			
    			input[i] = puffer[0];
    
    			i++;
    		}
    
    		free(puffer);
    		
    		UnInit();
    	}
    	else cout << "Bei der Initialisierung ist ein Fehler aufgetreten!" << endl;
    	
    	cout << "Aufnahme beendet!" << endl;
    }
    
    void playCaptured(uint8_t *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;
    	
    	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();
    }
    Zudem alles auf entsprechende Grösse SHRT_MAX ausgerichtet.

    Und jetzt?

  5. #5
    HaWe
    Gast
    ok, jetzt muss ich mir ein Bild von den wav-audio-Daten machen.
    in welchem array stehen jetzt die wav-Roh-Daten, die du vom Micro aufgenommen hast, und die jetzt weiterverarbeitet werden sollen?

    ist es

    in32_t input[SHRT_MAX]

    und enthält er noch beide Spuren (li+re) ?

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Richtig.

    input32_t input[SHRT_MAX];

    ist das was vom Mikro kommt. Direkt in diese Variable. Also da wird nicht erst noch was konvertiert oder so.

    Und zu besseren Verständnis, wie die audioCapture() funktioniert hier ne kleine Erklärung:

    Code:
    audioCapture(input, SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    
    audoCapture("Variable zum Speichern der Daten", "Aufzeichnungslänge", "Soundkarte", "Kanäle", "Frequenz", "Bit");
    Ich jammere rum weil tinyalsa keine gute Dokumentation hat und biete dann für meine Funktion ebenfalls keine Erklärung. Tztztztz.

    Wie du siehst, ich nehme nur mit einem Kanal auf.

    Okay, habe versucht eine CSV hoch zu laden, hat natürlich nicht geklappt . Versuch es mal hier http://www.kipperei.de/test.csv

  7. #7
    HaWe
    Gast
    ok, hab ich mir angeschaut.
    Es sind jetzt alles Zahlen in Byte-Größe.

    Betrachten wir jetzt mal diesen Array input, N == SHRTR_MAX Zellen mit jeweils 4 Bytes:

    Code:
    |----,----,----,----,----,----,----,----,----,----,---- .... ----,----,----,----,----,----,----,----,----,----,----|
      0     1    2    3    4    5    6    7    8    9   10  ....                                                   N=SHRT-MAX-1
    wie ist jetzt jede 4er-Bytes-Gruppe aufgebaut?

Ä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