Ticket #8693: mythtv-pulseaudio.2.diff

File mythtv-pulseaudio.2.diff, 4.5 KB (added by pmhahn+mythtv@…, 16 years ago)

patch for audiooutputpulse.cpp from trunk (r26372)

  • mythtv/libs/libmyth/audiooutputpulse.cpp

    Add support for controlling PulseAudio stream volume.
    
    PulseAudio can controll the individual stream volume in addition to controlling
    the sink volume. Since I use MythTV on my desktop computer, muting and changing
    the sink-volume changes all sounds, including other sounds like desktop events
    and other audio streams.
    This patch adds support to controlling the stream volume by selecting "PCM" for
    the MixerControl. Selecting "Master" uses the old schema of controlling the
    sink volume.
    
    The second part of this patch also sets several properties which help in
    identifying the right stream with PulseAudio enabled applications.
     
    335335    volume = min(100, volume);
    336336    volume = max(0, volume);
    337337
    338     uint32_t sink_index = pa_stream_get_device_index(pstream);
    339     pa_threaded_mainloop_lock(mainloop);
    340     pa_operation *op =
    341         pa_context_set_sink_volume_by_index(pcontext, sink_index,
    342                                             &volume_control,
    343                                             OpCompletionCallback, this);
    344     pa_threaded_mainloop_unlock(mainloop);
    345     if (op)
    346         pa_operation_unref(op);
     338    if (gCoreContext->GetSetting("MixerControl", "PCM").toLower() == "pcm")
     339    {
     340        uint32_t stream_index = pa_stream_get_index(pstream);
     341        pa_threaded_mainloop_lock(mainloop);
     342        pa_operation *op =
     343            pa_context_set_sink_input_volume(pcontext, stream_index,
     344                                             &volume_control,
     345                                             OpCompletionCallback, this);
     346        pa_threaded_mainloop_unlock(mainloop);
     347        if (op)
     348            pa_operation_unref(op);
     349        else
     350            VBERROR(fn_log_tag +
     351                    QString("set stream volume operation failed, stream %1, error %2 ")
     352                    .arg(stream_index).arg(pa_strerror(pa_context_errno(pcontext))));
     353    }
    347354    else
    348         VBERROR(fn_log_tag +
    349                 QString("set sink volume operation failed, sink %1, error %2 ")
    350                 .arg(sink_index).arg(pa_strerror(pa_context_errno(pcontext))));
     355    {
     356        uint32_t sink_index = pa_stream_get_device_index(pstream);
     357        pa_threaded_mainloop_lock(mainloop);
     358        pa_operation *op =
     359            pa_context_set_sink_volume_by_index(pcontext, sink_index,
     360                                                &volume_control,
     361                                                OpCompletionCallback, this);
     362        pa_threaded_mainloop_unlock(mainloop);
     363        if (op)
     364            pa_operation_unref(op);
     365        else
     366            VBERROR(fn_log_tag +
     367                    QString("set sink volume operation failed, sink %1, error %2 ")
     368                    .arg(sink_index).arg(pa_strerror(pa_context_errno(pcontext))));
     369    }
    351370}
    352371
    353372void AudioOutputPulseAudio::Drain(void)
     
    373392        pcontext = NULL;
    374393        return false;
    375394    }
    376     pcontext = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "MythTV");
     395    pa_proplist *proplist = pa_proplist_new();
     396    if (!proplist)
     397    {
     398        VERBOSE(VB_IMPORTANT, LOC_ERR + fn_log_tag +
     399                QString("failed to create new proplist"));
     400        return false;
     401    }
     402    pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "MythTV");
     403    pa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "mythtv");
     404    pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, "video");
     405    pcontext = pa_context_new_with_proplist(pa_threaded_mainloop_get_api(mainloop), "MythTV", proplist);
    377406    if (!pcontext)
    378407    {
    379408        VBERROR(fn_log_tag + "failed to acquire new context");
     
    480509bool AudioOutputPulseAudio::ConnectPlaybackStream(void)
    481510{
    482511    QString fn_log_tag = "ConnectPlaybackStream, ";
    483     pstream = pa_stream_new(pcontext, "MythTV playback", &sample_spec,
    484                             &channel_map);
     512    pa_proplist *proplist = pa_proplist_new();
     513    if (!proplist)
     514    {
     515        VERBOSE(VB_IMPORTANT, LOC_ERR + fn_log_tag +
     516                QString("failed to create new proplist"));
     517        return false;
     518    }
     519    pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, "video");
     520    pstream = pa_stream_new_with_proplist(pcontext, "MythTV playback", &sample_spec,
     521                            &channel_map, proplist);
    485522    if (!pstream)
    486523    {
    487524        VBERROR(fn_log_tag + QString("failed to create new playback stream"));