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, ¶meters, 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 ?