added audio device settings to preferences

This commit is contained in:
itsmattkc
2019-01-30 22:51:43 +11:00
parent c19a2dad7d
commit 861a5e2ce5
8 changed files with 143 additions and 31 deletions
+2 -7
View File
@@ -8,6 +8,7 @@
#include "panels/timeline.h"
#include "playback/playback.h"
#include "project/media.h"
#include "playback/audio.h"
#include <QVariant>
#include <QVBoxLayout>
@@ -232,13 +233,7 @@ void NewSequenceDialog::setup_ui() {
audioLayout->addWidget(new QLabel(tr("Sample Rate: "), this), 0, 0, 1, 1);
audio_frequency_combobox = new QComboBox(audioGroupBox);
audio_frequency_combobox->addItem("22050 Hz", 22050);
audio_frequency_combobox->addItem("24000 Hz", 24000);
audio_frequency_combobox->addItem("32000 Hz", 32000);
audio_frequency_combobox->addItem("44100 Hz", 44100);
audio_frequency_combobox->addItem("48000 Hz", 48000);
audio_frequency_combobox->addItem("88200 Hz", 88200);
audio_frequency_combobox->addItem("96000 Hz", 96000);
combobox_audio_sample_rates(audio_frequency_combobox);
audio_frequency_combobox->setCurrentIndex(4);
audioLayout->addWidget(audio_frequency_combobox, 0, 1, 1, 1);
+74 -3
View File
@@ -1,6 +1,7 @@
#include "preferencesdialog.h"
#include "io/config.h"
#include "playback/audio.h"
#include "mainwindow.h"
#include <QMenuBar>
@@ -22,6 +23,7 @@
#include <QDoubleSpinBox>
#include <QFileDialog>
#include <QMessageBox>
#include <QAudioDeviceInfo>
#include "debug.h"
@@ -133,6 +135,14 @@ void PreferencesDialog::save() {
config.previous_queue_size = previous_queue_spinbox->value();
config.previous_queue_type = previous_queue_type->currentIndex();
// audio preferences
bool reset_audio_required = (config.preferred_audio_output != audio_output_devices->currentData().toString()
|| config.preferred_audio_input != audio_input_devices->currentData().toString());
config.preferred_audio_output = audio_output_devices->currentData().toString();
config.preferred_audio_input = audio_input_devices->currentData().toString();
qDebug() << "selected audio input" << audio_input_devices->currentData().toString();
config.audio_rate = audio_sample_rate->currentData().toInt();
// the following settings may require a restart of Olive to take effect:
bool needs_restart = false;
@@ -152,6 +162,10 @@ void PreferencesDialog::save() {
key_shortcut_fields.at(i)->set_action_shortcut();
}
if (reset_audio_required) {
init_audio();
}
if (needs_restart) {
QMessageBox::information(this, tr("Warning"), tr("Some changed settings will require restarting Olive to take effect"));
}
@@ -286,7 +300,7 @@ void PreferencesDialog::setup_ui() {
QTabWidget* tabWidget = new QTabWidget(this);
// General
QTabWidget* general_tab = new QTabWidget(this);
QWidget* general_tab = new QWidget(this);
QGridLayout* general_layout = new QGridLayout(general_tab);
// General -> Custom CSS
@@ -382,6 +396,65 @@ void PreferencesDialog::setup_ui() {
tabWidget->addTab(playback_tab, tr("Playback"));
// Audio
QWidget* audio_tab = new QWidget(this);
QGridLayout* audio_tab_layout = new QGridLayout(audio_tab);
audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), 0, 0);
audio_output_devices = new QComboBox();
audio_output_devices->addItem(tr("Default"), "");
// list all available audio output devices
QList<QAudioDeviceInfo> devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
bool found_preferred_device = false;
for (int i=0;i<devs.size();i++) {
audio_output_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
if (!found_preferred_device
&& devs.at(i).deviceName() == config.preferred_audio_output) {
audio_output_devices->setCurrentIndex(audio_output_devices->count()-1);
found_preferred_device = true;
}
}
audio_tab_layout->addWidget(audio_output_devices, 0, 1);
audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), 1, 0);
audio_input_devices = new QComboBox();
audio_input_devices->addItem(tr("Default"), "");
// list all available audio input devices
devs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
found_preferred_device = false;
for (int i=0;i<devs.size();i++) {
audio_input_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
if (!found_preferred_device
&& devs.at(i).deviceName() == config.preferred_audio_input) {
audio_input_devices->setCurrentIndex(audio_input_devices->count()-1);
found_preferred_device = true;
}
}
audio_tab_layout->addWidget(audio_input_devices, 1, 1);
audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), 2, 0);
audio_sample_rate = new QComboBox();
combobox_audio_sample_rates(audio_sample_rate);
for (int i=0;i<audio_sample_rate->count();i++) {
if (audio_sample_rate->itemData(i).toInt() == config.audio_rate) {
audio_sample_rate->setCurrentIndex(i);
break;
}
}
audio_tab_layout->addWidget(audio_sample_rate, 2, 1);
tabWidget->addTab(audio_tab, tr("Audio"));
// Shortcuts
QWidget* shortcut_tab = new QWidget(this);
QVBoxLayout* shortcut_layout = new QVBoxLayout(shortcut_tab);
@@ -432,6 +505,4 @@ void PreferencesDialog::setup_ui() {
connect(buttonBox, SIGNAL(accepted()), this, SLOT(save()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
tabWidget->setCurrentIndex(2);
}
+3
View File
@@ -62,6 +62,9 @@ private:
QComboBox* previous_queue_type;
QSpinBox* effect_textbox_lines_field;
QCheckBox* use_software_fallbacks_checkbox;
QComboBox* audio_output_devices;
QComboBox* audio_input_devices;
QComboBox* audio_sample_rate;
QVector<QAction*> key_shortcut_actions;
QVector<QTreeWidgetItem*> key_shortcut_items;
+8
View File
@@ -173,6 +173,12 @@ void Config::load(QString path) {
} else if (stream.name() == "CenterTimelineTimecodes") {
stream.readNext();
center_timeline_timecodes = (stream.text() == "1");
} else if (stream.name() == "PreferredAudioOutput") {
stream.readNext();
preferred_audio_output = stream.text().toString();
} else if (stream.name() == "PreferredAudioInput") {
stream.readNext();
preferred_audio_input = stream.text().toString();
}
}
}
@@ -235,6 +241,8 @@ void Config::save(QString path) {
stream.writeTextElement("EffectTextboxLines", QString::number(effect_textbox_lines));
stream.writeTextElement("UseSoftwareFallback", QString::number(use_software_fallback));
stream.writeTextElement("CenterTimelineTimecodes", QString::number(center_timeline_timecodes));
stream.writeTextElement("PreferredAudioOutput", preferred_audio_output);
stream.writeTextElement("PreferredAudioInput", preferred_audio_input);
stream.writeEndElement(); // configuration
stream.writeEndDocument(); // doc
+2
View File
@@ -64,6 +64,8 @@ struct Config {
int effect_textbox_lines;
bool use_software_fallback;
bool center_timeline_timecodes;
QString preferred_audio_output;
QString preferred_audio_input;
void load(QString path);
void save(QString path);
+5 -8
View File
@@ -132,9 +132,6 @@ bool ExportThread::setupVideo() {
break;
}
break;
case AV_CODEC_ID_GIF:
av_opt_set(vcodec_ctx->priv_data, "image", "1", AV_OPT_SEARCH_CHILDREN);
break;
}
AVDictionary* opts = nullptr;
@@ -377,18 +374,20 @@ void ExportThread::run() {
sws_frame->height = video_height;
av_frame_get_buffer(sws_frame, 0);
// change pixel format
// convert pixel format to format expected by the encoder
sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_frame->height, sws_frame->data, sws_frame->linesize);
sws_frame->pts = qRound(timecode_secs/av_q2d(video_stream->time_base));
// send to encoder
// send converted frame to encoder
if (!encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream, false)) continueEncode = false;
av_frame_free(&sws_frame);
}
if (audio_enabled) {
// do we need to encode more audio samples?
while (continueEncode && file_audio_samples <= (timecode_secs*audio_sampling_rate)) {
// copy samples from audio buffer to AVFrame
int adjusted_read = audio_ibuffer_read%audio_ibuffer_size;
int copylen = qMin(aframe_bytes, audio_ibuffer_size-adjusted_read);
@@ -415,15 +414,13 @@ void ExportThread::run() {
}
}
// encoding stats
// generating encoding statistics (time it took to encode this frame/estimated remaining time)
frame_time = (QDateTime::currentMSecsSinceEpoch()-start_time);
total_time += frame_time;
remaining_frames = (end_frame-sequence->playhead);
avg_time = (total_time/frame_count);
eta = (remaining_frames*avg_time);
// qInfo() << "Encoded frame" << sequence->playhead << "- took" << frame_time << "ms (avg:" << avg_time << "ms, remaining:" << remaining_frames << ", ETA:" << eta << ")";
emit progress_changed(qRound((double(sequence->playhead-start_frame) / double(end_frame-start_frame)) * 100.0), eta);
sequence->playhead++;
frame_count++;
+46 -13
View File
@@ -17,6 +17,7 @@
#include <QtMath>
#include <QFile>
#include <QDir>
#include <QComboBox>
extern "C" {
#include <libavcodec/avcodec.h>
@@ -43,6 +44,35 @@ bool is_audio_device_set() {
return audio_device_set;
}
QAudioDeviceInfo get_audio_device(QAudio::Mode mode) {
QList<QAudioDeviceInfo> devs = QAudioDeviceInfo::availableDevices(mode);
// try to retrieve preferred device from config
QString preferred_device = (mode == QAudio::AudioOutput) ? config.preferred_audio_output : config.preferred_audio_input;
if (!preferred_device.isEmpty()) {
for (int i=0;i<devs.size();i++) {
// try to match available devices with preferred device
if (devs.at(i).deviceName() == preferred_device) {
return devs.at(i);
}
}
}
// if no preferred output is set, try to get the default device
QAudioDeviceInfo default_device = (mode == QAudio::AudioOutput) ? QAudioDeviceInfo::defaultOutputDevice() : QAudioDeviceInfo::defaultInputDevice();
if (!default_device.isNull()) {
return default_device;
}
// if no default output could be retrieved, just use the first in the list
if (devs.size() > 0) {
return devs.at(0);
}
// couldn't find any audio devices, return null device
return QAudioDeviceInfo();
}
void init_audio() {
stop_audio();
@@ -54,18 +84,9 @@ void init_audio() {
audio_format.setByteOrder(QAudioFormat::LittleEndian);
audio_format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
QList<QAudioDeviceInfo> devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
qInfo() << "Found the following audio devices:";
for (int i=0;i<devs.size();i++) {
dout << " " << devs.at(i).deviceName();
}
if (info.isNull() && devs.size() > 0) {
qWarning() << "Default audio returned nullptr, attempting to use first device found...";
info = devs.at(0);
}
qInfo() << "Using audio device" << info.deviceName();
QAudioDeviceInfo info = get_audio_device(QAudio::AudioOutput);
// see if desired format can be used by the device, use nearest if not
if (!info.isFormatSupported(audio_format)) {
qWarning() << "Audio format is not supported by backend, using nearest";
audio_format = info.nearestFormat(audio_format);
@@ -311,13 +332,15 @@ bool start_recording() {
if (config.recording_mode != audio_format.channelCount()) {
audio_format.setChannelCount(config.recording_mode);
}
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
QAudioDeviceInfo info = get_audio_device(QAudio::AudioInput);
if (!info.isFormatSupported(audio_format)) {
qWarning() << "Default format not supported, using nearest";
audio_format = info.nearestFormat(audio_format);
}
write_wave_header(output_recording, audio_format);
audio_input = new QAudioInput(audio_format);
audio_input = new QAudioInput(info, audio_format);
audio_input->start(&output_recording);
recording = true;
@@ -341,3 +364,13 @@ void stop_recording() {
QString get_recorded_audio_filename() {
return output_recording.fileName();
}
void combobox_audio_sample_rates(QComboBox *combobox) {
combobox->addItem("22050 Hz", 22050);
combobox->addItem("24000 Hz", 24000);
combobox->addItem("32000 Hz", 32000);
combobox->addItem("44100 Hz", 44100);
combobox->addItem("48000 Hz", 48000);
combobox->addItem("88200 Hz", 88200);
combobox->addItem("96000 Hz", 96000);
}
+3
View File
@@ -11,6 +11,7 @@
class QIODevice;
class QAudioOutput;
class QComboBox;
struct Sequence;
@@ -59,4 +60,6 @@ bool start_recording();
void stop_recording();
QString get_recorded_audio_filename();
void combobox_audio_sample_rates(QComboBox* combobox);
#endif // AUDIO_H