added audio device settings to preferences
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user