Skip to content

Commit

Permalink
PulseAudio: Fix multi speakers configuration.
Browse files Browse the repository at this point in the history
- The PulseAudio profile for the speakers is now used in mumble.
- This also fixed the problem of mumble crashing when using a 7.1 setup.
- Cleared some additional QHash's and remove one that was unused.
- Assigned the pa_sample_spec in order with the structure(format,rate,channels)
- Added multi channel support for echo cancellation.
  • Loading branch information
rawnar authored and hacst committed Mar 6, 2011
1 parent e83173c commit c245e2d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
35 changes: 23 additions & 12 deletions src/mumble/PulseAudio.cpp
Expand Up @@ -162,14 +162,17 @@ void PulseAudioSystem::eventCallback(pa_mainloop_api *api, pa_defer_event *) {
case PA_STREAM_TERMINATED: {
if (pasOutput)
pa_stream_unref(pasOutput);

pa_sample_spec pss = qhSpecMap.value(odev);
pa_channel_map pcm = qhChanMap.value(odev);
if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
pss.format = PA_SAMPLE_FLOAT32NE;
if (pss.rate == 0)
pss.rate = SAMPLE_RATE;
if ((pss.channels == 0) || (! g.s.doPositionalAudio()))
pss.channels = 1;
if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
pss.format = PA_SAMPLE_FLOAT32NE;
pasOutput = pa_stream_new(pacContext, "Mumble Speakers", &pss, NULL);

pasOutput = pa_stream_new(pacContext, "Mumble Speakers", &pss, (pss.channels == 1) ? NULL : &pcm);
pa_stream_set_state_callback(pasOutput, stream_callback, this);
pa_stream_set_write_callback(pasOutput, write_callback, this);
}
Expand Down Expand Up @@ -227,11 +230,11 @@ void PulseAudioSystem::eventCallback(pa_mainloop_api *api, pa_defer_event *) {
pa_stream_unref(pasInput);

pa_sample_spec pss = qhSpecMap.value(idev);
if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
pss.format = PA_SAMPLE_FLOAT32NE;
if (pss.rate == 0)
pss.rate = SAMPLE_RATE;
pss.channels = 1;
if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
pss.format = PA_SAMPLE_FLOAT32NE;

pasInput = pa_stream_new(pacContext, "Microphone", &pss, NULL);
pa_stream_set_state_callback(pasInput, stream_callback, this);
Expand Down Expand Up @@ -286,20 +289,25 @@ void PulseAudioSystem::eventCallback(pa_mainloop_api *api, pa_defer_event *) {
pa_stream_unref(pasSpeaker);

pa_sample_spec pss = qhSpecMap.value(edev);
if (pss.rate == 0)
pss.rate = SAMPLE_RATE;
pss.channels = 1;
pa_channel_map pcm = qhChanMap.value(edev);
if ((pss.format != PA_SAMPLE_FLOAT32NE) && (pss.format != PA_SAMPLE_S16NE))
pss.format = PA_SAMPLE_FLOAT32NE;
pasSpeaker = pa_stream_new(pacContext, "Mumble Speakers (Echo)", &pss, NULL);
if (pss.rate == 0)
pss.rate = SAMPLE_RATE;
if ((pss.channels == 0) || (! g.s.bEchoMulti))
pss.channels = 1;

pasSpeaker = pa_stream_new(pacContext, "Mumble Speakers (Echo)", &pss, (pss.channels == 1) ? NULL : &pcm);
pa_stream_set_state_callback(pasSpeaker, stream_callback, this);
pa_stream_set_read_callback(pasSpeaker, read_callback, this);
}
case PA_STREAM_UNCONNECTED:
do_start = true;
break;
case PA_STREAM_READY: {
if (edev != qsEchoCache) {
if (g.s.bEchoMulti != bEchoMultiCache) {
do_stop = true;
} else if (edev != qsEchoCache) {
do_stop = true;
}
break;
Expand All @@ -322,6 +330,7 @@ void PulseAudioSystem::eventCallback(pa_mainloop_api *api, pa_defer_event *) {
buff.prebuf = -1;
buff.fragsize = iBlockLen;

bEchoMultiCache = g.s.bEchoMulti;
qsEchoCache = edev;

pa_stream_connect_record(pasSpeaker, qPrintable(edev), &buff, PA_STREAM_ADJUST_LATENCY);
Expand Down Expand Up @@ -364,8 +373,8 @@ void PulseAudioSystem::sink_callback(pa_context *, const pa_sink_info *i, int eo

const QString name = QLatin1String(i->name);

pas->qhIndexMap.insert(name, i->index);
pas->qhSpecMap.insert(name, i->sample_spec);
pas->qhChanMap.insert(name, i->channel_map);
pas->qhOutput.insert(name, QLatin1String(i->description));
pas->qhEchoMap.insert(name, QLatin1String(i->monitor_source_name));
}
Expand All @@ -380,8 +389,8 @@ void PulseAudioSystem::source_callback(pa_context *, const pa_source_info *i, in

const QString name = QLatin1String(i->name);

pas->qhIndexMap.insert(name, i->index);
pas->qhSpecMap.insert(name, i->sample_spec);
pas->qhChanMap.insert(name, i->channel_map);

if (i->monitor_of_sink == PA_INVALID_INDEX)
pas->qhInput.insert(QLatin1String(i->name), QLatin1String(i->description));
Expand Down Expand Up @@ -542,6 +551,8 @@ void PulseAudioSystem::query() {
qhInput.clear();
qhOutput.clear();
qhEchoMap.clear();
qhSpecMap.clear();
qhChanMap.clear();
qhInput.insert(QString(), tr("Default Input"));
qhOutput.insert(QString(), tr("Default Output"));
pa_operation_unref(pa_context_get_server_info(pacContext, server_callback, this));
Expand Down
3 changes: 2 additions & 1 deletion src/mumble/PulseAudio.h
Expand Up @@ -56,9 +56,10 @@ class PulseAudioSystem : public QObject {
int iDelayCache;
QString qsOutputCache, qsInputCache, qsEchoCache;
bool bPositionalCache;
bool bEchoMultiCache;
QHash<QString, QString> qhEchoMap;
QHash<QString, pa_sample_spec> qhSpecMap;
QHash<QString, int> qhIndexMap;
QHash<QString, pa_channel_map> qhChanMap;

static void defer_event_callback(pa_mainloop_api *a, pa_defer_event *e, void *userdata);
static void context_state_callback(pa_context *c, void *userdata);
Expand Down

0 comments on commit c245e2d

Please sign in to comment.