Worker: use pulseaudio-simple API to get audio

This commit is contained in:
Louis-Joseph Fournier 2016-01-05 15:20:43 +01:00
parent e3a3d25cbd
commit dcf28780b1
5 changed files with 81 additions and 19 deletions

View file

@ -1,9 +1,11 @@
QT += qml quick gui multimedia dbus
TARGET = Tuner
CONFIG += c++11 debug
CONFIG += c++11 debug link_pkgconfig
# PKGCONFIG += libpulse
DEFINES += TARGET=\""$(TARGET")\"
PKGCONFIG += libpulse-simple
SOURCES += \
src/desktop.cpp \

View file

@ -1,10 +1,11 @@
QT += qml quick gui multimedia dbus
TARGET = harbour-sailtuner
CONFIG += c++11 sailfishapp sailfishapp_i18n sailfishapp_no_deploy_qml
CONFIG += c++11 sailfishapp sailfishapp_i18n sailfishapp_no_deploy_qml link_pkgconfig
DEFINES += TARGET=\""$(TARGET")\"
# PKGCONFIG += libpulse
PKGCONFIG += libpulse
RESOURCES += \
qml/sailfish.qrc \

View file

@ -35,6 +35,8 @@ Tuner::Tuner()
temperament_idx = 0;
la = Scale::defaultLa;
qRegisterMetaType<PitchDetection::PitchResult>("PitchDetection::PitchResult");
worker = new TunerWorker();
worker->moveToThread(&workerThread);

View file

@ -20,9 +20,18 @@
#include <iostream>
#include <fstream>
#include <stdint.h>
extern "C" {
#include <pulse/simple.h>
}
#include "TunerWorker.hpp"
#define name_(x) #x
#define name(x) name_(x)
#define NAME name(TARGET)
using namespace std;
/// file name to record audio
@ -50,6 +59,7 @@ TunerWorker::TunerWorker() :
la_to_update(0),
temperament_to_update(-1)
{
//qRegisterMetaType<PitchDetection::PitchResult>("PitchDetection::PitchResult");
}
TunerWorker::~TunerWorker()
@ -102,6 +112,11 @@ void TunerWorker::Entry()
int nbSamplePreventRunning = nbSecPreventRunning * PitchDetection::rate;
int nb_sample_running = 0;
bool new_stream = true;
int16_t *buffer = new int16_t[nbSampleBuffer];
PitchDetection::PitchResult result;
ofstream *file = NULL;
if (filename_record) file = new ofstream(filename_record);
@ -109,6 +124,26 @@ void TunerWorker::Entry()
PitchDetection *pitchDetection = new PitchDetection();
emit temperamentListUpdated(pitchDetection->GetTemperamentList());
// pulseaudio
pa_simple *p_simple;
pa_sample_spec p_spec;
p_spec.format = PA_SAMPLE_S16NE;
p_spec.channels = 1;
p_spec.rate = PitchDetection::rate;
p_simple = pa_simple_new(
NULL,
NAME,
PA_STREAM_RECORD,
NULL,
"Mic",
&p_spec,
NULL,
NULL,
NULL
);
while (1) {
// wait for running
mutex.lock();
@ -117,10 +152,7 @@ void TunerWorker::Entry()
while (!running && !quit) condition.wait(&mutex);
cerr << "wake-up" << endl;
// reset operations on start
if (!quit) {
pitchDetection->Reset();
nb_sample_running = 0;
}
new_stream = true;
}
if (quit) {
mutex.unlock();
@ -137,26 +169,50 @@ void TunerWorker::Entry()
}
mutex.unlock();
// record in file is needed
//if (file) file->write((char*) ptr, nb_frame * sizeof(int16_t));
std::cout << __func__ << " do job" << std::endl;
// if srteam was stopped, reset analyse
if (new_stream) {
pitchDetection->Reset();
nb_sample_running = 0;
// flush audio
pa_simple_flush(p_simple, NULL);
new_stream = false;
}
// get audio data
int size = pa_simple_read(p_simple, (void*) buffer, nbSampleBuffer << 1, NULL);
if (size < 0) {
cerr << "audio read failed " << size << endl;
continue;
}
//cerr << "read " << nb_sample_running << endl;
// record in file is needed
if (file) file->write((char*) buffer, nbSampleBuffer << 1);
pitchDetection->AudioAnalyse(buffer, nbSampleBuffer);
if (pitchDetection->GetResultUpdated(result)) {
if (result.found) cout << Scale::NoteName(result.note) << " " << result.frequency << endl;
emit resultUpdated(result);
}
// prevent screen blanking
nb_sample_running += nbSampleBuffer;
if (nb_sample_running >= nbSamplePreventRunning && running) {
nb_sample_running = 0;
blank_prevent(true);
}
}
pa_simple_free(p_simple);
delete pitchDetection;
delete buffer;
if (file) {
file->close();
delete file;
}
cerr << __func__ << " quit" << endl;
/*
// prevent screen blanking
if (nb_sample_running >= nbSamplePreventRunning && running) {
nb_sample_running = 0;
blank_prevent(true);
}*/
}
/// Set a filename before instanciation to record raw audio stream

View file

@ -36,6 +36,7 @@ class TunerWorker : public QObject {
private:
static const int nbSecPreventRunning = 40;
static const int nbSampleBuffer = 512;
static const char *filename_record;
QMutex mutex;