Получить PortAudio записанные данные с помощью одного метода

Я работаю над гитарным тюнером на C ++. Я использую PortAudio для записи данных с микрофона. Код записи работает хорошо, если он помещен в основной класс. Тем не менее, я бы предпочел единственный метод в главном классе для извлечения записанных данных. Я создал отдельный класс (recordaudio.cpp) со всем кодом PortAudio, но когда я вызываю метод readStream этого класса из основного класса, я получаю сообщение:

Номер ошибки: -10000
Сообщение об ошибке: PortAudio не инициализирован

PortAudio уже создан в конструкторе класса «recordaudio.cpp», поэтому я не уверен, почему он так говорит.

Вот основной класс, вызывающий метод getAudioStream (buffer):

#include "autocorrelation.h"#include "peakpicking.h"#include "recordaudio.h"#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <alsa/asoundlib.h>
#include <unistd.h>

#define SAMPLE_RATE 44100
#define WINDOW_SIZE 1024
#define WIN_HAMMING 1
#define WIN_HANN 2
#define WIN_SINE 3

using namespace std;

int main(){
double max, average, val;
double frequency=0;
double period;

// Data buffers
double* buffer = (double*) malloc(sizeof(double)*WINDOW_SIZE);
double* buffer_snac = (double*) malloc(sizeof(double)*WINDOW_SIZE);

// Instantiate
recordaudio audio = recordaudio();
autocorrelation acf = autocorrelation(WINDOW_SIZE);
peakpicking pick = peakpicking(buffer_snac, WINDOW_SIZE);

while (true){
audioStatus = audio.getAudioStream(buffer);

// Autocorrelation function
acf.autocorrelation_snac(buffer, buffer_snac);

// Peak Picking
period = pick.getPeriod();

// Calculate frequency
frequency = SAMPLE_RATE/period;
cout  << "\r" << "frequency: " <<frequency << "  "  << flush;
}
audio.closeStream();

}

Файл recordaudio.h

#ifndef RECORD_AUDIO_H
#define RECORD_AUDIO_H
#include "portaudio.h"
class recordaudio {

private:
PaStreamParameters inputParameters;
PaError err;
PaStream *stream;

public:
recordaudio();
bool getAudioStream(double *buffer);
void closeStream();
};

#endif

Вот класс recordaudio.cpp. Идея состоит в том, чтобы постоянно вызывать метод getAudioStream (* buffer), который находится в этом классе.

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <alsa/asoundlib.h>
#include <unistd.h>
#include <algorithm>
#include "recordaudio.h"
#define SAMPLE_RATE 44100
#define WINDOW_SIZE 1024
#define WIN_HAMMING 1
#define WIN_HANN 2
#define WIN_SINE 3

#define NUM_CHANNELS    (1)
/* #define DITHER_FLAG     (paDitherOff)  */
#define DITHER_FLAG     (0) /**/
/* Select sample format. */
#define PA_SAMPLE_TYPE  paFloat32
#define SAMPLE_SILENCE  (0.0f)
#define PRINTF_S_FORMAT "%.8f"

using namespace std;

recordaudio::recordaudio( ){
err = Pa_Initialize();
if( err != paNoError ) goto error;

inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto error;
}

inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;

err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,     /* &outputParameters, */
SAMPLE_RATE,
WINDOW_SIZE,
paClipOff,/* we won't output out of range samples so don't bother clipping them */
NULL,     /* no callback, use blocking API */
NULL );   /* no callback, so no callback userData */if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
cout << "Now recording!!" << endl;

error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}

bool recordaudio::getAudioStream(double *buffer){
err = Pa_ReadStream(stream, buffer, WINDOW_SIZE);
if( err != paNoError ) goto error;
return true;

error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return false;}

void recordaudio::closeStream(){
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;

error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
}

0

Решение

    if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
cout << "Now recording!!" << endl;

error:
Pa_Terminate();

Так что сразу после «сейчас записи» — вы вызываете PA_Terminate (), вероятно, не то, что вы хотели. GOTO это злой и лейбл в этом случае смутил вас, думая, что он пойдет туда, только если вы позвоните goto error. Это не так. Этикетка — всего лишь маркер, и исполнение будет радостно продолжаться.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector