diff options
| author | Martin Lambers <marlam@marlam.de> | 2012-01-28 19:10:14 +0100 |
|---|---|---|
| committer | Martin Lambers <marlam@marlam.de> | 2012-01-28 19:10:14 +0100 |
| commit | 7dc2939801a53b10b50333b5de14480a6c4a335c (patch) | |
| tree | 80171813ed31f7077f421d5ef859236089595936 | |
| parent | 3e6ea1acfffacdb12f737802d0078539b5f29bbb (diff) | |
| download | bino-7dc2939801a53b10b50333b5de14480a6c4a335c.tar.gz | |
Add support for selecting an audio device.
| -rw-r--r-- | doc/bino.1 | 4 | ||||
| -rw-r--r-- | doc/bino.texi | 5 | ||||
| -rw-r--r-- | src/audio_output.cpp | 48 | ||||
| -rw-r--r-- | src/audio_output.h | 13 | ||||
| -rw-r--r-- | src/main.cpp | 28 | ||||
| -rw-r--r-- | src/player.cpp | 7 | ||||
| -rw-r--r-- | src/player.h | 3 | ||||
| -rw-r--r-- | src/player_qt.cpp | 69 | ||||
| -rw-r--r-- | src/player_qt.h | 21 |
9 files changed, 187 insertions, 11 deletions
@@ -34,6 +34,10 @@ Append all log messages to the given file. .IP "\-L|\-\-log\-level=\fILEVEL\fP" Select log level: \fIdebug\fP, \fIinfo\fP, \fIwarning\fP, \fIerror\fP, or \fIquiet\fP. +.IP "\-\-list\-audio\-devices" +Print a list of known audio devices and exit. +.IP "\-A|\-\-audio\-device=\fID\fP" +Use audio device number D. D=0 is the default device. .IP "\-\-device\-type=\fITYPE\fP" Type of input device: \fIdefault\fP, \fIfirewire\fP, or \fIx11\fP. .IP "\-\-device\-frame\-size=\fIW\fPx\fIH\fP" diff --git a/doc/bino.texi b/doc/bino.texi index 28bbab8..fb9f5b8 100644 --- a/doc/bino.texi +++ b/doc/bino.texi @@ -113,6 +113,11 @@ Append all log messages to the given file. @itemx --log-level=@var{LEVEL} Select log level: @var{debug}, @var{info}, @var{warning}, @var{error}, or @var{quiet}. +@item --list-audio-devices +Print a list of known audio devices and exit. +@item -A +@itemx --audio-device=@var{D} +Use audio device number @var{D}. @var{D}=0 is the default device. @item --device-type=@var{TYPE} Type of input device: @var{default}, @var{firewire}, or @var{x11}. @item --device-frame-size=@var{W}x@var{H} diff --git a/src/audio_output.cpp b/src/audio_output.cpp index 54b4772..5016251 100644 --- a/src/audio_output.cpp +++ b/src/audio_output.cpp @@ -1,7 +1,7 @@ /* * This file is part of bino, a 3D video player. * - * Copyright (C) 2010-2011 + * Copyright (C) 2010, 2011, 2012 * Martin Lambers <marlam@marlam.de> * Gabriele Greco <gabrielegreco@gmail.com> * @@ -45,6 +45,20 @@ const size_t audio_output::_buffer_size = 20160 * 2; audio_output::audio_output() : controller(), _initialized(false) { + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) + { + const char *p = alcGetString(NULL, ALC_DEVICE_SPECIFIER); + while (p && *p) + { + _devices.push_back(p); + p += _devices.back().length() + 1; + } + msg::dbg("%d OpenAL devices available:", devices()); + for (size_t i = 0; i < _devices.size(); i++) + { + msg::dbg(4, _devices[i]); + } + } } audio_output::~audio_output() @@ -52,13 +66,39 @@ audio_output::~audio_output() deinit(); } -void audio_output::init() +int audio_output::devices() const +{ + return _devices.size(); +} + +const std::string &audio_output::device_name(int i) const +{ + assert(i >= 0 && i < devices()); + return _devices[i]; +} + +void audio_output::init(int i) { if (!_initialized) { - if (!(_device = alcOpenDevice(NULL))) + if (i == -1) + { + if (!(_device = alcOpenDevice(NULL))) + { + throw exc(_("No OpenAL device available.")); + } + } + else if (i < -1 || i >= static_cast<int>(_devices.size())) { - throw exc(_("No OpenAL device available.")); + throw exc(str::asprintf(_("OpenAL device '%s' is not available."), _("unknown"))); + } + else + { + if (!(_device = alcOpenDevice(_devices[i].c_str()))) + { + throw exc(str::asprintf(_("OpenAL device '%s' is not available."), + _devices[i].c_str())); + } } if (!(_context = alcCreateContext(_device, NULL))) { diff --git a/src/audio_output.h b/src/audio_output.h index 83ebc70..474495d 100644 --- a/src/audio_output.h +++ b/src/audio_output.h @@ -1,7 +1,7 @@ /* * This file is part of bino, a 3D video player. * - * Copyright (C) 2010-2011 + * Copyright (C) 2010, 2011, 2012 * Martin Lambers <marlam@marlam.de> * Gabriele Greco <gabrielegreco@gmail.com> * @@ -45,6 +45,7 @@ private: static const size_t _buffer_size; // Size of each audio buffer // OpenAL things + std::vector<std::string> _devices; // List of known OpenAL devices bool _initialized; // Was this initialized? ALCdevice *_device; // Audio device ALCcontext *_context; // Audio context associated with device @@ -70,8 +71,14 @@ public: audio_output(); ~audio_output(); - /* Initialize the audio device for output. Throw an exception if this fails. */ - void init(); + /* How many OpenAL devices are available? */ + int devices() const; + /* Return the name of OpenAL device i. */ + const std::string &device_name(int i) const; + + /* Initialize the audio device i for output. If i is -1, the default device + * will be used. Throw an exception if this fails. */ + void init(int i = -1); /* Deinitialize the audio device. */ void deinit(); diff --git a/src/main.cpp b/src/main.cpp index ae3457e..c6c874d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -205,6 +205,10 @@ int main(int argc, char *argv[]) log_levels.push_back("quiet"); opt::val<std::string> log_level("log-level", 'L', opt::optional, log_levels, ""); options.push_back(&log_level); + opt::info list_audio_devices("list-audio-devices", '\0', opt::optional); + options.push_back(&list_audio_devices); + opt::val<int> audio_device("audio-device", '\0', opt::optional, 0, 999, 0); + options.push_back(&audio_device); std::vector<std::string> device_types; device_types.push_back("default"); device_types.push_back("firewire"); @@ -388,6 +392,8 @@ int main(int argc, char *argv[]) " -n|--no-gui Do not use the GUI, just show a plain window.\n" " --log-file=FILE Append all log messages to the given file.\n" " -L|--log-level=LEVEL Set log level (debug/info/warning/error/quiet).\n" + " --list-audio-devices Print a list of known audio devices and exit.\n" + " -A|--audio-devices=D Use audio device number D (D=0 is the default).\n" " --device-type=TYPE Type of input device: default, firewire, x11.\n" " --device-frame-size=WxH Request frame size WxH from input device.\n" " --device-frame-rate=N/D Request frame rate N/D from input device.\n" @@ -490,7 +496,23 @@ int main(int argc, char *argv[]) " Media keys Media keys should work as expected."), program_name); } - if (version.value() || help.value()) + if (list_audio_devices.value()) + { + audio_output ao; + if (ao.devices() == 0) + { + msg::req(_("No audio devices known.")); + } + else + { + msg::req("%d audio devices available:", ao.devices()); + for (int i = 0; i < ao.devices(); i++) + { + msg::req(4, "%d: %s", i + 1, ao.device_name(i).c_str()); + } + } + } + if (version.value() || help.value() || list_audio_devices.value()) { return 0; } @@ -540,6 +562,10 @@ int main(int argc, char *argv[]) { init_data.log_level = msg::REQ; } + if (audio_device.values().size() > 0) + { + init_data.audio_device = audio_device.value() - 1; + } if (device_type.value() == "") { init_data.dev_request.device = diff --git a/src/player.cpp b/src/player.cpp index 73d5ba5..5de5696 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1,7 +1,7 @@ /* * This file is part of bino, a 3D video player. * - * Copyright (C) 2010-2011 + * Copyright (C) 2010, 2011, 2012 * Martin Lambers <marlam@marlam.de> * Alexey Osipov <lion-simba@pridelands.ru> * Joe <cuchac@email.cz> @@ -43,6 +43,7 @@ player_init_data::player_init_data() : log_level(msg::INF), + audio_device(-2), dev_request(), urls(), video_stream(0), @@ -69,6 +70,7 @@ player_init_data::~player_init_data() void player_init_data::save(std::ostream &os) const { s11n::save(os, static_cast<int>(log_level)); + s11n::save(os, audio_device); s11n::save(os, dev_request); s11n::save(os, urls); s11n::save(os, video_stream); @@ -92,6 +94,7 @@ void player_init_data::load(std::istream &is) int x; s11n::load(is, x); log_level = static_cast<msg::level_t>(x); + s11n::load(is, audio_device); s11n::load(is, dev_request); s11n::load(is, urls); s11n::load(is, video_stream); @@ -252,7 +255,7 @@ void player::open(const player_init_data &init_data) } if (_audio_output) { - _audio_output->init(); + _audio_output->init(init_data.audio_device < -1 ? -1 : init_data.audio_device); } // Create video output diff --git a/src/player.h b/src/player.h index 3f8ad56..72d4c5d 100644 --- a/src/player.h +++ b/src/player.h @@ -1,7 +1,7 @@ /* * This file is part of bino, a 3D video player. * - * Copyright (C) 2010-2011 + * Copyright (C) 2010, 2011, 2012 * Martin Lambers <marlam@marlam.de> * Alexey Osipov <lion-simba@pridelands.ru> * Joe <cuchac@email.cz> @@ -41,6 +41,7 @@ class player_init_data : public serializable { public: msg::level_t log_level; // Level of log messages + int audio_device; // Audio device index, or -1 for default device_request dev_request; // Request for input device settings std::vector<std::string> urls; // Input media objects int video_stream; // Selected video stream diff --git a/src/player_qt.cpp b/src/player_qt.cpp index a15144e..ed003a5 100644 --- a/src/player_qt.cpp +++ b/src/player_qt.cpp @@ -1362,6 +1362,54 @@ void crosstalk_dialog::receive_notification(const notification ¬e) } +audio_dialog::audio_dialog(player_init_data *init_data, parameters *params, QWidget *parent) : QDialog(parent), + _init_data(init_data), _params(params), _lock(false) +{ + setModal(false); + setWindowTitle(_("Audio Settings")); + + QLabel *info_label = new QLabel(_("<p>Changing the audio device takes effect<br>for the next started video.</p>")); + QLabel *device_label = new QLabel(_("Audio Device:")); + device_label->setToolTip(_("<p>Select the audio device. This will take effect for the next started video.</p>")); + _device_combobox = new QComboBox(); + _device_combobox->setToolTip(device_label->toolTip()); + _device_combobox->addItem(_("Default")); + audio_output ao; + for (int i = 0; i < ao.devices(); i++) + { + _device_combobox->addItem(ao.device_name(i).c_str()); + } + connect(_device_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(device_changed())); + if (_init_data->audio_device < 0 || _init_data->audio_device >= _device_combobox->count()) + { + _device_combobox->setCurrentIndex(0); + } + else + { + _device_combobox->setCurrentIndex(_init_data->audio_device + 1); + } + + QPushButton *ok_button = new QPushButton(_("OK")); + connect(ok_button, SIGNAL(pressed()), this, SLOT(close())); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(info_label, 0, 0, 1, 2); + layout->addWidget(device_label, 1, 0); + layout->addWidget(_device_combobox, 1, 1); + layout->addWidget(ok_button, 2, 0, 1, 2); + setLayout(layout); +} + +void audio_dialog::device_changed() +{ + _init_data->audio_device = _device_combobox->currentIndex() - 1; +} + +void audio_dialog::receive_notification(const notification &/* note */) +{ +} + + subtitle_dialog::subtitle_dialog(parameters *params, QWidget *parent) : QDialog(parent), _params(params), _lock(false) { @@ -2011,6 +2059,7 @@ main_window::main_window(QSettings *settings, const player_init_data &init_data) _settings(settings), _color_dialog(NULL), _crosstalk_dialog(NULL), + _audio_dialog(NULL), _subtitle_dialog(NULL), _video_dialog(NULL), _player(NULL), @@ -2025,6 +2074,10 @@ main_window::main_window(QSettings *settings, const player_init_data &init_data) // Load preferences _settings->beginGroup("Session"); + if (_init_data.audio_device < -1) + { + _init_data.audio_device = _settings->value("audio-device", QString("-1")).toInt(); + } if (!std::isnormal(_init_data.params.contrast)) { _init_data.params.contrast = _settings->value("contrast", QString("0")).toFloat(); @@ -2173,6 +2226,10 @@ main_window::main_window(QSettings *settings, const player_init_data &init_data) connect(preferences_crosstalk_act, SIGNAL(triggered()), this, SLOT(preferences_crosstalk())); preferences_menu->addAction(preferences_crosstalk_act); preferences_menu->addSeparator(); + QAction *preferences_audio_act = new QAction(_("&Audio Settings..."), this); + connect(preferences_audio_act, SIGNAL(triggered()), this, SLOT(preferences_audio())); + preferences_menu->addAction(preferences_audio_act); + preferences_menu->addSeparator(); QAction *preferences_subtitle_act = new QAction(_("&Subtitle Settings..."), this); connect(preferences_subtitle_act, SIGNAL(triggered()), this, SLOT(preferences_subtitle())); preferences_menu->addAction(preferences_subtitle_act); @@ -2535,6 +2592,7 @@ void main_window::closeEvent(QCloseEvent *event) _timer->stop(); // Remember the Session preferences _settings->beginGroup("Session"); + _settings->setValue("audio-device", QVariant(_init_data.audio_device).toString()); _settings->setValue("contrast", QVariant(_init_data.params.contrast).toString()); _settings->setValue("brightness", QVariant(_init_data.params.brightness).toString()); _settings->setValue("hue", QVariant(_init_data.params.hue).toString()); @@ -3039,6 +3097,17 @@ void main_window::preferences_crosstalk() _crosstalk_dialog->activateWindow(); } +void main_window::preferences_audio() +{ + if (!_audio_dialog) + { + _audio_dialog = new audio_dialog(&_init_data, &_init_data.params, this); + } + _audio_dialog->show(); + _audio_dialog->raise(); + _audio_dialog->activateWindow(); +} + void main_window::preferences_subtitle() { if (!_subtitle_dialog) diff --git a/src/player_qt.h b/src/player_qt.h index c4160af..823d5d4 100644 --- a/src/player_qt.h +++ b/src/player_qt.h @@ -210,6 +210,25 @@ public: virtual void receive_notification(const notification ¬e); }; +class audio_dialog : public QDialog, public controller +{ + Q_OBJECT + +private: + player_init_data *_init_data; + parameters *_params; + bool _lock; + QComboBox *_device_combobox; + +private slots: + void device_changed(); + +public: + audio_dialog(player_init_data *init_data, parameters *params, QWidget *parent); + + virtual void receive_notification(const notification ¬e); +}; + class subtitle_dialog: public QDialog, public controller { Q_OBJECT @@ -317,6 +336,7 @@ private: controls_widget *_controls_widget; color_dialog *_color_dialog; crosstalk_dialog *_crosstalk_dialog; + audio_dialog *_audio_dialog; subtitle_dialog *_subtitle_dialog; video_dialog *_video_dialog; player_qt_internal *_player; @@ -346,6 +366,7 @@ private slots: void preferences_fullscreen(); void preferences_colors(); void preferences_crosstalk(); + void preferences_audio(); void preferences_subtitle(); void preferences_video(); void help_manual(); |
