-
        

Ergebnis 1 bis 8 von 8

Thema: Hilfe mit Audio

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    321

    Hilfe mit Audio

    Anzeige

    Mahlzeit!

    Ich muss um Hilfe rufen. Google, mein Freund, will da einfach keine passende Antwort finden.

    So es geht um folgendes. Ich brauche ein Audiosignal. Das an sich wäre weniger das Problem. Mein Code, um das Signal von einer Soundkarte mit Alsa abzurufen und auch wieder auszugeben sehen so aus:

    Code:
    void audioAufzeichnung(double *input, int max, string name, unsigned int channels, unsigned int actualRate, unsigned short inputBits)
    {
    	int i=0;
    	
    	double *puffer;
    	 
    	puffer = (double *) malloc(1);
    	
    	if(InitCapture(name, channels, actualRate, inputBits))
    	{
    		while(i < max)
    		{
    			snd_pcm_readi(soundKarte, puffer, 1);
    			
    			input[i] = puffer[0];
    
    			i++;
    		}
    
    		free(puffer);
    		
    		UnInit();
    	}
    }
    
    void playAufzeichnung(double *array, unsigned int inputSize, string name, unsigned int channels, unsigned int actualRate, unsigned short inputBits)
    {
    	uint8_t *puffer;
    
    	register snd_pcm_uframes_t count, frames;	
    
    	Init(name, channels, actualRate, inputBits);
    
    	puffer = (uint8_t *) malloc(inputSize);
    	
    	for(int32_t i=0;i<inputSize;i++) puffer[i] = array[i];
    
    	inputSize = inputSize * 8 / inputBits * channels;
    
    	count = 0;
    
    	do
    	{
    		frames = snd_pcm_writei(soundKarte, puffer + count, inputSize - count);
    
    		if(frames < 0) frames = snd_pcm_recover(soundKarte, frames, 0);
    		if(frames < 0)
    		{
    			break;
    		}
    
    		count += frames;
    
    	} while(count < inputSize);
    
    	if(count == inputSize) snd_pcm_drain(soundKarte);
    
    	UnInit();
    }
    Mein Problem ist folgendes. Benutze ich diesen Code und nehme anstatt double int32_t funktioniert es. Nun habe ich ja aber hier im Forum und auch sonst im Netz immer wieder gelesen, man solle doch für Audiodaten double nehmen. Das mag mit dem Einlesen der Daten von der Soundkarte noch funktionieren. Will ich es jedoch wieder ausgeben kommt dann nur ein tiefes Brummen.

    Nun würde ich den Schuldigen auf

    Code:
    	uint8_t *puffer;
    
           ..
    
    	puffer = (uint8_t *) malloc(inputSize);
    	
    	for(int32_t i=0;i<inputSize;i++) puffer[i] = array[i];
    schieben. Jedoch waren alle Versuche snd_pcm_writei() mit etwas Anderem wie mit einem char, bzw uint8_t Array zu füttern äusserst Schmerzhaft für die Ohren. Das gibt immer einen brutal hohen Piepton.

    Kann mir da jemand helfen?

    - - - Aktualisiert - - -

    Lol okay, hab gerade gesehen das ich doch nur int16 brauche. Das kriege ich dann wieder hin ^^.

    Das mit Double würde mich dann doch interessieren.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,

    Der Fehler liegt bei malloc(1);
    Das reserviert 1 Byte, da passt aber kein double rein!
    Was genau passiert kann dir jetzt aber keiner sagen, im Prinzip überschreibst du etwas, was hinter dem Speicherbereich von malloc() liegt.
    Damit der Heap nicht zu sehr fragmentiert, reserviert malloc() immer ein ganzzahliges vielfaches einer konstanten Anzahl Bytes, der Wert nennt sich Granularity.

    Richtig für die Benutzung von malloc ist:

    puffer = (double *) malloc( sizeof(double) );

    Ob das jetzt zum Aufruf von snd_pcm_readi() passt, ist eine andere frage und steht in der Beschreibung dieser Funktion.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    321
    Kopf -> Tisch

    Da kommen die Schwächen von C++ zum Tragen ^^. Also die Schwächen die sich bei mir selbst einschleichen. Als ich noch in Ansi C gearbeitet habe wäre mir das nicht passiert. Da wird man eben durch string usw. doch schon sehr verwöhnt.

    Danke schon mal. Ich versuche es mal.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,
    Zitat Zitat von hirnfrei Beitrag anzeigen
    Kopf -> Tisch
    Danke schon mal. Ich versuche es mal.
    Müsste eigentlich hohl tönen, bei hirnfrei

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Das reicht aber evtl. auch nicht. Der Parameter für die Anzahl in snd_pcm_readi() gibt _nicht_ die Anzahl der Bytes an sondern die Anzahl der zu lesenden Sample-Frames. Die Größe dieser Frames hängt davon ab, wieviele Kanäle und welchen Datentyp Du für ein Sample bei der Initialisierung der Soundschnittstelle eingestellt hast.

    Ein Kanal mit SND_PCM_FORMAT_S16_LE sind z.B. 2 Bytes pro Frame die Du im Puffer zur Verfügung stellen mußt.
    Bei zwei Kanälen sind's vier. Dazu ist zu beachten, wenn Du zwei Kanäle hast, wie die Anordnung der Samples ist. Wenn Du SND_PCM_ACCESS_RW_INTERLEAVED in snd_pcm_hw_params_set_access() angegeben hast, musst Du
    Code:
    snd_pcm_readi(hndl, buf, 4);
    aufrufen. _readi() weil interleaved (es gibt noch_readn() für non interleaved) und dann bedeutes das, das wenn du _S16_LE, 2 Kanäle angegeben hast, das der Puffer 2 * 4 * sizeof(int16_t) groß sein muß (Anzahl der Kanäle * Anz.d. Frames * Sample-Größe). Sonst schäpperts.
    Die Samples für den ersten Kanal liegen dann in buf[0,2,4,6] und für den zweiten Kanal in buf[1,3,5,7].
    Geändert von botty (28.06.2016 um 17:43 Uhr)

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    321
    Wie ich merke ist Audio gar nicht so einfach wie man denken sollte ^^.

    Zum Glück brauche ich aktuell nur ein Kanal.

    Aber mal schauen ob ich das richtig verstanden habe

    Anstelle von

    Code:
    snd_pcm_readi(hndl, buf, 4);
    könnte ich auch

    [code]
    snd_pcm_readi(hndl, buf, channel*2);
    [code]

    verwenden?

    Wäre dann bei SND_PCM_FORMAT_S32 das dann * 4?

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Der letzte Parameter ist die Anzahl der Frames, nicht die Puffergröße! Diese Anzahl wählt man am besten so groß, das man eine Periode aus ALSA in einem Rutsch auslesen kann (und wie ich feststellen mußte ist meine letzte ALSA Zeit zu lange her, als das ich das im Gedächtnis gehabt hätte).
    Schau Dir mal das Listing 4 in diesem Linux Journal Artikel an, ich hoffe dann wird's verständlicher.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    19.01.2016
    Ort
    Saarbrücken
    Beiträge
    321
    Das sieht sehr gut erklärt aus. Das werde ich mir mal genauer zu Gemüte führen! Vielen Dank!

Ähnliche Themen

  1. Audio-Differenzverstärker
    Von miniregler im Forum Elektronik
    Antworten: 17
    Letzter Beitrag: 20.04.2013, 10:47
  2. [ERLEDIGT] Audio via LAN - Endstelle
    Von robo_tom_24 im Forum Raspberry Pi
    Antworten: 1
    Letzter Beitrag: 28.07.2012, 18:06
  3. Audio Multiplexer
    Von Crock im Forum Elektronik
    Antworten: 11
    Letzter Beitrag: 12.01.2009, 18:08
  4. Audio-Mischer
    Von thewulf00 im Forum Elektronik
    Antworten: 10
    Letzter Beitrag: 06.08.2008, 15:13
  5. Audio => AVR (LM339)
    Von Jaecko im Forum Elektronik
    Antworten: 11
    Letzter Beitrag: 03.08.2008, 22:09

Berechtigungen

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