summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Lambers <marlam@marlam.de>2012-01-28 19:10:14 +0100
committerMartin Lambers <marlam@marlam.de>2012-01-28 19:10:14 +0100
commit7dc2939801a53b10b50333b5de14480a6c4a335c (patch)
tree80171813ed31f7077f421d5ef859236089595936
parent3e6ea1acfffacdb12f737802d0078539b5f29bbb (diff)
downloadbino-7dc2939801a53b10b50333b5de14480a6c4a335c.tar.gz
Add support for selecting an audio device.
-rw-r--r--doc/bino.14
-rw-r--r--doc/bino.texi5
-rw-r--r--src/audio_output.cpp48
-rw-r--r--src/audio_output.h13
-rw-r--r--src/main.cpp28
-rw-r--r--src/player.cpp7
-rw-r--r--src/player.h3
-rw-r--r--src/player_qt.cpp69
-rw-r--r--src/player_qt.h21
9 files changed, 187 insertions, 11 deletions
diff --git a/doc/bino.1 b/doc/bino.1
index a021004..6eeb8e7 100644
--- a/doc/bino.1
+++ b/doc/bino.1
@@ -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 &note)
}
+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 &note);
};
+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 &note);
+};
+
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();