Ticket #7517: volume_control_mythtv_r23492.patch

File volume_control_mythtv_r23492.patch, 76.5 KB (added by mythtv@…, 14 years ago)
  • configure

     
    595595    eval "$var=\"\$$var $*\""
    596596}
    597597
     598prepend(){
     599    var=$1
     600    shift
     601    flags_saved && eval "SAVE_$var=\"$* \$SAVE_$var\""
     602    eval "$var=\"$* \$$var\""
     603}
     604
    598605add_cflags(){
    599606    append CFLAGS "$@"
    600607}
     
    33253332    enable  audio_alsa ||
    33263333    disable audio_alsa
    33273334
     3335# OSS probe
     3336if ! disabled audio_oss ; then
     3337    if test -f /usr/"${libdir_name}"/oss/include/sys/soundcard.h &&
     3338       check_cpp_condition /usr/"${libdir_name}"/oss/include/sys/soundcard.h "SOUND_VERSION >= 0x040000"; then
     3339        disable soundcard_h
     3340        enable sys_soundcard_h
     3341        prepend CONFIG_INCLUDEPATH "/usr/${libdir_name}/oss/include"
     3342    elif test -f /usr/local/"${libdir_name}"/oss/include/sys/soundcard.h &&
     3343       check_cpp_condition /usr/local/"${libdir_name}"/oss/include/sys/soundcard.h "SOUND_VERSION >= 0x040000"; then
     3344        disable soundcard_h
     3345        enable sys_soundcard_h
     3346        prepend CONFIG_INCLUDEPATH "/usr/local/${libdir_name}/oss/include"
     3347    else
     3348        if enabled soundcard_h ; then
     3349            check_cpp_condition soundcard.h "SOUND_VERSION >= 0x040000" &&
     3350            enable  audio_oss ||
     3351            disable audio_oss
     3352        elif enabled sys_soundcard_h ; then
     3353            check_cpp_condition sys/soundcard.h "SOUND_VERSION >= 0x040000" &&
     3354            enable  audio_oss ||
     3355            disable audio_oss
     3356        fi
     3357    fi
     3358fi
     3359
    33283360# JACK probe
    33293361! disabled audio_jack &&
    33303362    check_lib jack/jack.h jack_client_new $audio_jack_libs &&
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    100100    kDisplayNUVTeletextCaptions,
    101101};
    102102
    103 NuppelVideoPlayer::NuppelVideoPlayer(bool muted)
     103NuppelVideoPlayer::NuppelVideoPlayer()
    104104    : decoder(NULL),                decoder_change_lock(QMutex::Recursive),
    105105      videoOutput(NULL),            player_ctx(NULL),
    106106      no_hardware_decoders(false),
     
    170170      audio_channels(2),            audio_codec(0),
    171171      audio_bits(-1),               audio_samplerate(44100),
    172172      audio_stretchfactor(1.0f),    audio_lock(QMutex::Recursive),
    173       audio_muted_on_creation(muted),
    174173      // Picture-in-Picture stuff
    175174      pip_active(false),            pip_visible(true),
    176175      // Preview window support
     
    367366    audio_samplerate      = (int)samplerate;
    368367}
    369368
    370 uint NuppelVideoPlayer::GetVolume(void)
    371 {
    372     QMutexLocker lock(&audio_lock);
    373     if (audioOutput)
    374         return audioOutput->GetCurrentVolume();
    375     return 0;
    376 }
    377 
    378 bool NuppelVideoPlayer::SetMuted(bool mute)
    379 {
    380     QMutexLocker lock(&audio_lock);
    381     bool is_muted = IsMuted();
    382 
    383     if (audioOutput && !is_muted && mute &&
    384         (kMuteAll == SetMuteState(kMuteAll)))
    385     {
    386         VERBOSE(VB_AUDIO, "muting sound " <<IsMuted());
    387         return true;
    388     }
    389     else if (audioOutput && is_muted && !mute &&
    390              (kMuteOff == SetMuteState(kMuteOff)))
    391     {
    392         VERBOSE(VB_AUDIO, "unmuting sound "<<IsMuted());
    393         return true;
    394     }
    395 
    396     VERBOSE(VB_AUDIO, "not changing sound mute state "<<IsMuted());
    397 
    398     return false;
    399 }
    400 
    401 MuteState NuppelVideoPlayer::SetMuteState(MuteState mstate)
    402 {
    403     QMutexLocker lock(&audio_lock);
    404     if (audioOutput)
    405         return audioOutput->SetMuteState(mstate);
    406     return kMuteAll;
    407 }
    408 
    409 MuteState NuppelVideoPlayer::IncrMuteState(void)
    410 {
    411     QMutexLocker lock(&audio_lock);
    412     MuteState mstate = kMuteAll;
    413     if (audioOutput)
    414         mstate = SetMuteState(VolumeBase::NextMuteState(GetMuteState()));
    415     return mstate;
    416 }
    417 
    418 MuteState NuppelVideoPlayer::GetMuteState(void)
    419 {
    420     QMutexLocker lock(&audio_lock);
    421     if (audioOutput)
    422         return audioOutput->GetMuteState();
    423     return kMuteAll;
    424 }
    425 
    426 uint NuppelVideoPlayer::AdjustVolume(int change)
    427 {
    428     QMutexLocker lock(&audio_lock);
    429     if (audioOutput)
    430         audioOutput->AdjustCurrentVolume(change);
    431     return GetVolume();
    432 }
    433 
    434369void NuppelVideoPlayer::PauseDecoder(void)
    435370{
    436371    decoder_lock.lock();
     
    859794
    860795    if (!audioOutput && !using_null_videoout && player_ctx->IsAudioNeeded())
    861796    {
    862         bool setVolume = gContext->GetNumSetting("MythControlsVolume", 1);
    863797        audioOutput = AudioOutput::OpenAudio(audio_main_device,
    864798                                             audio_passthru_device,
    865799                                             audio_bits, audio_channels,
    866800                                             audio_codec, audio_samplerate,
    867801                                             AUDIOOUTPUT_VIDEO,
    868                                              setVolume, audio_passthru);
     802                                             audio_passthru);
    869803        if (!audioOutput)
    870804            errMsg = QObject::tr("Unable to create AudioOutput.");
    871805        else
     
    887821            VERBOSE(VB_IMPORTANT, LOC + "Enabling Audio");
    888822            no_audio_out = false;
    889823        }
    890         if (audio_muted_on_creation)
    891         {
    892             SetMuteState(kMuteAll);
    893             audio_muted_on_creation = false;
    894         }
    895824    }
    896825
    897826    if (audioOutput)
  • libs/libmythtv/avformatdecoder.cpp

     
    495495      audioSamples(NULL),           audioSamplesResampled(NULL),
    496496      reformat_ctx(NULL),           audio_src_fmt(SAMPLE_FMT_NONE),
    497497      allow_ac3_passthru(false),    allow_dts_passthru(false),
    498       internal_vol(false),
    499498      disable_passthru(false),      max_channels(2),
    500499      last_ac3_channels(0),         dummy_frame(NULL),
    501500      // DVD
     
    518517    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
    519518    allow_ac3_passthru = (max_channels > 2) ? gContext->GetNumSetting("AC3PassThru", false) : false;
    520519    allow_dts_passthru = (max_channels > 2) ? gContext->GetNumSetting("DTSPassThru", false) : false;
    521     internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
    522520
    523521    audioIn.sample_size = -32; // force SetupAudioStream to run once
    524522    itv = GetNVP()->GetInteractiveTV();
     
    45284526
    45294527    if (ctx->codec_id == CODEC_ID_AC3)
    45304528        passthru = allow_ac3_passthru &&
    4531                    ctx->channels >= (int)max_channels &&
    4532                    !internal_vol;
     4529                   ctx->channels >= (int)max_channels;
    45334530    else if (ctx->codec_id == CODEC_ID_DTS)
    4534         passthru = allow_dts_passthru && !internal_vol;
     4531        passthru = allow_dts_passthru;
    45354532
    45364533    passthru &= !transcoding && !disable_passthru;
    45374534    // Don't know any cards that support spdif clocked at < 44100
  • libs/libmythtv/tv_play.h

     
    3434#include "programlist.h"
    3535#include "channelutil.h"
    3636#include "videoouttypes.h"
    37 #include "volumebase.h"
     37#include "volumecontrolmanager.h"
    3838#include "inputinfo.h"
    3939#include "channelgroup.h"
    4040
     
    293293    void AddUDPNotifyEvent(const QString &name, const UDPNotifyOSDSet*);
    294294    void ClearUDPNotifyEvents(void);
    295295
     296    void VolumeChanged(int volume);
     297    void MuteChanged(bool mute);
     298
    296299  protected:
    297300    void TreeMenuEntered(OSDListTreeItemEnteredEvent *e);
    298301    void TreeMenuSelected(OSDListTreeItemSelectedEvent *e);
     
    302305    virtual void run(void);
    303306    void TVEventThreadChecks(void);
    304307
    305     void SetMuteTimer(PlayerContext*, int timeout);
    306     bool MuteChannelChange(PlayerContext *ctx);
    307 
    308308    bool eventFilter(QObject *o, QEvent *e);
    309309    static QStringList lastProgramStringList;
    310310    static EMBEDRETURNVOID RunPlaybackBoxPtr;
     
    502502
    503503    vector<long long> TeardownAllNVPs(PlayerContext*);
    504504    void RestartAllNVPs(PlayerContext *lctx,
    505                         const vector<long long> &pos,
    506                         MuteState mctx_mute);
     505                        const vector<long long> &pos);
    507506    void RestartMainNVP(PlayerContext *mctx);
    508507
    509508    void PxPToggleView(  PlayerContext *actx, bool wantPBP);
     
    664663    /// Picture attribute to modify (on arrow left or right)
    665664    PictureAttribute  adjustingPictureAttribute;
    666665
     666    QSharedPointer<VolumeControl> volumeControl; ///< Volume Control interface
     667
    667668    // Ask Allow state
    668669    AskAllowType                 askAllowType;
    669670    QMap<QString,AskProgramInfo> askAllowPrograms;
     
    821822    TimerContextMap      stateChangeTimerId;
    822823    TimerContextMap      signalMonitorTimerId;
    823824    TimerContextMap      tvchainUpdateTimerId;
    824     TimerContextMap      unmuteTimerId;
    825825
    826826    /// Condition to signal that the Event thread is up and running
    827827    QWaitCondition mainLoopCond;
     
    842842
    843843    ///< Timeout for entry modes in msec
    844844    static const uint kInputModeTimeout;
    845     /// Channel changing mute timeout in msec
    846     static const uint kMuteTimeout;
    847845    /// Timeout for updating LCD info in msec
    848846    static const uint kLCDTimeout;
    849847    /// Timeout for browse mode exit in msec
  • libs/libmythtv/playercontext.cpp

     
    430430
    431431bool PlayerContext::CreateNVP(TV *tv, QWidget *widget,
    432432                              TVState desiredState,
    433                               WId embedwinid, const QRect *embedbounds,
    434                               bool muted)
     433                              WId embedwinid, const QRect *embedbounds)
    435434{
    436435    int exact_seeking = gContext->GetNumSetting("ExactSeeking", 0);
    437436
     
    442441        return false;
    443442    }
    444443
    445     NuppelVideoPlayer *_nvp = new NuppelVideoPlayer(muted);
     444    NuppelVideoPlayer *_nvp = new NuppelVideoPlayer();
    446445
    447446    if (nohardwaredecoders)
    448447        _nvp->DisableHardwareDecoders();
     
    492491                VERBOSE(VB_IMPORTANT, LOC_ERR + errMsg);
    493492        }
    494493    }
    495     else if (pipState == kPBPRight)
    496         nvp->SetMuted(true);
    497494
    498495    int maxWait = -1;
    499496    //if (isPIP())
  • libs/libmythtv/NuppelVideoPlayer.h

     
    44#include <sys/time.h>
    55
    66#include "playercontext.h"
    7 #include "volumebase.h"
    87#include "RingBuffer.h"
    98#include "osd.h"
    109#include "jitterometer.h"
     
    8988    friend class PlayerContext;
    9089
    9190  public:
    92     NuppelVideoPlayer(bool muted = false);
     91    NuppelVideoPlayer();
    9392   ~NuppelVideoPlayer();
    9493
    9594    // Initialization
     
    112111    void SetAudioInfo(const QString &main, const QString &passthru, uint rate);
    113112    void SetAudioParams(int bits, int channels, int codec, int samplerate, bool passthru);
    114113    void SetEffDsp(int dsprate);
    115     uint AdjustVolume(int change);
    116     bool SetMuted(bool mute);
    117     MuteState SetMuteState(MuteState);
    118     MuteState IncrMuteState(void);
    119114    void SetAudioCodec(void *ac);
    120115
    121116    // Sets
     
    172167    float   GetVideoAspect(void) const        { return video_aspect; }
    173168    float   GetFrameRate(void) const          { return video_frame_rate; }
    174169
    175     uint    GetVolume(void);
    176170    int     GetSecondsBehind(void) const;
    177171    AspectOverrideMode GetAspectOverride(void) const;
    178172    AdjustFillMode     GetAdjustFill(void) const;
    179     MuteState          GetMuteState(void);
    180173    CommSkipMode       GetAutoCommercialSkip(void) const;
    181174
    182175    int     GetFFRewSkip(void) const          { return ffrew_skip; }
     
    211204    bool    HasAudioOut(void) const           { return !no_audio_out; }
    212205    bool    IsPIPActive(void) const           { return pip_active; }
    213206    bool    IsPIPVisible(void) const          { return pip_visible; }
    214     bool    IsMuted(void)              { return GetMuteState() == kMuteAll; }
    215207    bool    UsingNullVideo(void) const { return using_null_videoout; }
    216208    bool    HasTVChainNext(void) const;
    217209
     
    719711    float    audio_stretchfactor;
    720712    bool     audio_passthru;
    721713    QMutex   audio_lock;
    722     bool     audio_muted_on_creation;
    723714
    724715    // Picture-in-Picture
    725716    mutable QMutex pip_players_lock;
  • libs/libmythtv/tv_play.cpp

     
    8484
    8585
    8686const uint TV::kInputModeTimeout             = 5000;
    87 const uint TV::kMuteTimeout                  = 800;
    8887const uint TV::kLCDTimeout                   = 1000;
    8988const uint TV::kBrowseTimeout                = 30000;
    9089const uint TV::kKeyRepeatTimeout             = 300;
     
    991990    player.push_back(new PlayerContext(kPlayerInUseID));
    992991    playerActive = 0;
    993992    playerLock.unlock();
     993
     994    volumeControl = VolumeControlManager::GetControl(gContext->GetSetting("MixerDevice"));
     995    if (volumeControl)
     996    {
     997        connect(volumeControl.data(), SIGNAL(changedVolume(int)),
     998                this, SLOT(VolumeChanged(int)), Qt::QueuedConnection);
     999        connect(volumeControl.data(), SIGNAL(changedMute(bool)),
     1000                this, SLOT(MuteChanged(bool)), Qt::QueuedConnection);
     1001    }
     1002
    9941003    VERBOSE(VB_PLAYBACK, LOC + "ctor -- end");
    9951004}
    9961005
     
    28522861    if (handled)
    28532862        return;
    28542863
    2855     // Check unmute..
    2856     ctx = NULL;
    2857     {
    2858         QMutexLocker locker(&timerIdLock);
    2859         TimerContextMap::iterator it = unmuteTimerId.find(timer_id);
    2860         if (it != unmuteTimerId.end())
    2861         {
    2862             KillTimer(timer_id);
    2863             ctx = *it;
    2864             unmuteTimerId.erase(it);
    2865         }
    2866     }
    2867 
    2868     if (ctx)
    2869     {
    2870         PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
    2871         if (find_player_index(ctx) >= 0)
    2872         {
    2873             ctx->LockDeleteNVP(__FILE__, __LINE__);
    2874             if (ctx->nvp && ctx->nvp->IsMuted())
    2875                 ctx->nvp->SetMuted(false);
    2876             ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    2877         }
    2878         ReturnPlayerLock(mctx);
    2879         handled = true;
    2880     }
    2881 
    28822864    if (handled)
    28832865        return;
    28842866
     
    54195401        }
    54205402    }
    54215403
    5422     MuteState mctx_mute = kMuteOff;
    5423     mctx->LockDeleteNVP(__FILE__, __LINE__);
    5424     if (mctx->nvp)
    5425         mctx_mute = mctx->nvp->GetMuteState();
    5426     mctx->UnlockDeleteNVP(__FILE__, __LINE__);
    5427 
    54285404    vector<long long> pos = TeardownAllNVPs(mctx);
    54295405
    54305406    if (wantPBP)
     
    54425418        }
    54435419    }
    54445420
    5445     RestartAllNVPs(mctx, pos, mctx_mute);
     5421    RestartAllNVPs(mctx, pos);
    54465422
    54475423    VERBOSE(VB_PLAYBACK, LOC +
    54485424            QString("PxPToggleType() converting from %1 to %2 -- end")
     
    55865562* \brief Recreate Main and PIP windows. Could be either PIP or PBP views.
    55875563*/
    55885564void TV::RestartAllNVPs(PlayerContext *lctx,
    5589                         const vector<long long> &pos,
    5590                         MuteState mctx_mute)
     5565                        const vector<long long> &pos)
    55915566{
    55925567    QString loc = LOC + QString("RestartAllNVPs(): ");
    55935568
     
    56345609            pipctx->LockDeleteNVP(__FILE__, __LINE__);
    56355610            if (pipctx->nvp)
    56365611            {
    5637                 pipctx->nvp->SetMuted(true);
    56385612                pipctx->nvp->JumpToFrame(pos[i]);
    56395613            }
    56405614            pipctx->UnlockDeleteNVP(__FILE__, __LINE__);
     
    56465620            ForceNextStateNone(pipctx);
    56475621        }
    56485622    }
    5649 
    5650     // If old main player had a kMuteAll | kMuteOff setting,
    5651     // apply old main player's mute setting to new main player.
    5652     mctx->LockDeleteNVP(__FILE__, __LINE__);
    5653     if (mctx->nvp && ((kMuteAll == mctx_mute) || (kMuteOff == mctx_mute)))
    5654         mctx->nvp->SetMuteState(mctx_mute);
    5655     mctx->UnlockDeleteNVP(__FILE__, __LINE__);
    56565623}
    56575624
    56585625void TV::PxPSwap(PlayerContext *mctx, PlayerContext *pipctx)
     
    56805647        return;
    56815648    }
    56825649
    5683     MuteState mctx_mute = mctx->nvp->GetMuteState();
    56845650    mctx->deleteNVPLock.unlock();
    56855651    pipctx->deleteNVPLock.unlock();
    56865652
     
    56945660    playerActive = (ctx_index == playerActive) ?
    56955661        0 : ((ctx_index == 0) ? ctx_index : playerActive);
    56965662
    5697     RestartAllNVPs(mctx, pos, mctx_mute);
     5663    RestartAllNVPs(mctx, pos);
    56985664
    56995665    SetActive(mctx, playerActive, false);
    57005666
     
    57155681        mctx->deleteNVPLock.unlock();
    57165682        return;
    57175683    }
    5718 
    5719     MuteState mctx_mute = mctx->nvp->GetMuteState();
    5720 
    5721     // HACK - FIXME
    5722     // workaround muted audio when NVP is re-created
    5723     mctx_mute = kMuteOff;
    5724     // FIXME - end
    57255684    mctx->deleteNVPLock.unlock();
    57265685
    57275686    vector<long long> pos = TeardownAllNVPs(mctx);
    5728     RestartAllNVPs(mctx, pos, mctx_mute);
     5687    RestartAllNVPs(mctx, pos);
    57295688    SetActive(mctx, playerActive, false);
    57305689
    57315690    VERBOSE(VB_PLAYBACK, LOC + "Restart main player -- end");
     
    58505809
    58515810    VERBOSE(VB_PLAYBACK, LOC + "DoNVPSeek() -- begin");
    58525811
    5853     bool muted = false;
    5854 
    58555812    ctx->LockDeleteNVP(__FILE__, __LINE__);
    58565813    if (!ctx->nvp)
    58575814    {
     
    58595816        return false;
    58605817    }
    58615818
    5862     if (ctx == GetPlayer(ctx, 0))
    5863         muted = MuteChannelChange(ctx);
    5864 
    58655819    bool res = false;
    58665820
    58675821    if (LONG_LONG_MIN != audiosyncBaseline)
     
    58825836    }
    58835837    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    58845838
    5885     if (muted)
    5886         SetMuteTimer(ctx, kMuteTimeout);
    5887 
    58885839    VERBOSE(VB_PLAYBACK, LOC + "DoNVPSeek() -- end");
    58895840
    58905841    return res;
     
    62476198    NormalSpeed(ctx);
    62486199    StopFFRew(ctx);
    62496200
    6250     ctx->LockDeleteNVP(__FILE__, __LINE__);
    6251     bool muted = MuteChannelChange(ctx);
    6252     ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    6253 
    62546201    struct StatusPosInfo posInfo;
    62556202    ctx->CalcNVPSliderPosition(posInfo);
    62566203
     
    62696216    if (ctx->nvp)
    62706217        ctx->nvp->JumpChapter(chapter);
    62716218    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    6272 
    6273     if (muted)
    6274         SetMuteTimer(ctx, kMuteTimeout);
    62756219}
    62766220
    62776221void TV::DoSkipCommercials(PlayerContext *ctx, int direction)
     
    62826226    if (StateIsLiveTV(GetState(ctx)))
    62836227        return;
    62846228
    6285     ctx->LockDeleteNVP(__FILE__, __LINE__);
    6286     bool muted = MuteChannelChange(ctx);
    6287     ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    6288 
    62896229    struct StatusPosInfo posInfo;
    62906230    ctx->CalcNVPSliderPosition(posInfo);
    62916231
     
    63046244    if (ctx->nvp)
    63056245        ctx->nvp->SkipCommercials(direction);
    63066246    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    6307 
    6308     if (muted)
    6309         SetMuteTimer(ctx, kMuteTimeout);
    63106247}
    63116248
    63126249void TV::SwitchSource(uint source_direction)
     
    64766413        if (mctx != ctx)
    64776414            PIPRemovePlayer(mctx, ctx);
    64786415
    6479         bool muted = false;
    6480         ctx->LockDeleteNVP(__FILE__, __LINE__);
    6481         if (ctx->nvp && ctx->nvp->IsMuted())
    6482             muted = true;
    6483         ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    6484 
    64856416        // pause the decoder first, so we're not reading too close to the end.
    64866417        ctx->buffer->IgnoreLiveEOF(true);
    64876418        ctx->buffer->StopReads();
     
    65336464
    65346465            if (ctx->CreateNVP(
    65356466                    this, gContext->GetMainWindow(), ctx->GetState(),
    6536                     mctx->embedWinID, &mctx->embedBounds, muted))
     6467                    mctx->embedWinID, &mctx->embedBounds))
    65376468            {
    65386469                ScheduleStateChange(ctx);
    65396470                ok = true;
     
    68906821
    68916822void TV::ChangeChannel(PlayerContext *ctx, int direction)
    68926823{
    6893     bool muted = false;
    6894 
    68956824    if ((browse_changrp || (direction == CHANNEL_DIRECTION_FAVORITE)) &&
    68966825        (channel_group_id > -1))
    68976826    {
     
    69226851
    69236852    QString oldinputname = ctx->recorder->GetInput();
    69246853
    6925     muted = MuteChannelChange(ctx);
    6926 
    69276854    if (ctx->paused)
    69286855    {
    69296856        OSD *osd = GetOSDLock(ctx);
     
    69516878    ctx->recorder->ChangeChannel(direction);
    69526879    ClearInputQueues(ctx, false);
    69536880
    6954     if (muted)
    6955         SetMuteTimer(ctx, kMuteTimeout * 2);
    6956 
    69576881    UnpauseLiveTV(ctx);
    69586882
    69596883    if (oldinputname != ctx->recorder->GetInput())
     
    69706894
    69716895    QString channum = chan;
    69726896    QStringList reclist;
    6973     bool muted = false;
    69746897
    69756898    QString oldinputname = ctx->recorder->GetInput();
    69766899
     
    70406963    if (getit || !ctx->recorder || !ctx->recorder->CheckChannel(channum))
    70416964        return;
    70426965
    7043     muted = MuteChannelChange(ctx);
    7044 
    70456966    OSD *osd = GetOSDLock(ctx);
    70466967    if (osd && ctx->paused)
    70476968    {
     
    70676988
    70686989    ctx->recorder->SetChannel(channum);
    70696990
    7070     if (muted)
    7071         SetMuteTimer(ctx, kMuteTimeout * 2);
    7072 
    70736991    UnpauseLiveTV(ctx);
    70746992
    70756993    if (oldinputname != ctx->recorder->GetInput())
     
    81808098
    81818099void TV::ChangeVolume(PlayerContext *ctx, bool up)
    81828100{
    8183     ctx->LockDeleteNVP(__FILE__, __LINE__);
    8184     if (!ctx->nvp)
     8101    if (volumeControl)
    81858102    {
    8186         ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    8187         return;
     8103        if (up)
     8104            volumeControl->increaseVolume();
     8105        else
     8106            volumeControl->decreaseVolume();
    81888107    }
    8189     uint curvol = ctx->nvp->AdjustVolume((up) ? +2 : -2);
    8190     ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    8191 
    8192     QString text = tr("Volume %1 %").arg(curvol);
    8193 
    8194     OSD *osd = GetOSDLock(ctx);
    8195     if (osd && !browsemode)
    8196     {
    8197         osd->ShowStatus(curvol * 10, true, tr("Adjust Volume"), text, 5,
    8198                         kOSDFunctionalType_PictureAdjust);
    8199         SetUpdateOSDPosition(false);
    8200     }
    8201     ReturnOSDLock(ctx, osd);
    82028108}
    82038109
    82048110void TV::ToggleTimeStretch(PlayerContext *ctx)
     
    83478253
    83488254void TV::ToggleMute(PlayerContext *ctx)
    83498255{
    8350     ctx->LockDeleteNVP(__FILE__, __LINE__);
    8351     if (!ctx->nvp || !ctx->nvp->HasAudioOut())
    8352     {
    8353         ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    8354         return;
    8355     }
    8356 
    8357     MuteState mute_status;
    8358 
    8359     if (!MuteIndividualChannels)
    8360     {
    8361         ctx->nvp->SetMuted(!ctx->nvp->IsMuted());
    8362         mute_status = (ctx->nvp->IsMuted()) ? kMuteAll : kMuteOff;
    8363     }
    8364     else
    8365     {
    8366         mute_status = ctx->nvp->IncrMuteState();
    8367     }
    8368     ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    8369 
    8370     QString text;
    8371 
    8372     switch (mute_status)
    8373     {
    8374         case kMuteOff:   text = tr("Mute Off"); break;
    8375         case kMuteAll:   text = tr("Mute On"); break;
    8376         case kMuteLeft:  text = tr("Left Channel Muted"); break;
    8377         case kMuteRight: text = tr("Right Channel Muted"); break;
    8378     }
    8379 
    8380     OSD *osd = GetOSDLock(ctx);
    8381     if (osd && !browsemode)
    8382         osd->SetSettingsText(text, 5);
    8383     ReturnOSDLock(ctx, osd);
     8256    if (volumeControl)
     8257        volumeControl->setMute(!volumeControl->mute());
    83848258}
    83858259
    83868260void TV::ToggleSleepTimer(const PlayerContext *ctx)
     
    85408414    ReturnOSDLock(ctx, osd);
    85418415}
    85428416
    8543 void TV::SetMuteTimer(PlayerContext *ctx, int timeout)
    8544 {
    8545     // message to set the timer will be posted to the main UI thread
    8546     // where it will be caught in eventFilter and processed as CustomEvent
    8547     // this will properly set the mute timer
    8548     // otherwise it never fires on Win32
    8549     QString message = QString("UNMUTE %1 %2").arg((long long)ctx).arg(timeout);
    8550     qApp->postEvent(gContext->GetMainWindow(), new MythEvent(message));
    8551 }
    8552 
    8553 bool TV::MuteChannelChange(PlayerContext *ctx)
    8554 {
    8555     if (!ctx)
    8556         return false;
    8557 
    8558     bool muted = false;
    8559     ctx->LockDeleteNVP(__FILE__, __LINE__);
    8560     if (ctx->nvp && !ctx->nvp->IsMuted())
    8561         muted = ctx->nvp->SetMuted(true);
    8562     ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    8563 
    8564     return muted;
    8565 }
    8566 
    85678417void TV::customEvent(QEvent *e)
    85688418{
    85698419    if (e->type() == OSDCloseEvent::kEventType)
     
    88398689        }
    88408690    }
    88418691
    8842     if (message.left(6) == "UNMUTE")
    8843     {
    8844         if (tokens.size() >= 3)
    8845         {
    8846             long long target = tokens[1].toLongLong();
    8847             PlayerContext *mctx = GetPlayerReadLock(0, __FILE__, __LINE__);
    8848             for (uint i = 0; i < player.size(); i++)
    8849             {
    8850                 PlayerContext *ctx = GetPlayer(mctx, i);
    8851                 if (((long long)ctx) == target)
    8852                 {
    8853                     QMutexLocker locker(&timerIdLock);
    8854                     unmuteTimerId[StartTimer(tokens[2].toUInt(), __LINE__)] = ctx;
    8855                 }
    8856             }
    8857             ReturnPlayerLock(mctx);
    8858         }
    8859     }
    8860 
    88618692    if (message.left(9) == "START_EPG")
    88628693    {
    88638694        int editType = tokens[1].toInt();
     
    93469177        {
    93479178            value = ctx->nvp->getVideoOutput()->GetPictureAttribute(attr);
    93489179        }
    9349         else if (ctx->nvp->HasAudioOut())
     9180        else if (ctx->nvp->HasAudioOut() && volumeControl)
    93509181        {
    9351             value = ctx->nvp->GetVolume();
     9182            value = volumeControl->volume();
    93529183            title = tr("Adjust Volume");
    93539184        }
    93549185    }
     
    1188511716    ReturnPlayerLock(mctx);
    1188611717}
    1188711718
     11719void TV::VolumeChanged(int volume)
     11720{
     11721    OSD *osd = GetOSDL(__FILE__, __LINE__);
     11722    if (osd && !browsemode)
     11723    {
     11724        osd->ShowStatus(volume * 10, true, tr("Adjust Volume"),
     11725                        tr("Volume %1 %").arg(volume), 5,
     11726                        kOSDFunctionalType_PictureAdjust);
     11727        SetUpdateOSDPosition(false);
     11728    }
     11729    ReturnOSDLock(osd);
     11730}
     11731
     11732void TV::MuteChanged(bool mute)
     11733{
     11734    OSD *osd = GetOSDL(__FILE__, __LINE__);
     11735    if (osd && !browsemode)
     11736        osd->SetSettingsText(mute ? tr("Mute On") : tr("Mute Off"), 5);
     11737    ReturnOSDLock(osd);
     11738}
     11739
     11740
    1188811741OSD *TV::GetOSDL(const char *file, int location)
    1188911742{
    1189011743    PlayerContext *actx = GetPlayerReadLock(-1, file, location);
  • libs/libmythtv/playercontext.h

     
    4747    // Actions
    4848    bool CreateNVP(TV *tv, QWidget *widget,
    4949                   TVState desiredState,
    50                    WId embedwinid, const QRect *embedBounds,
    51                    bool muted = false);
     50                   WId embedwinid, const QRect *embedBounds);
    5251    void TeardownPlayer(void);
    5352    bool StartDecoderThread(int maxWait = -1);
    5453    bool StartOSD(TV *tv);
  • libs/libmythtv/avformatdecoder.h

     
    269269
    270270    bool              allow_ac3_passthru;
    271271    bool              allow_dts_passthru;
    272     bool              internal_vol;
    273272    bool              disable_passthru;
    274273    uint              max_channels;
    275274    uint              last_ac3_channels;
  • libs/libmyth/audiooutputwin.cpp

     
    280280{
    281281    return m_nPkts * fragment_size;
    282282}
    283 
    284 int AudioOutputWin::GetVolumeChannel(int channel) const
    285 {
    286     DWORD dwVolume = 0xffffffff;
    287     int Volume = 100;
    288     if (MMSYSERR_NOERROR == waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, &dwVolume))
    289     {
    290         Volume = (channel == 0) ?
    291             (LOWORD(dwVolume) / (0xffff / 100)) :
    292             (HIWORD(dwVolume) / (0xffff / 100));
    293     }
    294 
    295     VERBOSE(VB_AUDIO, "GetVolume(" << channel << ") "
    296             << Volume << "(" << dwVolume << ")");
    297 
    298     return Volume;
    299 }
    300 
    301 void AudioOutputWin::SetVolumeChannel(int channel, int volume)
    302 {
    303     if (channel > 1)
    304     {
    305         Error(QString("Error setting channel: %1. "
    306                       "Only stereo volume supported").arg(channel));
    307         return;
    308     }
    309 
    310     DWORD dwVolume = 0xffffffff;
    311     if (MMSYSERR_NOERROR == waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, &dwVolume))
    312     {
    313         if (channel == 0)
    314             dwVolume = dwVolume & 0xffff0000 | volume * (0xffff / 100);
    315         else
    316             dwVolume = dwVolume & 0xffff | ((volume * (0xffff / 100)) << 16);
    317     }
    318     else
    319     {
    320         dwVolume = volume * (0xffff / 100);
    321         dwVolume |= (dwVolume << 16);
    322     }
    323 
    324     VERBOSE(VB_AUDIO, QString("SetVolume(%1) %2(%3)")
    325             .arg(channel).arg(volume).arg(dwVolume));
    326     waveOutSetVolume((HWAVEOUT)WAVE_MAPPER, dwVolume);
    327 }
  • libs/libmyth/audiooutputjack.h

     
    1111    AudioOutputJACK(const AudioSettings &settings);
    1212    virtual ~AudioOutputJACK();
    1313   
    14     // Volume control
    15     virtual int GetVolumeChannel(int channel) const; // Returns 0-100
    16     virtual void SetVolumeChannel(int channel, int volume); // range 0-100 for vol
    17  
    1814  protected:
    1915
    2016    // You need to implement the following functions
     
    2723
    2824  private:
    2925
    30     void VolumeInit(void);
    31 
    3226    int audioid;
    3327
    3428};
  • libs/libmyth/audiooutputbase.h

     
    1818#include "audiooutput.h"
    1919#include "samplerate.h"
    2020#include "mythverbose.h"
     21#include "volumecontrolmanager.h"
    2122
    2223namespace soundtouch {
    2324class SoundTouch;
     
    4748
    4849    virtual void Reset(void);
    4950
    50     void SetSWVolume(int new_volume, bool save);
    51     int GetSWVolume(void);
    52 
    5351    // timecode is in milliseconds.
    5452    virtual bool AddSamples(char *buffer, int samples, long long timecode);
    5553    virtual bool AddSamples(char *buffers[], int samples, long long timecode);
     
    113111    int audiolen(bool use_lock); // number of valid bytes in audio buffer
    114112    int audiofree(bool use_lock); // number of free bytes in audio buffer
    115113
    116     void UpdateVolume(void);
    117 
    118114    void SetStretchFactorLocked(float factor);
    119115
    120116    int GetBaseAudioTime()                    const { return audiotime;       }
     
    148144    bool killaudio;
    149145
    150146    bool pauseaudio, audio_actually_paused, was_paused;
    151     bool set_initial_vol;
    152147    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    153148
    154149    int configured_audio_channels;
     
    181176    int surround_mode;
    182177    bool allow_ac3_passthru;
    183178    float old_audio_stretchfactor;
    184     int volume;
     179    QSharedPointer<VolumeControl> volume_control; ///< Volume Control interface
    185180
    186181    bool blocking; // do AddSamples calls block?
    187182
  • libs/libmyth/audiosettings.cpp

     
    1515    channels(-1),
    1616    codec(0),
    1717    samplerate(-1),
    18     set_initial_vol(false),
    1918    use_passthru(false),
    2019    source(AUDIOOUTPUT_UNKNOWN),
    2120    upmixer(0)
     
    2928    channels(other.channels),
    3029    codec(other.codec),
    3130    samplerate(other.samplerate),
    32     set_initial_vol(other.set_initial_vol),
    3331    use_passthru(other.use_passthru),
    3432    source(other.source),
    3533    upmixer(other.upmixer)
     
    4442    int audio_codec,
    4543    int audio_samplerate,
    4644    AudioOutputSource audio_source,
    47     bool audio_set_initial_vol,
    4845    bool audio_use_passthru,
    4946    int upmixer_startup) :
    5047    main_device(audio_main_device),
     
    5350    channels(audio_channels),
    5451    codec(audio_codec),
    5552    samplerate(audio_samplerate),
    56     set_initial_vol(audio_set_initial_vol),
    5753    use_passthru(audio_use_passthru),
    5854    source(audio_source),
    5955    upmixer(upmixer_startup)
     
    7369    channels(audio_channels),
    7470    codec(audio_codec),
    7571    samplerate(audio_samplerate),
    76     set_initial_vol(false),
    7772    use_passthru(audio_use_passthru),
    7873    source(AUDIOOUTPUT_UNKNOWN),
    7974    upmixer(upmixer_startup)
  • libs/libmyth/audiooutputalsa.cpp

     
    2121AudioOutputALSA::AudioOutputALSA(const AudioSettings &settings) :
    2222    AudioOutputBase(settings),
    2323    pcm_handle(NULL),
    24     numbadioctls(0),
    25     mixer_handle(NULL),
    26     mixer_control(QString::null)
     24    numbadioctls(0)
    2725{
    2826    // Set everything up
    2927    Reconfigure(settings);
     
    252250    // it really is
    253251    audio_buffer_unused = soundcard_buffer_size - (fragment_size * 4);
    254252
    255     if (internal_vol)
    256         OpenMixer(set_initial_vol);
    257    
    258253    // Device opened successfully
    259254    return true;
    260255}
    261256
    262257void AudioOutputALSA::CloseDevice()
    263258{
    264     CloseMixer();
    265259    if (pcm_handle != NULL)
    266260    {
    267261        snd_pcm_close(pcm_handle);
     
    620614
    621615    return 0;
    622616}
    623 
    624 
    625 int AudioOutputALSA::GetVolumeChannel(int channel) const
    626 {
    627     long actual_volume;
    628 
    629     if (mixer_handle == NULL)
    630         return 100;
    631 
    632     QByteArray mix_ctl = mixer_control.toAscii();
    633     snd_mixer_selem_id_t *sid;
    634     snd_mixer_selem_id_alloca(&sid);
    635     snd_mixer_selem_id_set_index(sid, 0);
    636     snd_mixer_selem_id_set_name(sid, mix_ctl.constData());
    637 
    638     snd_mixer_elem_t *elem = snd_mixer_find_selem(mixer_handle, sid);
    639     if (!elem)
    640     {
    641         VERBOSE(VB_IMPORTANT, QString("Mixer unable to find control %1")
    642                 .arg(mixer_control));
    643         return 100;
    644     }
    645 
    646     snd_mixer_selem_channel_id_t chan = (snd_mixer_selem_channel_id_t) channel;
    647     if (!snd_mixer_selem_has_playback_channel(elem, chan))
    648     {
    649         snd_mixer_selem_id_set_index(sid, channel);
    650         if ((elem = snd_mixer_find_selem(mixer_handle, sid)) == NULL)
    651         {
    652             VERBOSE(VB_IMPORTANT, QString("Mixer unable to find control %1 %2")
    653                     .arg(mixer_control).arg(channel));
    654             return 100;
    655         }
    656     }
    657 
    658     ALSAVolumeInfo vinfo = GetVolumeRange(elem);
    659 
    660     snd_mixer_selem_get_playback_volume(
    661         elem, (snd_mixer_selem_channel_id_t)channel, &actual_volume);
    662 
    663     return vinfo.ToMythRange(actual_volume);
    664 }
    665 
    666 void AudioOutputALSA::SetVolumeChannel(int channel, int volume)
    667 {
    668     SetCurrentVolume(mixer_control, channel, volume);
    669 }
    670 
    671 void AudioOutputALSA::SetCurrentVolume(QString control, int channel, int volume)
    672 {
    673     VERBOSE(VB_AUDIO, QString("Setting %1 volume to %2")
    674             .arg(control).arg(volume));
    675 
    676     if (!mixer_handle)
    677         return; // no mixer, nothing to do
    678 
    679     QByteArray ctl = control.toAscii();
    680     snd_mixer_selem_id_t *sid;
    681     snd_mixer_selem_id_alloca(&sid);
    682     snd_mixer_selem_id_set_index(sid, 0);
    683     snd_mixer_selem_id_set_name(sid, ctl.constData());
    684 
    685     snd_mixer_elem_t *elem = snd_mixer_find_selem(mixer_handle, sid);
    686     if (!elem)
    687     {
    688         VERBOSE(VB_IMPORTANT, QString("Mixer unable to find control %1")
    689                 .arg(control));
    690         return;
    691     }
    692 
    693     snd_mixer_selem_channel_id_t chan = (snd_mixer_selem_channel_id_t) channel;
    694     if (!snd_mixer_selem_has_playback_channel(elem, chan))
    695     {
    696         snd_mixer_selem_id_set_index(sid, channel);
    697         if ((elem = snd_mixer_find_selem(mixer_handle, sid)) == NULL)
    698         {
    699             VERBOSE(VB_IMPORTANT,
    700                     QString("mixer unable to find control %1 %2")
    701                     .arg(control).arg(channel));
    702             return;
    703         }
    704     }
    705 
    706     ALSAVolumeInfo vinfo = GetVolumeRange(elem);
    707 
    708     long set_vol = vinfo.ToALSARange(volume);
    709 
    710     int err = snd_mixer_selem_set_playback_volume(elem, chan, set_vol);
    711     if (err < 0)
    712     {
    713         VERBOSE(VB_IMPORTANT, QString("mixer set channel %1 err %2: %3")
    714                 .arg(channel).arg(err).arg(snd_strerror(err)));
    715     }
    716     else
    717     {
    718         VERBOSE(VB_AUDIO, QString("channel %1 vol set to %2")
    719                 .arg(channel).arg(set_vol));
    720     }
    721 
    722     if (snd_mixer_selem_has_playback_switch(elem))
    723     {
    724         int unmute = (0 != set_vol);
    725         if (snd_mixer_selem_has_playback_switch_joined(elem))
    726         {
    727             // Only mute if all the channels should be muted.
    728             for (int i = 0; i < audio_channels; i++)
    729             {
    730                 if (0 != GetVolumeChannel(i))
    731                     unmute = 1;
    732             }
    733         }
    734 
    735         err = snd_mixer_selem_set_playback_switch(elem, chan, unmute);
    736         if (err < 0)
    737         {
    738             VERBOSE(VB_IMPORTANT, LOC_ERR +
    739                     QString("Mixer set playback switch %1 err %2: %3")
    740                     .arg(channel).arg(err).arg(snd_strerror(err)));
    741         }
    742         else
    743         {
    744             VERBOSE(VB_AUDIO, LOC +
    745                     QString("channel %1 playback switch set to %2")
    746                     .arg(channel).arg(unmute));
    747         }
    748     }
    749 }
    750 
    751 void AudioOutputALSA::OpenMixer(bool setstartingvolume)
    752 {
    753     int volume;
    754 
    755     mixer_control = gContext->GetSetting("MixerControl", "PCM");
    756 
    757     SetupMixer();
    758 
    759     if (mixer_handle != NULL && setstartingvolume)
    760     {
    761         volume = gContext->GetNumSetting("MasterMixerVolume", 80);
    762         SetCurrentVolume("Master", 0, volume);
    763         SetCurrentVolume("Master", 1, volume);
    764 
    765         volume = gContext->GetNumSetting("PCMMixerVolume", 80);
    766         SetCurrentVolume("PCM", 0, volume);
    767         SetCurrentVolume("PCM", 1, volume);
    768     }
    769 }
    770 
    771 void AudioOutputALSA::CloseMixer(void)
    772 {
    773     if (mixer_handle != NULL)
    774         snd_mixer_close(mixer_handle);
    775     mixer_handle = NULL;
    776 }
    777 
    778 void AudioOutputALSA::SetupMixer(void)
    779 {
    780     int err;
    781 
    782     QString alsadevice = gContext->GetSetting("MixerDevice", "default");
    783     QString device = alsadevice.remove(QString("ALSA:"));
    784 
    785     if (mixer_handle != NULL)
    786         CloseMixer();
    787 
    788     if (alsadevice.toLower() == "software")
    789         return;
    790 
    791     VERBOSE(VB_AUDIO, QString("Opening mixer %1").arg(device));
    792 
    793     // TODO: This is opening card 0. Fix for case of multiple soundcards
    794     if ((err = snd_mixer_open(&mixer_handle, 0)) < 0)
    795     {
    796         Warn(QString("Mixer device open error %1: %2")
    797              .arg(err).arg(snd_strerror(err)));
    798         mixer_handle = NULL;
    799         return;
    800     }
    801 
    802     QByteArray dev = device.toAscii();
    803     if ((err = snd_mixer_attach(mixer_handle, dev.constData())) < 0)
    804     {
    805         Warn(QString("Mixer attach error %1: %2"
    806                      "\n\t\t\tCheck Mixer Name in Setup: '%3'")
    807              .arg(err).arg(snd_strerror(err)).arg(device));
    808         CloseMixer();
    809         return;
    810     }
    811 
    812     if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0)
    813     {
    814         Warn(QString("Mixer register error %1: %2")
    815              .arg(err).arg(snd_strerror(err)));
    816         CloseMixer();
    817         return;
    818     }
    819 
    820     if ((err = snd_mixer_load(mixer_handle)) < 0)
    821     {
    822         Warn(QString("Mixer load error %1: %2")
    823              .arg(err).arg(snd_strerror(err)));
    824         CloseMixer();
    825         return;
    826     }
    827 }
    828 
    829 ALSAVolumeInfo AudioOutputALSA::GetVolumeRange(snd_mixer_elem_t *elem) const
    830 {
    831     long volume_min, volume_max;
    832 
    833     int err = snd_mixer_selem_get_playback_volume_range(
    834         elem, &volume_min, &volume_max);
    835 
    836     if (err < 0)
    837     {
    838         static bool first_time = true;
    839         if (first_time)
    840         {
    841             VERBOSE(VB_IMPORTANT,
    842                     "snd_mixer_selem_get_playback_volume_range()" + ENO);
    843             first_time = false;
    844         }
    845     }
    846 
    847     ALSAVolumeInfo vinfo(volume_min, volume_max);
    848 
    849     VERBOSE(VB_AUDIO, QString("Volume range is %1 to %2, mult=%3")
    850             .arg(vinfo.volume_min).arg(vinfo.volume_max)
    851             .arg(vinfo.range_multiplier));
    852 
    853     return vinfo;
    854 }
  • libs/libmyth/audiooutputca.cpp

     
    244244        return false;
    245245    }
    246246
    247     if (internal_vol && set_initial_vol)
    248     {
    249         QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
    250         controlLabel += "MixerVolume";
    251         SetCurrentVolume(gContext->GetNumSetting(controlLabel, 80));
    252     }
    253 
    254247    return true;
    255248}
    256249
     
    399392    return noErr;
    400393}
    401394
    402 int AudioOutputCA::GetVolumeChannel(int channel) const
    403 {
    404     // FIXME: this only returns global volume
    405     (void)channel;
    406     Float32 volume;
    407 
    408     if (!AudioUnitGetParameter(d->mOutputUnit,
    409                                kHALOutputParam_Volume,
    410                                kAudioUnitScope_Global, 0, &volume))
    411         return (int)lroundf(volume * 100.0);
    412 
    413     return 0;    // error case
    414 }
    415 
    416 void AudioOutputCA::SetVolumeChannel(int channel, int volume)
    417 {
    418     // FIXME: this only sets global volume
    419     (void)channel;
    420      AudioUnitSetParameter(d->mOutputUnit, kHALOutputParam_Volume,
    421                            kAudioUnitScope_Global, 0, (volume * 0.01), 0);
    422 }
    423 
    424395// IOProc style callback for SPDIF audio output
    425396static OSStatus RenderCallbackSPDIF(AudioDeviceID        inDevice,
    426397                                    const AudioTimeStamp *inNow,
  • libs/libmyth/volumebase.cpp

     
    1 #include <cstdio>
    2 #include <cstdlib>
    3 
    4 #include <algorithm>
    5 using namespace std;
    6 
    7 #include <QString>
    8 
    9 #include "volumebase.h"
    10 #include "mythcontext.h"
    11 
    12 VolumeBase::VolumeBase() :
    13     internal_vol(false), volume(80),
    14     current_mute_state(kMuteOff)
    15 {
    16     swvol = swvol_setting =
    17         (gContext->GetSetting("MixerDevice", "default").toLower() == "software");
    18 }
    19 
    20 bool VolumeBase::SWVolume(void)
    21 {
    22     return swvol;
    23 }
    24 
    25 void VolumeBase::SWVolume(bool set)
    26 {
    27     if (swvol_setting)
    28         return;
    29     swvol = set;
    30 }
    31 
    32 uint VolumeBase::GetCurrentVolume(void) const
    33 {
    34     return volume;
    35 }
    36 
    37 void VolumeBase::SetCurrentVolume(int value)
    38 {
    39     volume = max(min(value, 100), 0);
    40     UpdateVolume();
    41 
    42     QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
    43     controlLabel += "MixerVolume";
    44     gContext->SaveSetting(controlLabel, volume);   
    45 }
    46 
    47 void VolumeBase::AdjustCurrentVolume(int change)
    48 {
    49     SetCurrentVolume(volume + change);
    50 }
    51 
    52 MuteState VolumeBase::SetMuteState(MuteState mstate)
    53 {
    54     current_mute_state = mstate;
    55     UpdateVolume();
    56     return current_mute_state;
    57 }
    58 
    59 void VolumeBase::ToggleMute(void)
    60 {
    61     bool is_muted = GetMuteState() == kMuteAll;
    62     SetMuteState((is_muted) ? kMuteOff : kMuteAll);
    63 }
    64 
    65 MuteState VolumeBase::GetMuteState(void) const
    66 {
    67     return current_mute_state;
    68 }
    69 
    70 MuteState VolumeBase::NextMuteState(MuteState cur)
    71 {
    72     MuteState next = cur;
    73 
    74     switch (cur)
    75     {
    76        case kMuteOff:
    77            next = kMuteLeft;
    78            break;
    79        case kMuteLeft:
    80            next = kMuteRight;
    81            break;
    82        case kMuteRight:
    83            next = kMuteAll;
    84            break;
    85        case kMuteAll:
    86            next = kMuteOff;
    87            break;
    88     }
    89 
    90     return (next);
    91 }
    92 
    93 void VolumeBase::UpdateVolume(void)
    94 {
    95     int new_volume = volume;
    96     bool save = true;
    97     if (current_mute_state == kMuteAll)
    98     {
    99         new_volume = 0;
    100         save = false;
    101     }
    102 
    103     if (swvol)
    104     {
    105         SetSWVolume(new_volume, save);
    106         return;
    107     }
    108    
    109     // TODO: Avoid assumption that there are 2 channels!
    110     for (int i = 0; i < 2; i++)
    111     {
    112         SetVolumeChannel(i, new_volume);
    113     }
    114    
    115     // Individual channel muting is handled in GetAudioData,
    116     // this code demonstrates the old method.
    117     // if (current_mute_state == kMuteLeft)
    118     // {
    119     //     SetVolumeChannel(0, 0);
    120     // }
    121     // else if (current_mute_state == kMuteRight)
    122     // {
    123     //     SetVolumeChannel(1, 0);
    124     // }
    125 }
    126 
    127 void VolumeBase::SyncVolume(void)
    128 {
    129     // Read the volume from the audio driver and setup our internal state to match
    130     if (swvol)
    131         volume = GetSWVolume();
    132     else
    133         volume = GetVolumeChannel(0);
    134 }
    135 
  • libs/libmyth/audiooutputwin.h

     
    1313    AudioOutputWin(const AudioSettings &settings);
    1414    virtual ~AudioOutputWin();
    1515
    16     // Volume control
    17     virtual int  GetVolumeChannel(int channel) const;
    18     virtual void SetVolumeChannel(int channel, int volume);
    19 
    2016  protected:
    2117    virtual bool OpenDevice(void);
    2218    virtual void CloseDevice(void);
  • libs/libmyth/audiooutputjack.cpp

     
    148148    audio_buffer_unused = JACK_GetBytesFreeSpace(audioid);
    149149    JACK_SetPosition(audioid, BYTES, 0);
    150150
    151     // Setup volume control
    152     if (internal_vol)
    153         VolumeInit();
    154 
    155151    // Device opened successfully
    156152    return true;
    157153}
     
    206202
    207203    return space;
    208204}
    209 
    210 void AudioOutputJACK::VolumeInit(void)
    211 {
    212     int volume = 100;
    213     if (set_initial_vol)
    214         volume = gContext->GetNumSetting("MasterMixerVolume", 80);
    215 
    216     JACK_SetAllVolume(audioid, volume);
    217 }
    218 
    219 int AudioOutputJACK::GetVolumeChannel(int channel) const
    220 {
    221     unsigned int vol = 0;
    222    
    223     if (!internal_vol)
    224         return 100;
    225 
    226     JACK_GetVolumeForChannel(audioid, channel, &vol);
    227     return vol;
    228 }
    229 
    230 void AudioOutputJACK::SetVolumeChannel(int channel, int volume)
    231 {
    232     if (internal_vol)
    233         JACK_SetVolumeForChannel(audioid, channel, volume);
    234 }
    235 
  • libs/libmyth/audiooutputoss.h

     
    1212    AudioOutputOSS(const AudioSettings &settings);
    1313    virtual ~AudioOutputOSS();
    1414
    15     // Volume control
    16     virtual int GetVolumeChannel(int channel) const;
    17     virtual void SetVolumeChannel(int channel, int volume);
    18 
    1915  protected:
    2016    // You need to implement the following functions
    2117    virtual bool OpenDevice(void);
     
    2622    vector<int> GetSupportedRates(void);
    2723
    2824  private:
    29     void VolumeInit(void);
    30     void VolumeCleanup(void);
    31    
    3225    void SetFragSize(void);
    3326   
    3427    int audiofd;
    3528    mutable int numbadioctls;
    36 
    37     // Volume related
    38     int mixerfd;
    39     int control;
    4029};
    4130
    4231#endif
  • libs/libmyth/audiooutputbase.cpp

     
    3737    pauseaudio(false),          audio_actually_paused(false),
    3838    was_paused(false),
    3939
    40     set_initial_vol(settings.set_initial_vol),
    4140    buffer_output_data_for_use(false),
    4241
    4342    // private
     
    5453    needs_upmix(false),
    5554    surround_mode(FreeSurround::SurroundModePassive),
    5655    old_audio_stretchfactor(1.0),
    57     volume(80),
    5856
    5957    blocking(false),
    6058
     
    109107
    110108    allow_ac3_passthru = (orig_config_channels > 2) ? gContext->GetNumSetting("AC3PassThru", false) : false;
    111109
     110    if (gContext->GetSetting("MixerDevice") == "Software:")
     111        volume_control = VolumeControlManager::GetControl("Software:");
     112   
    112113    // You need to call Reconfigure from your concrete class.
    113114    // Reconfigure(laudio_bits,       laudio_channels,
    114115    //             laudio_samplerate, laudio_passthru);
     
    278279    killaudio = false;
    279280    pauseaudio = false;
    280281    was_paused = true;
    281     internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
    282282
    283283    numlowbuffer = 0;
    284284
     
    359359        return;
    360360    }
    361361
    362     // Only used for software volume
    363     if (set_initial_vol && internal_vol)
    364         volume = gContext->GetNumSetting("PCMMixerVolume", 80);
    365     {
    366         QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
    367         controlLabel += "MixerVolume";
    368         volume = gContext->GetNumSetting(controlLabel, 80);
    369     }
    370 
    371     SyncVolume();
    372     VolumeBase::UpdateVolume();
    373 
    374362    VERBOSE(VB_AUDIO, LOC + QString("Audio fragment size: %1")
    375363            .arg(fragment_size));
    376364
     
    664652     return audbuf_timecode - GetAudiotime();
    665653}
    666654
    667 void AudioOutputBase::SetSWVolume(int new_volume, bool save)
    668 {
    669     volume = new_volume;
    670     if (save)
    671     {
    672         QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
    673         controlLabel += "MixerVolume";
    674         gContext->SaveSetting(controlLabel, volume);
    675     }
    676 }
    677 
    678 int AudioOutputBase::GetSWVolume()
    679 {
    680     return volume;
    681 }
    682 
    683655void AudioOutputBase::AdjustVolume(void *buffer, int len, bool music)
    684656{
    685657    if (audio_bits == 8)
     
    691663template <class AudioDataType>
    692664void AudioOutputBase::_AdjustVolume(AudioDataType *buffer, int len, bool music)
    693665{
     666    int volume = volume_control->mute() ? 0 : volume_control->volume();
     667 
    694668    float g = volume / 100.0;
    695669
    696670    // Should probably be exponential - this'll do
     
    10991073        }
    11001074    }
    11011075
    1102     if (internal_vol && SWVolume())
     1076    if (volume_control)
    11031077    {
    11041078        int bdiff = kAudioRingBufferSize - waud;
    11051079        bool music = (timecode < 1);
     
    13601334    audio_buflock.unlock();
    13611335
    13621336    // Mute individual channels through mono->stereo duplication
    1363     MuteState mute_state = GetMuteState();
     1337//    MuteState mute_state = GetMuteState();
    13641338    if (written_size &&
    1365         audio_channels > 1 &&
    1366         (mute_state == kMuteLeft || mute_state == kMuteRight))
     1339        audio_channels > 1 //&&
     1340//        (mute_state == kMuteLeft || mute_state == kMuteRight)
     1341       )
    13671342    {
    13681343        int offset_src = 0;
    13691344        int offset_dst = 0;
    13701345 
    1371         if (mute_state == kMuteLeft)
    1372             offset_src = audio_bits / 8;    // copy channel 1 to channel 0
    1373         else if (mute_state == kMuteRight)
    1374             offset_dst = audio_bits / 8;    // copy channel 0 to channel 1
     1346//        if (mute_state == kMuteLeft)
     1347//            offset_src = audio_bits / 8;    // copy channel 1 to channel 0
     1348//        else if (mute_state == kMuteRight)
     1349//            offset_dst = audio_bits / 8;    // copy channel 0 to channel 1
    13751350     
    13761351        for (int i = 0; i < written_size; i += audio_bytes_per_sample)
    13771352        {
  • libs/libmyth/audiooutput.cpp

     
    3434    int audio_bits, int audio_channels,
    3535    int audio_codec, int audio_samplerate,
    3636    AudioOutputSource source,
    37     bool set_initial_vol, bool audio_passthru,
     37    bool audio_passthru,
    3838    int upmixer_startup)
    3939{
    4040    AudioSettings settings(
    4141        main_device, passthru_device, audio_bits,
    4242        audio_channels, audio_codec, audio_samplerate, source,
    43         set_initial_vol, audio_passthru, upmixer_startup);
     43        audio_passthru, upmixer_startup);
    4444
    4545    settings.FixPassThrough();
    4646
  • libs/libmyth/libmyth.pro

     
    2323HEADERS += output.h
    2424HEADERS += settings.h
    2525HEADERS += uilistbtntype.h uitypes.h util.h mythuifilebrowser.h
    26 HEADERS += volumebase.h visual.h xmlparse.h
     26HEADERS += volumecontrol.h volumecontrolmanager.h volumecontrolsoftware.h
     27HEADERS += visual.h xmlparse.h
    2728HEADERS += mythhdd.h mythcdrom.h storagegroup.h dbutil.h
    2829HEADERS += mythcommandlineparser.h mythterminal.h
    2930HEADERS += mythhttppool.h mythhttphandler.h
     
    4748SOURCES += output.cpp
    4849SOURCES += settings.cpp
    4950SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp mythuifilebrowser.cpp
    50 SOURCES += volumebase.cpp xmlparse.cpp
     51SOURCES += volumecontrolmanager.cpp volumecontrolsoftware.cpp
     52SOURCES += xmlparse.cpp
    5153SOURCES += mythhdd.cpp mythcdrom.cpp storagegroup.cpp dbutil.cpp
    5254SOURCES += mythcommandlineparser.cpp mythterminal.cpp
    5355SOURCES += mythhttppool.cpp mythhttphandler.cpp
     
    8789# Install headers so that plugins can compile independently
    8890inc.path = $${PREFIX}/include/mythtv/
    8991inc.files  = dialogbox.h mythcontext.h
    90 inc.files += mythwidgets.h remotefile.h oldsettings.h volumecontrol.h
     92inc.files += mythwidgets.h remotefile.h oldsettings.h
    9193inc.files += settings.h uitypes.h xmlparse.h mythplugin.h mythdialogs.h
    9294inc.files += audiooutput.h audiosettings.h util.h
    9395inc.files += inetcomms.h mythmedia.h mythwizard.h schemawizard.h dbutil.h
    9496inc.files += uilistbtntype.h generictree.h managedlist.h mythmediamonitor.h
    95 inc.files += visual.h volumebase.h output.h langsettings.h
     97inc.files += visual.h volumecontrol.h volumecontrolmanager.h output.h langsettings.h
    9698inc.files += mythexp.h mythpluginapi.h storagegroup.h
    9799inc.files += mythconfigdialogs.h mythconfiggroups.h
    98100inc.files += mythterminal.h mythdeque.h mythuifilebrowser.h
     
    107109
    108110using_oss {
    109111    DEFINES += USING_OSS
    110     SOURCES += audiooutputoss.cpp
    111     HEADERS += audiooutputoss.h
     112    SOURCES += audiooutputoss.cpp volumecontroloss.cpp
     113    HEADERS += audiooutputoss.h volumecontroloss.h
    112114    LIBS += $$OSS_LIBS
    113115}
    114116
     
    136138
    137139mingw {
    138140    DEFINES += USING_MINGW
    139     SOURCES += mediamonitor-windows.cpp audiooutputwin.cpp audiooutputdx.cpp
    140     HEADERS += mediamonitor-windows.h   audiooutputwin.h   audiooutputdx.h
    141     LIBS += -lpthread -lwinmm -lws2_32
     141    SOURCES += mediamonitor-windows.cpp
     142    HEADERS += mediamonitor-windows.h
     143    SOURCES += audiooutputwin.cpp audiooutputdx.cpp volumecontrolendpoint.cpp
     144    HEADERS += audiooutputwin.h   audiooutputdx.h   volumecontrolendpoint.h
     145    LIBS += -lpthread -lwinmm -lws2_32 -lole32
    142146}
    143147
    144148macx {
    145     HEADERS += audiooutputca.h
    146     SOURCES += audiooutputca.cpp
     149    DEFINES += USE_COREAUDIO
     150    HEADERS += audiooutputca.h volumecontrolcoreaudio.h
     151    SOURCES += audiooutputca.cpp volumecontrolcoreaudio.cpp
    147152    HEADERS += mythcdrom-darwin.h
    148153    SOURCES += mythcdrom-darwin.cpp
    149154
     
    183188
    184189using_alsa {
    185190    DEFINES += USE_ALSA
    186     HEADERS += audiooutputalsa.h
    187     SOURCES += audiooutputalsa.cpp
     191    HEADERS += audiooutputalsa.h volumecontrolalsa.h
     192    SOURCES += audiooutputalsa.cpp volumecontrolalsa.cpp
    188193    LIBS += $$ALSA_LIBS
    189194}
    190195
  • libs/libmyth/audiosettings.h

     
    3232        int               audio_codec,
    3333        int               audio_samplerate,
    3434        AudioOutputSource audio_source,
    35         bool              audio_set_initial_vol,
    3635        bool              audio_use_passthru,
    3736        int               upmixer_startup = 0);
    3837
     
    5857    int     channels;
    5958    int     codec;
    6059    int     samplerate;
    61     bool    set_initial_vol;
    6260    bool    use_passthru;
    6361    AudioOutputSource source;
    6462    int     upmixer;
  • libs/libmyth/audiooutputca.h

     
    2525    bool RenderAudio(unsigned char *aubuf, int size,
    2626                     unsigned long long timestamp);
    2727
    28     // Volume control
    29     virtual int  GetVolumeChannel(int channel) const;
    30     virtual void SetVolumeChannel(int channel, int volume);
    31 
    3228    void Debug(QString msg)
    3329    {   VERBOSE(VB_AUDIO,     "AudioOutputCA::" + msg);   }
    3430
     
    3733
    3834    void Warn(QString msg)
    3935    {   VERBOSE(VB_IMPORTANT, "AudioOutputCA Warning: " + msg);   }
     36    bool internal_vol;
    4037
    4138protected:
    4239
  • libs/libmyth/audiooutputoss.cpp

     
    3030
    3131AudioOutputOSS::AudioOutputOSS(const AudioSettings &settings) :
    3232    AudioOutputBase(settings),
    33     audiofd(-1), numbadioctls(0),
    34     mixerfd(-1), control(SOUND_MIXER_VOLUME)
     33    audiofd(-1), numbadioctls(0)
    3534{
    3635    // Set everything up
    3736    Reconfigure(settings);
     
    194193                " the error was: %1").arg(strerror(errno)));
    195194    }
    196195
    197     // Setup volume control
    198     if (internal_vol)
    199         VolumeInit();
    200 
    201196    // Device opened successfully
    202197    return true;
    203198}
     
    242237        close(audiofd);
    243238
    244239    audiofd = -1;
    245    
    246     VolumeCleanup();
    247240}
    248241
    249242
     
    310303
    311304    return space;
    312305}
    313 
    314 void AudioOutputOSS::VolumeInit()
    315 {
    316     mixerfd = -1;
    317     int volume = 0;
    318 
    319     QString device = gContext->GetSetting("MixerDevice", "/dev/mixer");
    320     if (device.toLower() == "software")
    321         return;
    322 
    323     QByteArray dev = device.toAscii();
    324     mixerfd = open(dev.constData(), O_RDONLY);
    325 
    326     QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
    327 
    328     if (controlLabel == "Master")
    329     {
    330         control = SOUND_MIXER_VOLUME;
    331     }
    332     else
    333     {
    334         control = SOUND_MIXER_PCM;
    335     }
    336 
    337     if (mixerfd < 0)
    338     {
    339         VERBOSE(VB_IMPORTANT, LOC +
    340                 QString("Unable to open mixer: '%1'").arg(device));
    341         return;
    342     }
    343 
    344     if (set_initial_vol)
    345     {
    346         int tmpVol;
    347         volume = gContext->GetNumSetting("MasterMixerVolume", 80);
    348         tmpVol = (volume << 8) + volume;
    349         int ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_VOLUME), &tmpVol);
    350         if (ret < 0)
    351         {
    352             VERBOSE(VB_IMPORTANT, LOC_ERR +
    353                     QString("Error Setting initial Master Volume") + ENO);
    354         }
    355 
    356         volume = gContext->GetNumSetting("PCMMixerVolume", 80);
    357         tmpVol = (volume << 8) + volume;
    358         ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &tmpVol);
    359         if (ret < 0)
    360         {
    361             VERBOSE(VB_IMPORTANT, LOC_ERR +
    362                     QString("Error setting initial PCM Volume") + ENO);
    363         }
    364     }
    365 }
    366 
    367 void AudioOutputOSS::VolumeCleanup()
    368 {
    369     if (mixerfd >= 0)
    370     {
    371         close(mixerfd);
    372         mixerfd = -1;
    373     }
    374 }
    375 
    376 int AudioOutputOSS::GetVolumeChannel(int channel) const
    377 {
    378     int volume=0;
    379     int tmpVol=0;
    380 
    381     if (mixerfd <= 0)
    382         return 100;
    383 
    384     int ret = ioctl(mixerfd, MIXER_READ(control), &tmpVol);
    385     if (ret < 0) {
    386         VERBOSE(VB_IMPORTANT, QString("Error reading volume for channel %1")
    387                           .arg(channel));
    388         perror("Reading PCM volume: ");
    389         return 0;
    390     }
    391 
    392     if (channel == 0) {
    393         volume = tmpVol & 0xff; // left
    394     } else if (channel == 1) {
    395         volume = (tmpVol >> 8) & 0xff; // right
    396     } else {
    397         VERBOSE(VB_IMPORTANT, QString("Invalid channel. Only stereo volume supported"));
    398     }
    399 
    400     return volume;
    401 }
    402 
    403 void AudioOutputOSS::SetVolumeChannel(int channel, int volume)
    404 {
    405     if (channel > 1) {
    406         // Don't support more than two channels!
    407     VERBOSE(VB_IMPORTANT, QString("Error setting channel: %1.  Only stereo volume supported")
    408                                 .arg(channel));
    409         return;
    410     }
    411 
    412     if (volume > 100)
    413         volume = 100;
    414     if (volume < 0)
    415         volume = 0;
    416 
    417     if (mixerfd >= 0)
    418     {
    419         int tmpVol = 0;
    420         if (channel == 0)
    421             tmpVol = (GetVolumeChannel(1) << 8) + volume;
    422         else
    423             tmpVol = (volume << 8) + GetVolumeChannel(0);
    424 
    425         int ret = ioctl(mixerfd, MIXER_WRITE(control), &tmpVol);
    426         if (ret < 0)
    427         {
    428             VERBOSE(VB_IMPORTANT, QString("Error setting volume on channel: %1").arg(channel));
    429             perror("Setting volume: ");
    430         }
    431     }
    432 }
    433 
  • libs/libmyth/volumebase.h

     
    1 #ifndef __VOLUME_BASE__
    2 #define __VOLUME_BASE__
    3 
    4 #include "mythexp.h"
    5 
    6 typedef enum {
    7     kMuteOff = 0,
    8     kMuteLeft,
    9     kMuteRight,
    10     kMuteAll,
    11 } MuteState;
    12 
    13 class MPUBLIC VolumeBase
    14 {
    15   public:
    16     VolumeBase();   
    17     virtual ~VolumeBase() {};
    18 
    19     void SWVolume(bool set);
    20     bool SWVolume(void);
    21     virtual uint GetCurrentVolume(void) const;
    22     virtual void SetCurrentVolume(int value);
    23     virtual void AdjustCurrentVolume(int change);
    24     virtual void ToggleMute(void);
    25 
    26     virtual MuteState GetMuteState(void) const;
    27     virtual MuteState SetMuteState(MuteState);
    28 
    29     static MuteState NextMuteState(MuteState);
    30 
    31   protected:
    32 
    33     virtual int GetVolumeChannel(int channel) const = 0; // Returns 0-100
    34     virtual void SetVolumeChannel(int channel, int volume) = 0; // range 0-100 for vol
    35     virtual void SetSWVolume(int new_volume, bool save) = 0;
    36     virtual int GetSWVolume(void) = 0;
    37 
    38     void UpdateVolume(void);
    39     void SyncVolume(void);
    40 
    41     bool internal_vol;
    42 
    43  private:
    44    
    45     int volume;
    46     MuteState current_mute_state;
    47     bool swvol;
    48     bool swvol_setting;
    49 
    50 };
    51 
    52 #endif // __VOLUME_BASE__
  • libs/libmyth/audiooutputdx.cpp

     
    369369    dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
    370370                    | DSBCAPS_GLOBALFOCUS       /* Allows background playing */
    371371                    | DSBCAPS_LOCHARDWARE;      /* Needed for 5.1 on emu101k */
    372     if (!m_UseSPDIF)
    373         dsbdesc.dwFlags |= DSBCAPS_CTRLVOLUME;  /* Allow volume control */
    374372    dsbdesc.dwBufferBytes = soundcard_buffer_size;   /* buffer size */
    375373    dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&wf;
    376374
     
    517515    return buffered;
    518516}
    519517
    520 int AudioOutputDX::GetVolumeChannel(int channel) const
    521 {
    522     HRESULT dsresult;
    523     long dxVolume = 0;
    524     int volume;
    525 
    526     if (m_UseSPDIF)
    527         return 100;
    528 
    529     dsresult = IDirectSoundBuffer_GetVolume(m_priv->dsbuffer, &dxVolume);
    530     volume = (int)(pow(10,(float)dxVolume/20)*100);
    531 
    532     if (dsresult != DS_OK)
    533     {
    534         VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to get volume %1")
    535                                                 .arg(dxVolume));
    536         return volume;
    537     }
    538 
    539     VERBOSE(VB_AUDIO, LOC + QString("Got volume %1").arg(volume));
    540     return volume;
    541 }
    542 
    543 void AudioOutputDX::SetVolumeChannel(int channel, int volume)
    544 {
    545     HRESULT dsresult;
    546     float dbAtten = 20 * log10((float)volume/100);
    547     long dxVolume = (volume == 0) ? DSBVOLUME_MIN : (long)(100.0f * dbAtten);
    548 
    549     if (m_UseSPDIF)
    550         return;
    551 
    552     // dxVolume is attenuation in 100ths of a decibel
    553     dsresult = IDirectSoundBuffer_SetVolume(m_priv->dsbuffer, dxVolume);
    554 
    555     if (dsresult != DS_OK)
    556     {
    557         VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Failed to set volume %1")
    558                                                 .arg(dxVolume));
    559         return;
    560     }
    561    
    562     VERBOSE(VB_AUDIO, LOC + QString("Set volume %1").arg(dxVolume));
    563 }
    564 
    565518/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmyth/audiooutputnull.h

     
    2727
    2828    virtual void Reset(void);
    2929
    30 
    31     // Volume control
    32     virtual int GetVolumeChannel(int /* channel */) const { return 100; }
    33     virtual void SetVolumeChannel(int /* channel */, int /* volume */){return;}
    34 
    3530    virtual int readOutputData(unsigned char *read_buffer, int max_length);
    3631
    3732  protected:
  • libs/libmyth/audiooutput.h

     
    55
    66#include "audiosettings.h"
    77#include "mythcontext.h"
    8 #include "volumebase.h"
    98#include "output.h"
    109
    11 class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners
     10class MPUBLIC AudioOutput : public OutputListeners
    1211{
    1312 public:
    1413    // opens one of the concrete subclasses
     
    1817        int audio_bits, int audio_channels,
    1918        int audio_codec, int audio_samplerate,
    2019        AudioOutputSource source,
    21         bool set_initial_vol, bool audio_passthru,
     20        bool audio_passthru,
    2221        int upmixer_startup = 0);
    2322
    2423    AudioOutput() :
    25         VolumeBase(),             OutputListeners(),
     24        OutputListeners(),
    2625        lastError(QString::null), lastWarn(QString::null) {}
    2726
    2827    virtual ~AudioOutput() { };
  • libs/libmyth/audiooutputpulse.h

     
    3030    AudioOutputPulseAudio(const AudioSettings &settings);
    3131   ~AudioOutputPulseAudio();
    3232
    33     int GetVolumeChannel(int channel) const;
    34     void SetVolumeChannel(int channel, int volume);
    3533    void Pause(bool paused);
    3634    void Reset(void);
    3735    void Drain(void);
  • libs/libmyth/audiooutputdx.h

     
    1313    AudioOutputDX(const AudioSettings &settings);
    1414    virtual ~AudioOutputDX();
    1515
    16     virtual int GetVolumeChannel(int channel) const;
    17     virtual void SetVolumeChannel(int channel, int volume);
    18 
    1916  protected:
    2017    virtual bool OpenDevice(void);
    2118    virtual void CloseDevice(void);
  • libs/libmyth/audiooutputalsa.h

     
    99
    1010using namespace std;
    1111
    12 class ALSAVolumeInfo
    13 {
    14   public:
    15     ALSAVolumeInfo(long  playback_vol_min,
    16                    long  playback_vol_max) :
    17         range_multiplier(1.0f),
    18         volume_min(playback_vol_min), volume_max(playback_vol_max)
    19     {
    20         float range = (float) (volume_max - volume_min);
    21         if (range > 0.0f)
    22             range_multiplier = 100.0f / range;
    23         range_multiplier_inv = 1.0f / range_multiplier;
    24     }
    25 
    26     int ToMythRange(long alsa_volume)
    27     {
    28         long toz = alsa_volume - volume_min;
    29         int val = (int) (toz * range_multiplier);
    30         val = (val < 0)   ? 0   : val;
    31         val = (val > 100) ? 100 : val;
    32         return val;
    33     }
    34 
    35     long ToALSARange(int myth_volume)
    36     {
    37         float tos = myth_volume * range_multiplier_inv;
    38         long val = (long) (tos + volume_min + 0.5);
    39         val = (val < volume_min) ? volume_min : val;
    40         val = (val > volume_max) ? volume_max : val;
    41         return val;
    42     }
    43 
    44     float range_multiplier;
    45     float range_multiplier_inv;
    46     long  volume_min;
    47     long  volume_max;
    48 };
    49 
    5012class AudioOutputALSA : public AudioOutputBase
    5113{
    5214  public:
    5315    AudioOutputALSA(const AudioSettings &settings);
    5416    virtual ~AudioOutputALSA();
    5517
    56     // Volume control
    57     virtual int GetVolumeChannel(int channel) const; // Returns 0-100
    58     virtual void SetVolumeChannel(int channel, int volume); // range 0-100 for vol
    59 
    60    
    6118  protected:
    6219    // You need to implement the following functions
    6320    virtual bool OpenDevice(void);
     
    7734    void ReorderSmpteToAlsa6ch(void *buf, int frames);
    7835    template <class AudioDataType>
    7936        void _ReorderSmpteToAlsa6ch(AudioDataType *buf, int frames);
    80     // Volume related
    81     void SetCurrentVolume(QString control, int channel, int volume);
    82     void OpenMixer(bool setstartingvolume);
    83     void CloseMixer(void);
    84     void SetupMixer(void);
    85     ALSAVolumeInfo GetVolumeRange(snd_mixer_elem_t *elem) const;
    8637
    8738  private:
    8839    snd_pcm_t   *pcm_handle;
    8940    int          numbadioctls;
    9041    QMutex       killAudioLock;
    91     snd_mixer_t *mixer_handle;
    92     QString      mixer_control; // e.g. "PCM"
    9342    snd_pcm_sframes_t (*pcm_write_func)(snd_pcm_t*, const void*,
    9443                                        snd_pcm_uframes_t);
    9544};
  • libs/libmyth/audiooutputpulse.cpp

     
    268268    return writable;
    269269}
    270270
    271 int AudioOutputPulseAudio::GetVolumeChannel(int channel) const
    272 {
    273     return (float)volume_control.values[channel]
    274         / (float)PA_VOLUME_NORM * 100.0f;
    275 }
    276 
    277 void AudioOutputPulseAudio::SetVolumeChannel(int channel, int volume)
    278 {
    279     QString fn_log_tag = "SetVolumeChannel, ";
    280     if (channel < 0 || channel > PULSE_MAX_CHANNELS || volume < 0)
    281     {
    282         VERBOSE(VB_IMPORTANT, LOC_ERR + fn_log_tag +
    283                 QString("bad volume params, channel %1, volume %2")
    284                 .arg(channel).arg(volume));
    285         return;
    286     }
    287     volume_control.values[channel] =
    288         (float)volume / 100.0f * (float)PA_VOLUME_NORM;
    289     volume = min(100, volume);
    290     volume = max(0, volume);
    291     uint32_t sink_index = pa_stream_get_device_index(pstream);
    292     pa_threaded_mainloop_lock(mainloop);
    293     pa_operation *op =
    294         pa_context_set_sink_volume_by_index(pcontext, sink_index,
    295                                             &volume_control,
    296                                             OpCompletionCallback, this);
    297     pa_threaded_mainloop_unlock(mainloop);
    298     if (op)
    299         pa_operation_unref(op);
    300     else
    301         VERBOSE(VB_IMPORTANT, LOC_ERR + fn_log_tag +
    302                 QString("set sink volume operation failed, sink: %1, "
    303                         "error: %2 ")
    304                 .arg(sink_index)
    305                 .arg(pa_strerror(pa_context_errno(pcontext))));
    306 }
    307 
    308271void AudioOutputPulseAudio::Pause(bool paused)
    309272{
    310273    pa_operation *op;
     
    545508    pa_stream_set_overflow_callback(pstream, BufferFlowCallback, (char*)"over");
    546509    pa_stream_set_underflow_callback(pstream, BufferFlowCallback,
    547510                                     (char*)"under");
    548     if (set_initial_vol)
    549     {
    550         int volume = gContext->GetNumSetting("MasterMixerVolume", 80);
    551         pa_cvolume_set(&volume_control, audio_channels,
    552                        (float)volume * (float)PA_VOLUME_NORM / 100.0f);
    553     }
    554     else
    555         pa_cvolume_reset(&volume_control, audio_channels);
     511    pa_cvolume_reset(&volume_control, audio_channels);
    556512
    557513    // set myth sizes and pa buffer metrics
    558514    fragment_size = (float)sample_rate * 0.020f * // 20msec
  • programs/mythfrontend/globalsettings.cpp

     
    2828#include "iso639.h"
    2929#include "playbackbox.h"
    3030#include "globalsettings.h"
     31#include "libmyth/volumecontrolmanager.h"
    3132#include "recordingprofile.h"
    3233#include "mythxdisplay.h"
    3334#include "DisplayRes.h"
     
    179180    return gc;
    180181}
    181182
    182 static HostCheckBox *MythControlsVolume()
    183 {
    184     HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
    185     gc->setLabel(QObject::tr("Use internal volume controls"));
    186     gc->setValue(true);
    187     gc->setHelpText(QObject::tr("MythTV can control the PCM and master "
    188                     "mixer volume.  If you prefer to control the volume externally "
    189                     "(like your amplifier) or use an external mixer "
    190                     "program, disable this option."));
    191     return gc;
    192 }
    193 
    194183static HostComboBox *MixerDevice()
    195184{
    196185    HostComboBox *gc = new HostComboBox("MixerDevice", true);
    197186    gc->setLabel(QObject::tr("Mixer Device"));
     187    gc->addSelection(QObject::tr("Disabled"), QString());
    198188
    199 #ifdef USING_OSS
    200     QDir dev("/dev", "mixer*", QDir::Name, QDir::System);
    201     gc->fillSelectionsFromDir(dev);
     189    QHash<QString, QString> controls = VolumeControlManager::Enumerate();
    202190
    203     dev.setPath("/dev/sound");
    204     if (dev.exists())
     191    for (QHash<QString, QString>::const_iterator control = controls.begin();
     192         control != controls.end(); ++control)
    205193    {
    206         gc->fillSelectionsFromDir(dev);
     194        gc->addSelection(control.value(), control.key());
    207195    }
    208 #endif
    209 #ifdef USING_ALSA
    210     gc->addSelection("ALSA:default", "ALSA:default");
    211 #endif
    212 #ifdef USING_MINGW
    213     gc->addSelection("DirectX:", "DirectX:");
    214     gc->addSelection("Windows:", "Windows:");
    215 #endif
    216 #if !defined(USING_MINGW)
    217     gc->addSelection("software", "software");
    218     gc->setHelpText(QObject::tr("Setting the mixer device to \"software\" lets MythTV control "
    219                                 "the volume of all audio at the expense of a slight quality loss."));
    220 #endif
    221196
    222197    return gc;
    223198}
    224199
    225 static const char* MixerControlControls[] = { "PCM",
    226                                               "Master" };
    227 
    228 static HostComboBox *MixerControl()
    229 {
    230     HostComboBox *gc = new HostComboBox("MixerControl", true);
    231     gc->setLabel(QObject::tr("Mixer Controls"));
    232     for (unsigned int i = 0; i < sizeof(MixerControlControls) / sizeof(char*);
    233          ++i)
    234     {
    235         gc->addSelection(QObject::tr(MixerControlControls[i]),
    236                          MixerControlControls[i]);
    237     }
    238 
    239     gc->setHelpText(QObject::tr("Changing the volume adjusts the selected mixer."));
    240     return gc;
    241 }
    242 
    243 static HostSlider *MixerVolume()
    244 {
    245     HostSlider *gs = new HostSlider("MasterMixerVolume", 0, 100, 1);
    246     gs->setLabel(QObject::tr("Master Mixer Volume"));
    247     gs->setValue(70);
    248     gs->setHelpText(QObject::tr("Initial volume for the Master Mixer.  "
    249                     "This affects all sound created by the sound card.  "
    250                     "Note: Do not set this too low."));
    251     return gs;
    252 }
    253 
    254 static HostSlider *PCMVolume()
    255 {
    256     HostSlider *gs = new HostSlider("PCMMixerVolume", 0, 100, 1);
    257     gs->setLabel(QObject::tr("PCM Mixer Volume"));
    258     gs->setValue(70);
    259     gs->setHelpText(QObject::tr("Initial volume for PCM output.  Using the "
    260                     "volume keys in MythTV will adjust this parameter."));
    261     return gs;
    262 }
    263 
    264200static HostCheckBox *IndividualMuteControl()
    265201{
    266202    HostCheckBox *gc = new HostCheckBox("IndividualMuteControl");
     
    34973433    group2->addChild(AggressiveBuffer());
    34983434
    34993435    return vcg;
    3500 
    35013436}
    35023437
    3503 class AudioMixerSettingsGroup : public TriggeredConfigurationGroup
     3438static ConfigurationGroup *AudioMixerSettingsGroup()
    35043439{
    3505   public:
    3506     AudioMixerSettingsGroup() :
    3507         TriggeredConfigurationGroup(false, true, false, false)
    3508     {
    3509         setLabel(QObject::tr("Audio Mixer"));
    3510         setUseLabel(false);
     3440    ConfigurationGroup *vcg = new VerticalConfigurationGroup(false, true, false, false);
     3441   
     3442    vcg->setLabel(QObject::tr("Audio Mixer"));
     3443    vcg->setUseLabel(false);
    35113444
    3512         Setting *volumeControl = MythControlsVolume();
    3513         addChild(volumeControl);
     3445    vcg->addChild(MixerDevice());
    35143446
    3515         // Mixer settings
    3516         ConfigurationGroup *settings =
    3517             new VerticalConfigurationGroup(false, true, false, false);
    3518         settings->addChild(MixerDevice());
    3519         settings->addChild(MixerControl());
    3520         settings->addChild(MixerVolume());
    3521         settings->addChild(PCMVolume());
    3522         settings->addChild(IndividualMuteControl());
     3447    return vcg;
     3448}
    35233449
    3524         ConfigurationGroup *dummy =
    3525             new VerticalConfigurationGroup(false, true, false, false);
    3526 
    3527         // Show Mixer config only if internal volume controls enabled
    3528         setTrigger(volumeControl);
    3529         addTarget("0", dummy);
    3530         addTarget("1", settings);
    3531     }
    3532 };
    3533 
    35343450static HostComboBox *MythLanguage()
    35353451{
    35363452    HostComboBox *gc = new HostComboBox("Language");
     
    42144130
    42154131    addChild(AudioSystemSettingsGroup());
    42164132
    4217     addChild(new AudioMixerSettingsGroup());
     4133    addChild(AudioMixerSettingsGroup());
    42184134
    42194135    VerticalConfigurationGroup *general =
    42204136        new VerticalConfigurationGroup(false, true, false, false);
  • programs/mythtranscode/transcode.cpp

     
    166166        return last_audiotime;
    167167    }
    168168
    169     virtual int GetVolumeChannel(int) const
    170     {
    171         // Do nothing
    172         return 100;
    173     }
    174     virtual void SetVolumeChannel(int, int)
    175     {
    176         // Do nothing
    177     }
    178     virtual void SetVolumeAll(int)
    179     {
    180         // Do nothing
    181     }
    182     virtual uint GetCurrentVolume(void) const
    183     {
    184         // Do nothing
    185         return 100;
    186     }
    187     virtual void SetCurrentVolume(int)
    188     {
    189         // Do nothing
    190     }
    191     virtual void AdjustCurrentVolume(int)
    192     {
    193         // Do nothing
    194     }
    195     virtual void SetMute(bool)
    196     {
    197         // Do nothing
    198     }
    199     virtual void ToggleMute(void)
    200     {
    201         // Do nothing
    202     }
    203     virtual MuteState GetMuteState(void) const
    204     {
    205         // Do nothing
    206         return kMuteOff;
    207     }
    208     virtual MuteState IterateMutedChannels(void)
    209     {
    210         // Do nothing
    211         return kMuteOff;
    212     }
    213169    virtual bool ToggleUpmix(void)
    214170    {
    215171        // Do nothing
    216172        return false;
    217173    }
    218174
    219     virtual void SetSWVolume(int new_volume, bool save)
    220     {
    221         // Do nothing
    222         return;
    223     }
    224     virtual int GetSWVolume(void)
    225     {
    226         // Do nothing
    227         return 100;
    228     }
    229 
    230175    //  These are pure virtual in AudioOutput, but we don't need them here
    231176    virtual void bufferOutputData(bool){ return; }
    232177    virtual int readOutputData(unsigned char*, int ){ return 0; }