Tuner: analyse and record audio cmd-line option for debug
./tuner file.raw: analyse file ./tuner record out.raw: record audio stream
This commit is contained in:
parent
e0e717e9c5
commit
e0aef524f6
4 changed files with 61 additions and 26 deletions
|
@ -6,6 +6,9 @@
|
||||||
#include <QDBusConnection>
|
#include <QDBusConnection>
|
||||||
#include <QDBusInterface>
|
#include <QDBusInterface>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "Tuner.hpp"
|
#include "Tuner.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -14,6 +17,8 @@ using namespace std;
|
||||||
static double a10[] = { 1 , -2.99214602, 2.98432286, -0.99217678 };
|
static double a10[] = { 1 , -2.99214602, 2.98432286, -0.99217678 };
|
||||||
static double b10[] = { 0.99608071, -2.98824212, 2.98824212, -0.99608071 };
|
static double b10[] = { 0.99608071, -2.98824212, 2.98824212, -0.99608071 };
|
||||||
|
|
||||||
|
const char * Tuner::filename_record = NULL;
|
||||||
|
|
||||||
// function to prevent screen blank
|
// function to prevent screen blank
|
||||||
|
|
||||||
static void blank_prevent(bool prevent)
|
static void blank_prevent(bool prevent)
|
||||||
|
@ -37,6 +42,8 @@ Tuner::Tuner()
|
||||||
found = false;
|
found = false;
|
||||||
count_found = count_not_found = 0;
|
count_found = count_not_found = 0;
|
||||||
|
|
||||||
|
if (filename_record) file_record.open(filename_record);
|
||||||
|
|
||||||
high_filter = new LinearFilter<int16_t>(3, a10, b10);
|
high_filter = new LinearFilter<int16_t>(3, a10, b10);
|
||||||
|
|
||||||
ZeroCross<int16_t>::Config cross_config({rate, defaultNbFrame, defaultFreqMin, defaultFreqMax});
|
ZeroCross<int16_t>::Config cross_config({rate, defaultNbFrame, defaultFreqMin, defaultFreqMax});
|
||||||
|
@ -63,6 +70,7 @@ Tuner::Tuner()
|
||||||
|
|
||||||
Tuner::~Tuner()
|
Tuner::~Tuner()
|
||||||
{
|
{
|
||||||
|
if (filename_record && file_record.is_open()) file_record.close();
|
||||||
delete high_filter;
|
delete high_filter;
|
||||||
delete cross;
|
delete cross;
|
||||||
delete recorder;
|
delete recorder;
|
||||||
|
@ -176,6 +184,8 @@ void Tuner::AudioAnalyse(const int16_t *ptr, int nb_frame)
|
||||||
{
|
{
|
||||||
nb_sample_running += nb_frame;
|
nb_sample_running += nb_frame;
|
||||||
|
|
||||||
|
if (filename_record && file_record.is_open()) file_record.write((char*) ptr, nb_frame * sizeof(int16_t));
|
||||||
|
|
||||||
while (nb_frame--) ComputeFrame(*ptr++);
|
while (nb_frame--) ComputeFrame(*ptr++);
|
||||||
|
|
||||||
if (freq != cross->Freq()) {
|
if (freq != cross->Freq()) {
|
||||||
|
@ -241,3 +251,36 @@ bool Tuner::GetFound()
|
||||||
{
|
{
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a filename to record raw audio stream
|
||||||
|
|
||||||
|
void Tuner::set_record(const char *f)
|
||||||
|
{
|
||||||
|
filename_record = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// analyse a file (static function)
|
||||||
|
void Tuner::analyse_file(const char *filename)
|
||||||
|
{
|
||||||
|
cout << "analyse file " << filename << endl;
|
||||||
|
ifstream fin;
|
||||||
|
fin.open(filename);
|
||||||
|
|
||||||
|
const int nb_frame = 1024;
|
||||||
|
Tuner *tuner = new Tuner();
|
||||||
|
int16_t buffer[nb_frame];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
fin.read((char*) buffer, sizeof(buffer));
|
||||||
|
tuner->AudioAnalyse(buffer, sizeof(buffer) >> 1);
|
||||||
|
|
||||||
|
cout << tuner->GetFreq() << " ";
|
||||||
|
if (tuner->GetFound())
|
||||||
|
cout << tuner->GetNoteName() << " " << tuner->GetOctave() << " " << tuner->GetDeviation();
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
if (fin.eof()) break;
|
||||||
|
}
|
||||||
|
fin.close();
|
||||||
|
delete tuner;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <QAudioRecorder>
|
#include <QAudioRecorder>
|
||||||
#include <QAudioProbe>
|
#include <QAudioProbe>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "audio/LinearFilter.hpp"
|
#include "audio/LinearFilter.hpp"
|
||||||
#include "audio/ZeroCross.hpp"
|
#include "audio/ZeroCross.hpp"
|
||||||
#include "scale/Scale.hpp"
|
#include "scale/Scale.hpp"
|
||||||
|
@ -23,6 +25,8 @@ class Tuner : public QObject {
|
||||||
LinearFilter<int16_t> *high_filter;
|
LinearFilter<int16_t> *high_filter;
|
||||||
ZeroCross<int16_t> *cross;
|
ZeroCross<int16_t> *cross;
|
||||||
Scale *scale;
|
Scale *scale;
|
||||||
|
static const char *filename_record;
|
||||||
|
std::ofstream file_record;
|
||||||
|
|
||||||
bool running, found;
|
bool running, found;
|
||||||
double freq, deviation;
|
double freq, deviation;
|
||||||
|
@ -72,6 +76,11 @@ class Tuner : public QObject {
|
||||||
bool GetFound();
|
bool GetFound();
|
||||||
const char* GetNoteName();
|
const char* GetNoteName();
|
||||||
|
|
||||||
|
/// analyse a file for debug
|
||||||
|
static void analyse_file(const char *filename);
|
||||||
|
/// write a file with raw audio
|
||||||
|
static void set_record(const char *filename_record);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void runningChanged();
|
void runningChanged();
|
||||||
void freqChanged();
|
void freqChanged();
|
||||||
|
|
|
@ -7,35 +7,10 @@
|
||||||
|
|
||||||
#include "Tuner.hpp"
|
#include "Tuner.hpp"
|
||||||
|
|
||||||
static void analyse_file(const char *filename)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
cout << "analyse file " << filename << endl;
|
|
||||||
ifstream fin;
|
|
||||||
fin.open(filename);
|
|
||||||
|
|
||||||
const int nb_frame = 1024;
|
|
||||||
Tuner *tuner = new Tuner();
|
|
||||||
int16_t buffer[nb_frame];
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
fin.read((char*) buffer, sizeof(buffer));
|
|
||||||
tuner->AudioAnalyse(buffer, sizeof(buffer) >> 1);
|
|
||||||
|
|
||||||
cout << tuner->GetFreq() << " ";
|
|
||||||
if (tuner->GetFound())
|
|
||||||
cout << tuner->GetNoteName() << " " << tuner->GetOctave() << " " << tuner->GetDeviation();
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
if (fin.eof()) break;
|
|
||||||
}
|
|
||||||
delete tuner;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_EXPORT int main(int argc, char* argv[])
|
Q_DECL_EXPORT int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
analyse_file(argv[1]);
|
Tuner::analyse_file(argv[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,14 @@ class Main {
|
||||||
|
|
||||||
Q_DECL_EXPORT int main(int argc, char* argv[])
|
Q_DECL_EXPORT int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
if (argc == 2) {
|
||||||
|
Tuner::analyse_file(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (argc == 3 && strcmp(argv[1], "record") == 0) {
|
||||||
|
Tuner::set_record(argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
qmlRegisterType<Tuner>("harbour.sailtuner.tuner", 1, 0, "Tuner");
|
qmlRegisterType<Tuner>("harbour.sailtuner.tuner", 1, 0, "Tuner");
|
||||||
Main *appli = new Main(argc, argv);
|
Main *appli = new Main(argc, argv);
|
||||||
return appli->Launch();
|
return appli->Launch();
|
||||||
|
|
Loading…
Reference in a new issue