- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
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
    bei playWave(); übergibst du ein Dateiname. Dieser wird geladen, die Header und Chunk ausgelesen, damit die Soundkarte geöffnet und das dann abgespielt.

    Bei playCaptured(); übergibst du nur die Rohdaten und gibst die Daten für die Soundkarte vor.

    Vereinheitlichen dürfte schwierig werden, da man dann für playWave ebenfalls die Vorgaben für die Soundlarten treffen müsste, auch wenn diese dann von der Datei überschrieben werden.

  2. #2
    HaWe
    Gast
    achso, playCaptured spielt einen array ab, keinen File, richtig?
    vlt wäre dann
    playSoundarray
    besser, denn nicht alles ist ja "gecaptured"... 8-)

    aber was ist denn
    string wave
    ?

    wieso string?

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Das kommt aus der Funktion snd_pcm_writei();. Die erwartet ein char *. Warum auch immer.

  4. #4
    HaWe
    Gast
    dann mach doch auch
    char * wave;
    da gibts sonst immer so hässliche *WARNINGS* vom Compiler

    char ist allerdings komisch bei int16 (16bit encoding)

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Ich mag String aber lieber da ich mich da nicht um den Speicher kümmern muss. Zu meinen reinen Ansi-C Zeiten war das immer mein grösstes Problem. Hier mal zu wenig allociert, peng Absturz usw. Das macht String viel viel einfacher.

    Und Warnungen stören mich wenig

  6. #6
    HaWe
    Gast
    wenn du deinen wave string gesäubert und entrauscht hast -
    dann muss er ja in einen komplexen array kopiert werden (type casting (float), in reelen Teil, imaginärer bleibt leer == 0 ).
    Geht das mit string genauso einfach wie mit char[] ?

    und wieso jetzt char[] bei int16 (16bit encoding) ?

    ps,
    übrigens musst du dafür sowieso die array-Größe deines wave arrays festlegen, um es der FFT zu unterwerfen.
    char (oder int16_t) wave[SHRT_MAX] // == 32767
    wäre also eh die richtige Array-Größe, ohne \0 am Schluss wie bei strings.

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    Du siehst ja, es kommt ein vector<int> bei der Aufnahme heraus. Was man damit dann letzten Endes macht ist ziemlich egal. Man muss es ja auch nicht mehr aus geben. Es geht ja darum das der Bot versteht was man von ihm will, nicht das er wiederholt was man ihm sagt.

    Sagen wir so. Du brauchst für Spracherkennung letzten Endes nur das audioCapture();. Da kommen die Daten und dann wird damit gearbeitet. Da ich noch keinen Plan habe wie FFT überhaupt funktioniert kann ich dazu aber auch nichts sagen. Da du aber da schon Erfahrung hast, wie würdest du denn aus dem ankommenden vector<int> passende Daten für FFT machen?

    Hast du eigentlich eine Idee wie man den Scheiss entrauschen kann?

  8. #8
    HaWe
    Gast
    das ist das input, das ich u.a. hier gefunden habe:

    vector<int> audioCapture(int sek, string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    int err, zielzeit;
    char *puffer;
    vector<int> input;


    was du intern nur in den Funktionen verwendest, ist für mich natürlich nicht wichtig, aber alles was weiterverarbeitet wird (gefiltert, extrahiert, geglättet, geschnitten, transformiert) muss feste array-Größen haben.

    Das Ziel ist ja (ich hatte es schon erwähnt):

    du hast aufgenommenene Rohdaten (die können länger oder kürzer sein als 2^15 Werte oder "packages") als bytes (strings) oder ints, keine Ahnung,
    die müssen in einen int32_t array überführt werden, wo sie nur max. 32767==SHRT_MAX Zellen belegen dürfen
    (sample rate 11-12kHz, also ca. 3 sec.),
    dann kommt der double-Array von doppelter Länge (65535==USHRT_MAX) ins Spiel, dessen (mindestens) 2. Hälfte mit Nullen aufgefüllt wird.

    Länger als 3 sec dürfen also die gesprochenen Kommandos nicht werden (egal ob 1 oder mehrere Wörter)


    wav enthält dann im "Roh-array" 2 Kanäle, und wir verarbeiten aber nur 1 Kanal, also muss jedes 2. Datenpaket raus geschmissen werden.
    Es sind dann wohl 16-bit ints, oder wie ist das, das ist schließlich wichtig, denn das muss ja exakt in floats (double) überführt werden.
    Also immer 2 bytes als int16 lesen und in den Bearbeitungs-Array als int32 kopieren (li Kanal), dann 2 bytes verwerfen (re Kanal), dann wieder 2 lesen+kopieren (li Kanal) usw. ?
    Oder andersrum? Oder andere Datenblöcke? Da kommts jetzt drauf an.

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    397
    So ich habe dann etwas rum gebastelt. Jetzt nimmt er genau SHRT_MAX auf. Hast recht, bei 12Khz sind es um die 3 Sekunden, rauscht dafür aber auch mehr.

    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;
    }
    
    vector<int> audioCapture(int SHRT_MAX, string name, unsigned int channels, unsigned int actualRate, unsigned short WaveBits)
    {
    	int err, i=0;
    	
    	char *puffer;
    	 
    	vector<int> input;
    	
    	puffer = (char *) malloc(1);
    	
    	cout << "Beginne Aufnahme" << endl;
    	
    	if(InitCapture(name, channels, actualRate, WaveBits))
    	{
    		while(i < SHRT_MAX)
    		{
    			err = snd_pcm_readi(soundKarte, puffer, 1);
    			
    			if(err < 0) cout << "Fehler bei der Aufnahme!" << endl;
    			
    			input.push_back(puffer[0]);
    
    			i++;
    		}
    
    		free(puffer);
    		
    		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();
    }
    Das ist der neue Header und hier kommt das neue main:

    Code:
    #include <iostream>
    #include <vector>
    #include <fstream>
    
    #include <stdio.h>
    
    #include "diaSound.hpp"
    
    bool debug = false;
    
    int main()
    {
    	fstream datei;
    	
    	vector<int> input;
    
    	unsigned int i, SHRT_MAX = 32767;
    
    	char *wave;
    	
    	input = audioCapture(SHRT_MAX, "plughw:1,0", 1, 12000, 8);
    	
    	wave = (char *) malloc(input.size());
    	
    	if(debug) datei.open("test.csv", ios::out);
    	
    	for(i=0;i<input.size();i++)
    	{
    		wave[i] = input[i];
    		if(debug) datei << input[i] << endl;
    	} 
    	
    	if(debug) datei.close();
    	
    	playCaptured(wave, input.size(), "plughw:1,0", 1, 12000, 8);
    	
    	free(wave);
    	
    	return 1;
    }
    Zufrieden soweit?

  10. #10
    HaWe
    Gast
    stelle gerade fest:

    die float (double) arrays müssen USHRT_MAX+1 groß sein ( == exakt 2^16 ),
    für SHRT_MAX soll es so bleiben.

    SHRT_MAX und USHRT_MAX sind C-Konstanten, die brauchst du nicht mehr definieren
    (oder wir verwenden explizit 32767, 65536)

    http://www.cplusplus.com/reference/climits/


    und bitte auch möglichst nirgends int oder unsigned int verwenden, immer nur int32_t und uint32_t

    das gleiche gilt für char und unsigned char (stattdessen möglichst int8_t, uint8_t)



    in main steht immer noch

    vector<int> input;

    das müsste dann auch zu
    int32_t input[SHRT_MAX]
    werden

Seite 1 von 2 12 LetzteLetzte

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

LiFePO4 Speicher Test