X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fdelay_analyzer.cpp;fp=nageru%2Fdelay_analyzer.cpp;h=7e25738667e7330e0c29affb06337e2f51595858;hb=bd01e11a41a19fef2315319909d8655cac359f0f;hp=0000000000000000000000000000000000000000;hpb=a944bad466ba5601a96f6833e1ea2eb31f9b55af;p=nageru diff --git a/nageru/delay_analyzer.cpp b/nageru/delay_analyzer.cpp new file mode 100644 index 0000000..7e25738 --- /dev/null +++ b/nageru/delay_analyzer.cpp @@ -0,0 +1,127 @@ +#include "delay_analyzer.h" + +#include "audio_mixer.h" +#include "ui_delay_analyzer.h" + +#include + +#include + +using namespace bmusb; +using namespace std; +using namespace std::chrono; +using namespace std::placeholders; + +DelayAnalyzer::DelayAnalyzer() + : ui(new Ui::DelayAnalyzer), + devices(global_audio_mixer->get_devices(AudioMixer::HOLD_NO_DEVICES)) +{ + ui->setupUi(this); + connect(ui->grab_btn, &QPushButton::clicked, this, &DelayAnalyzer::grab_clicked); + + connect(ui->card_combo_1, static_cast(&QComboBox::currentIndexChanged), + bind(&DelayAnalyzer::card_selected, this, ui->card_combo_1, _1)); + connect(ui->card_combo_2, static_cast(&QComboBox::currentIndexChanged), + bind(&DelayAnalyzer::card_selected, this, ui->card_combo_2, _1)); + connect(ui->channel_combo_1, static_cast(&QComboBox::currentIndexChanged), + bind(&DelayAnalyzer::channel_selected, this, ui->channel_combo_1)); + connect(ui->channel_combo_2, static_cast(&QComboBox::currentIndexChanged), + bind(&DelayAnalyzer::channel_selected, this, ui->channel_combo_2)); + + for (const auto &spec_and_info : devices) { + QString label(QString::fromStdString(spec_and_info.second.display_name)); + ui->card_combo_1->addItem(label + " ", qulonglong(DeviceSpec_to_key(spec_and_info.first))); + ui->card_combo_2->addItem(label + " ", qulonglong(DeviceSpec_to_key(spec_and_info.first))); + } + + ui->peak_display_1->set_audio_clip(&clip1); + ui->peak_display_2->set_audio_clip(&clip2); +} + +DelayAnalyzer::~DelayAnalyzer() +{ +} + +void DelayAnalyzer::grab_clicked() +{ + grabbing = true; + clip1.clear(); + clip2.clear(); + ui->peak_display_1->audio_clip_updated(); + ui->peak_display_2->audio_clip_updated(); +} + +void DelayAnalyzer::card_selected(QComboBox *card_combo, int selected_index) +{ + assert(card_combo == ui->card_combo_1 || card_combo == ui->card_combo_2); + QComboBox *channel_combo = (card_combo == ui->card_combo_1 ? ui->channel_combo_1 : ui->channel_combo_2); + int current_channel = channel_combo->currentIndex(); + + channel_combo->clear(); + + uint64_t key = card_combo->itemData(selected_index).toULongLong(); + auto device_it = devices.find(key_to_DeviceSpec(key)); + assert(device_it != devices.end()); + unsigned num_device_channels = device_it->second.num_channels; + for (unsigned source = 0; source < num_device_channels; ++source) { + char buf[256]; + snprintf(buf, sizeof(buf), "Channel %u ", source + 1); + channel_combo->addItem(QString(buf)); + } + + if (current_channel != -1 && current_channel < channel_combo->count()) { + channel_combo->setCurrentIndex(current_channel); + } else { + channel_combo->setCurrentIndex(0); + } + + if (card_combo == ui->card_combo_1) { + clip1.clear(); + ui->peak_display_1->audio_clip_updated(); + } else { + clip2.clear(); + ui->peak_display_2->audio_clip_updated(); + } +} + +void DelayAnalyzer::channel_selected(QComboBox *channel_combo) +{ + if (channel_combo == ui->channel_combo_1) { + clip1.clear(); + ui->peak_display_1->audio_clip_updated(); + } else { + clip2.clear(); + ui->peak_display_2->audio_clip_updated(); + } +} + +DeviceSpec DelayAnalyzer::get_selected_device(QComboBox *card_combo) +{ + return key_to_DeviceSpec(card_combo->currentData().toULongLong()); +} + +void DelayAnalyzer::add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, AudioFormat audio_format, steady_clock::time_point frame_time) +{ + unique_ptr tmp; + + if (device_spec == get_selected_device(ui->card_combo_1)) { + tmp.reset(new float[num_samples]); + + convert_audio_to_fp32(tmp.get(), /*out_channel=*/0, /*out_num_channels=*/1, data, ui->channel_combo_1->currentIndex(), audio_format, num_samples); + clip1.add_audio(tmp.get(), num_samples, audio_format.sample_rate, frame_time); + ui->peak_display_1->audio_clip_updated(); + } + if (device_spec == get_selected_device(ui->card_combo_2)) { + if (tmp == nullptr) { + tmp.reset(new float[num_samples]); + } + + convert_audio_to_fp32(tmp.get(), /*out_channel=*/0, /*out_num_channels=*/1, data, ui->channel_combo_2->currentIndex(), audio_format, num_samples); + clip2.add_audio(tmp.get(), num_samples, audio_format.sample_rate, frame_time); + ui->peak_display_2->audio_clip_updated(); + } + + if (clip1.get_length_seconds() >= 1.0 && clip2.get_length_seconds() >= 1.0) { + grabbing = false; + } +}