Ticket #6279: softvol-trunk.patch

File softvol-trunk.patch, 10.5 KB (added by foobum@…, 12 years ago)
  • mythtv/libs/libmyth/audiooutputalsa.cpp

    diff --git a/mythtv/libs/libmyth/audiooutputalsa.cpp b/mythtv/libs/libmyth/audiooutputalsa.cpp
    index 1a66dfe..cce3258 100644
    a b void AudioOutputALSA::SetupMixer(void) 
    699699    if (mixer_handle != NULL)
    700700        CloseMixer();
    701701
     702    if (alsadevice.toLower() == "software")
     703        return;
     704
    702705    VERBOSE(VB_AUDIO, QString("Opening mixer %1").arg(device));
    703706
    704707    // TODO: This is opening card 0. Fix for case of multiple soundcards
  • mythtv/libs/libmyth/audiooutputbase.cpp

    diff --git a/mythtv/libs/libmyth/audiooutputbase.cpp b/mythtv/libs/libmyth/audiooutputbase.cpp
    index 112f554..efa098b 100644
    a b AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 
    5353    needs_upmix(false),
    5454    surround_mode(FreeSurround::SurroundModePassive),
    5555    old_audio_stretchfactor(1.0),
     56    volume(80),
    5657
    5758    blocking(false),
    5859
    void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 
    269270    if(audio_passthru || audio_enc)
    270271        // AC-3 output - soundcard expects a 2ch 48k stream
    271272        audio_channels = 2;
     273
     274    if (internal_vol && audio_enc && audio_reenc)
     275    {
     276        VERBOSE(VB_AUDIO, LOC + "Using software vol control for AC-3");
     277        SWVolume(true);
     278    }
     279    else
     280        SWVolume(false);
    272281   
    273282    audio_bytes_per_sample = audio_channels * audio_bits / 8;
    274283    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 
    309318        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    310319        return;
    311320    }
    312 
     321   
     322    // Only used for software volume
     323    if (set_initial_vol && internal_vol)
     324        volume = gContext->GetNumSetting("PCMMixerVolume", 100);
     325   
    313326    SyncVolume();
    314327
    315328    VERBOSE(VB_AUDIO, LOC + QString("Audio fragment size: %1")
    int AudioOutputBase::GetAudioBufferedTime(void) 
    600613     return audbuf_timecode - GetAudiotime();
    601614}
    602615
     616void AudioOutputBase::SetSWVolume(int new_volume)
     617{
     618    volume = new_volume;
     619}
     620
     621int AudioOutputBase::GetSWVolume()
     622{
     623    return volume;
     624}
     625
     626template <class AudioDataType>
     627void AudioOutputBase::_AdjustVolume(AudioDataType *buffer, int len, bool music)
     628{
     629    float g = volume / 100.0;
     630
     631    // Should probably be logarithmic - this'll do
     632    g *= g;
     633   
     634    // Add gain to AC-3 - try to ~ match PCM volume
     635    if (audio_enc && audio_reenc)
     636        g *= 1.8;
     637
     638    // Music is relatively loud - ditto
     639    else if (music)
     640        g *= 0.4;
     641
     642    if (g == 1.0)
     643        return;
     644
     645    for (int i = 0; i < (int)(len / sizeof(AudioDataType)); i++)
     646    {
     647        float s = static_cast<float>(buffer[i]) * g /
     648                  static_cast<float>(numeric_limits<AudioDataType>::max());
     649        if (s >= 1.0)
     650            buffer[i] = numeric_limits<AudioDataType>::max();
     651        else if (s <= -1.0)
     652            buffer[i] = numeric_limits<AudioDataType>::min();
     653        else
     654            buffer[i] = static_cast<AudioDataType>
     655                        (s * numeric_limits<AudioDataType>::max());
     656    }
     657}
     658
     659void AudioOutputBase::AdjustVolume(void *buffer, int len, bool music) {
     660
     661    if (audio_bits == 8)
     662        _AdjustVolume<char>((char *)buffer, len, music);
     663    else if (audio_bits == 16)
     664        _AdjustVolume<short>((short *)buffer, len, music);
     665
     666}
     667
     668
    603669bool AudioOutputBase::AddSamples(char *buffers[], int samples,
    604670                                 long long timecode)
    605671{
    void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 
    9431009       
    9441010    }
    9451011
     1012    if (internal_vol && SWVolume())
     1013    {
     1014        int bdiff = kAudioRingBufferSize - waud;
     1015        bool music = (timecode < 1);
     1016
     1017        if (bdiff < len)
     1018        {
     1019            AdjustVolume(audiobuffer + waud, bdiff, music);
     1020            AdjustVolume(audiobuffer, len - bdiff, music);
     1021        }
     1022        else
     1023            AdjustVolume(audiobuffer + waud, len, music);
     1024    }
     1025
    9461026    // Encode to AC-3?
    9471027    if (encoder)
    9481028    {
  • mythtv/libs/libmyth/audiooutputbase.h

    diff --git a/mythtv/libs/libmyth/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h
    index 9a264a7..20f32ef 100644
    a b class AudioOutputBase : public AudioOutput, public QThread 
    4747
    4848    virtual void Reset(void);
    4949
     50    void SetSWVolume(int new_volume);
     51    int GetSWVolume(void);
     52
    5053    // timecode is in milliseconds.
    5154    virtual bool AddSamples(char *buffer, int samples, long long timecode);
    5255    virtual bool AddSamples(char *buffers[], int samples, long long timecode);
    class AudioOutputBase : public AudioOutput, public QThread 
    150153    int src_quality;
    151154
    152155 private:
     156    // software volume
     157    template <class AudioDataType>
     158    void _AdjustVolume(AudioDataType *buffer, int len, bool music);
     159    void AdjustVolume(void *buffer, int len, bool music);
     160   
    153161    // resampler
    154162    bool need_resampler;
    155163    SRC_STATE *src_ctx;
    class AudioOutputBase : public AudioOutput, public QThread 
    166174    int surround_mode;
    167175    bool allow_ac3_passthru;
    168176    float old_audio_stretchfactor;
     177    int volume;
    169178
    170179    bool blocking; // do AddSamples calls block?
    171180
  • mythtv/libs/libmyth/audiooutputoss.cpp

    diff --git a/mythtv/libs/libmyth/audiooutputoss.cpp b/mythtv/libs/libmyth/audiooutputoss.cpp
    index a18f147..348a60f 100644
    a b void AudioOutputOSS::VolumeInit() 
    287287    int volume = 0;
    288288
    289289    QString device = gContext->GetSetting("MixerDevice", "/dev/mixer");
     290    if (device.toLower() == "software")
     291        return;
    290292    QByteArray dev = device.toAscii();
    291293    mixerfd = open(dev.constData(), O_RDONLY);
    292294
  • mythtv/libs/libmyth/volumebase.cpp

    diff --git a/mythtv/libs/libmyth/volumebase.cpp b/mythtv/libs/libmyth/volumebase.cpp
    index d1f1fb0..be28940 100644
    a b VolumeBase::VolumeBase() : 
    1010    internal_vol(false), volume(80),
    1111    current_mute_state(kMuteOff)
    1212{
     13    swvol = swvol_setting =
     14      (gContext->GetSetting("MixerDevice", "default").toLower() == "software");
     15}
     16
     17bool VolumeBase::SWVolume(void)
     18{
     19    return swvol;
     20}
     21
     22void VolumeBase::SWVolume(bool set)
     23{
     24    if (swvol_setting)
     25        return;
     26    swvol = set;
    1327}
    1428
    1529uint VolumeBase::GetCurrentVolume(void) const
    void VolumeBase::UpdateVolume(void) 
    8094    {
    8195        new_volume = 0;
    8296    }
     97
     98    if (swvol)
     99    {
     100        SetSWVolume(new_volume);
     101        return;
     102    }
    83103   
    84104    // TODO: Avoid assumption that there are 2 channels!
    85105    for (int i = 0; i < 2; i++)
    void VolumeBase::UpdateVolume(void) 
    102122void VolumeBase::SyncVolume(void)
    103123{
    104124    // Read the volume from the audio driver and setup our internal state to match
    105     volume = GetVolumeChannel(0);
     125    if (swvol)
     126        volume = GetSWVolume();
     127    else
     128        volume = GetVolumeChannel(0);
    106129}
    107130
  • mythtv/libs/libmyth/volumebase.h

    diff --git a/mythtv/libs/libmyth/volumebase.h b/mythtv/libs/libmyth/volumebase.h
    index 4257f0b..8c658da 100644
    a b class MPUBLIC VolumeBase 
    2020    VolumeBase();   
    2121    virtual ~VolumeBase() {};
    2222
     23    void SWVolume(bool set);
     24    bool SWVolume(void);
    2325    virtual uint GetCurrentVolume(void) const;
    2426    virtual void SetCurrentVolume(int value);
    2527    virtual void AdjustCurrentVolume(int change);
    class MPUBLIC VolumeBase 
    3436
    3537    virtual int GetVolumeChannel(int channel) const = 0; // Returns 0-100
    3638    virtual void SetVolumeChannel(int channel, int volume) = 0; // range 0-100 for vol
     39    virtual void SetSWVolume(int new_volume) = 0;
     40    virtual int GetSWVolume(void) = 0;
    3741
    3842    void UpdateVolume(void);
    3943    void SyncVolume(void);
    class MPUBLIC VolumeBase 
    4448   
    4549    int volume;
    4650    MuteState current_mute_state;
     51    bool swvol;
     52    bool swvol_setting;
    4753
    4854};
    4955
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
    index 6145de8..721c851 100644
    a b AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 
    426426      // Audio
    427427      audioSamples(NULL),
    428428      allow_ac3_passthru(false),    allow_dts_passthru(false),
     429      internal_vol(false),
    429430      disable_passthru(false),      max_channels(2),
    430431      last_ac3_channels(0),         dummy_frame(NULL),
    431432      // DVD
    AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 
    447448
    448449    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    449450    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     451    internal_vol = gContext->GetNumSetting("MythControlsVolume", 0);
    450452    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
    451453
    452454    audioIn.sample_size = -32; // force SetupAudioStream to run once
    bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 
    41264128
    41274129    if (ctx->codec_id == CODEC_ID_AC3)
    41284130        passthru = allow_ac3_passthru &&
    4129                    ctx->channels >= (int)max_channels;
     4131                   ctx->channels >= (int)max_channels &&
     4132                   !internal_vol;
    41304133    else if (ctx->codec_id == CODEC_ID_DTS)
    41314134        passthru = allow_dts_passthru;
    41324135   
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
    index 57311b6..fb9cfe7 100644
    a b class AvFormatDecoder : public DecoderBase 
    269269    short int        *audioSamples;
    270270    bool              allow_ac3_passthru;
    271271    bool              allow_dts_passthru;
     272    bool              internal_vol;
    272273    bool              disable_passthru;
    273274    uint              max_channels;
    274275    uint              last_ac3_channels;
  • mythtv/programs/mythtranscode/transcode.cpp

    diff --git a/mythtv/programs/mythtranscode/transcode.cpp b/mythtv/programs/mythtranscode/transcode.cpp
    index 6721262..459d6a5 100644
    a b class AudioReencodeBuffer : public AudioOutput 
    226226        // Do nothing
    227227        return false;
    228228    }
     229    virtual void SetSWVolume(int new_volume)
     230    {
     231        // Do nothing
     232        return;
     233    }
     234   
     235    virtual int GetSWVolume(void)
     236    {
     237        // Do nothing
     238        return 100;
     239    }
    229240
    230241    //  These are pure virtual in AudioOutput, but we don't need them here
    231242    virtual void bufferOutputData(bool){ return; }