[RISOLTO] Aiuto con RtAudio su Linux

di il
4 risposte

[RISOLTO] Aiuto con RtAudio su Linux

Ciao a tutti, sto cercando di imparare ad usare la libreria RtAudio 4.0.12 in Linux. Questa libreria serve per gestire l'I/O audio. Seguendo quanto descritto nel tutorial di questa libreria, ho provato a scrivere questo codice:

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <stdio.h>     // FILE, fopen(), fwrite(), fclose()

using namespace std;

typedef signed short MY_TYPE;
#define FORMAT RTAUDIO_SINT16

struct InputData {
  MY_TYPE *buffer;
  unsigned long bufferBytes;
  unsigned long totalFrames;
  unsigned long frameCounter;
  unsigned int channels;
};

int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
                  double streamTime, RtAudioStreamStatus status, void *userData )
{
   if ( status )
      cout << "Stream overflow detected!" << endl;
      
   // Do something with the userData in the "inputBuffer" buffer.
   InputData *iData = (InputData *) userData;
   
   // Simply copy the data to our allocated buffer.
   unsigned int frames = nBufferFrames;
   if ( iData->frameCounter + nBufferFrames > iData->totalFrames ) {
      frames = iData->totalFrames - iData->frameCounter;
      iData->bufferBytes = frames * iData->channels * sizeof( MY_TYPE );
   }
   //unsigned long offset = iData->frameCounter * iData->channels;
   FILE *fd;
   fd = fopen( "record.txt", "wa" );
   fwrite( inputBuffer, iData->bufferBytes, iData->totalFrames * iData->channels, fd );
   fclose( fd );
   
   iData->frameCounter += frames;

   return 0;
}

int main()
{
   double time = 2.0;
	
   RtAudio adc;
   if ( adc.getDeviceCount() < 1 ) {
      cout << "\nNo audio devices found!\n";
      exit( 0 );
   }
   
   RtAudio::StreamParameters parameters;
   parameters.deviceId = adc.getDefaultInputDevice();
   parameters.nChannels = 2;
   parameters.firstChannel = 0;
   unsigned int sampleRate = 44100;
   unsigned int bufferFrames = 256;      // 256 sample frames

   InputData data;
   data.buffer = 0;
   
   try {
      adc.openStream( NULL, &parameters, RTAUDIO_SINT16, sampleRate, &bufferFrames, &record);
      
      data.bufferBytes = bufferFrames * parameters.nChannels * sizeof( MY_TYPE );
      data.totalFrames = (unsigned long) (sampleRate * time);
      data.frameCounter = 0;
      data.channels = parameters.nChannels;
      unsigned long totalBytes;
      totalBytes = data.totalFrames * data.channels * sizeof( MY_TYPE );

      // Allocate the entire data buffer before starting stream.
      data.buffer = (MY_TYPE*) malloc( totalBytes );
      if ( data.buffer == 0 ) {
         cout << "Memory allocation error ... quitting!\n";
         if ( adc.isStreamOpen() ) adc.closeStream();
         if ( data.buffer ) free( data.buffer );
      }
      
      adc.startStream();
   }
   catch ( RtError& e ) {
      e.printMessage();
      if ( adc.isStreamOpen() ) adc.closeStream();
      if ( data.buffer ) free( data.buffer );
      exit( 0 );
   }

   char input;
   cout << "\nRecording ... press <enter> to quit.\n";
   cin.get( input );

   try {
      // Stop the stream
      adc.stopStream();
   }
   catch (RtError& e) {
      e.printMessage();
   }

   if ( adc.isStreamOpen() ) adc.closeStream();

   return 0;
}
di seguito riporto anche il Makefile per compilarlo:

PROGRAMS = udito
RM = /bin/rm
SRC_PATH = ..
INCLUDE = ..
OBJECT_PATH = Release
vpath %.o $(OBJECT_PATH)

OBJECTS	=	RtAudio.o 

CC       = g++
DEFS     =   -DHAVE_GETTIMEOFDAY -D__LINUX_ALSA__
CFLAGS   = -O2 -Wall
CFLAGS  += -I$(INCLUDE) -I./include
LIBRARY  = -lpthread -lasound 

%.o : $(SRC_PATH)/%.cpp
	$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@

%.o : ./include/%.cpp
	$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@

all : $(PROGRAMS)

udito : udito.cpp $(OBJECTS)
	$(CC) $(CFLAGS) $(DEFS) -o udito udito.cpp $(OBJECT_PATH)/*.o $(LIBRARY)

clean : 
	$(RM) -f $(PROGRAMS)
	$(RM) -f *.txt *~ *.exe
	$(RM) -fR *.dSYM
Il programma deve registare in un file record.txt cio' legge dal microfono dal momento che avvio il programma fino a quando chiudo la registrazione premendo il pulsante enter.
Il problema che ottengo con ./udito: segmentation fault.
Mi potete aiutare a capire dove sbaglio e come devo correggere l'errore ?

4 Risposte

  • Re: [RISOLTO] Aiuto con RtAudio su Linux

    Non ho esperienza diretta con questa libreria; visto però che finora nessuno ti ha risposto, per capire il problema del segmentation fault ti suggerisco alcune strade:
    1- inserire più printf() che puoi, per individuare il punto in cui c'è il crash
    2- parti da un main() che non contiene niente e aggiungi una alla volta le varie parti, per capire qual è la parte che da fastidio
    3- prova ad attivare i debug symbols di gcc (metti -g nelle opzioni di compilazione) e prova a debuggare (io di solito uso kdbg).
    A mio avviso, comunque, se RtAudio è una classe potrebbe non essere molto indicato utilizzarlo come variabile locale, potrebbe esaurirsi lo stack (per capire se è quello prova a spostarlo fuori dal main()).
  • Re: [RISOLTO] Aiuto con RtAudio su Linux

    Grazie candaluar per il tuo consiglio, provero' a fare come dici tu.
    Una domanda kdbg e' presente di default su Slackware 14.0 oppure bisogna installarlo ?
  • Re: [RISOLTO] Aiuto con RtAudio su Linux

    Su slackware non so; per esperienza (ma di qualche anno fa) so che su Ubuntu non c'è e probabilmente anche le altre distribuzioni non lo inseriscono. Magari qualcuno del forum che è più aggiornato di me può rispondere a questa domanda ed eventualmente ci può dire se ci sono anche altri debugger per Linux (oltre a gdb che è a linea di comando e al citato kdbg).
  • Re: [RISOLTO] Aiuto con RtAudio su Linux

    Ho risolto scaricando lo SlackBuild di kdbg. Ho anche trovato, grazie a kdbg, l'errore di segmentation fault sul codice che avevo riportato. L'errore è la mia dimenticanza nel mettere
    
    (void *)&data
    
    in
    
    adc.openStream( NULL, &parameters, RTAUDIO_SINT16, sampleRate, &bufferFrames, &record);
    
    ossia
    
    adc.openStream( NULL, &parameters, RTAUDIO_SINT16, sampleRate, &bufferFrames, &record, (void *)&data);
    
Devi accedere o registrarti per scrivere nel forum
4 risposte