arkq / bluez-alsa

Bluetooth Audio ALSA Backend
MIT License
865 stars 189 forks source link

Feasibility to implement a command line parameter to disable volume control. #125

Closed badbat75 closed 3 years ago

badbat75 commented 6 years ago

When bluealsa-aplay is started volume of reproduction device go to 100%. There's no way to control it by remote device and volume control can't be disabled.

badbat75 commented 6 years ago

It is possible to implement a parameter in blue-alsa command line to disable volume control when used as a sink device?

arkq commented 6 years ago

What do you mean by "disable volume control"? Could you specify exact usecase?

Also, I'm not able to test it properly, because my smarphone does not communicate well with bluez and volume control works fine on the smartphone site (AVRCP volume command is not sent to PC). Anyway, AVRCP communication is beyond the scope of bluez-alsa.

Take a look at this fork: https://github.com/hmbedded/bluez-alsa

badbat75 commented 6 years ago

I'm sorry, I understand I was not so clear. The problem is that in the BT sink host, independently of how the master volume is set, when blualsa-aplay is started, the master volume of the default alsa device is set to 100%. So if I want to hear at soft volume a bluetooth streaming I have to reduce the bluetooth volume on the source device but the quality of reproduction is very bad because in every device I'm using the blootooth volume is a software volume. I supposed the behaviour in bluealsa is because the host can manage the volume parameter sent from client devices, but I really don't know. Is it a bug that volume go to 100% when bluealsa-aplay start, or is there a reason for this behaviour? If it is the right behaviour, is there a way to disable it keeping the volume at its own value without changing it when bluealsa-aplay is started?

joerg-krause commented 6 years ago

I have implemented a volume control based on @hmbedded 's fork: https://github.com/joerg-krause/bluez-alsa/tree/volume.

The volume is set at the beginning of a transport session to the current volume of the Mixer element passed via the --volume-control option, e.g. "Master":

bluealsa -p a2dp-sink --a2dp-volume &
bluealsa-aplay --profile-a2dp --volume-control Master 00:00:00:00:00:00

With volume control, if the transport volume is changed, e.g. on the iPhone, the ALSA mixers control volume is changed. If the volume is changed on the device, e.g. by hardware buttons or via amixer, the transport value is updated, too.

EDIT: fix bluealsa-aplay command line parameters

badbat75 commented 6 years ago

Hi Joerg, I tested the volume branch with parameter you suggested but:

In this way: /usr/bin/bluealsa -p a2dp-source -p a2dp-sink /usr/bin/bluealsa-aplay --pcm-buffer-time=20000 --profile-a2dp -d plughw:0,0 --volume-control Master 98:10:E8:XX:XX:XX The behaviour remain the same as the standard bluealsa branch

In this way: /usr/bin/bluealsa -p a2dp-source -p a2dp-sink --a2dp-volume /usr/bin/bluealsa-aplay --pcm-buffer-time=20000 --profile-a2dp -d plughw:0,0 --volume-control Master 98:10:E8:XX:XX:XX The hardware volume on sink device go to 100% as the previous way: Simple mixer control 'Master',0 Capabilities: volume volume-joined Playback channels: Mono Capture channels: Mono Limits: 0 - 248 Mono: 248 [100%] Simple mixer control 'Channels',0 Capabilities: volume Playback channels: Front Left - Front Right Capture channels: Front Left - Front Right Limits: 0 - 248 Front Left: 218 [88%] Front Right: 218 [88%] but software volume control on my iPhone stopped completely to work. Go from mute at mute step to 100% at first step of volume until to last step.

joerg-krause commented 6 years ago

@badbat75

bluealsa needs to be run with the --a2dp-volume command line parameter, otherwise the volume scale is calculated by bluealsa.

So your Master device is at 100% in your log. Was it at 100% before you started bluealsa-aplay? Furthermore, it is mono. Maybe this isn't handled correctly.

Is your Channels mixer usable? If so, could you try to start bluealsa-play with --volume-control Channels?

badbat75 commented 6 years ago

Ok I tried also this setup: /usr/bin/bluealsa -p a2dp-source -p a2dp-sink --a2dp-volume /usr/bin/bluealsa-aplay --pcm-buffer-time=20000 --profile-a2dp -d plughw:0,0 --volume-control Channels 98:10:E8:XX:XX:XX

Always Master to 100% (with bluealsa-aplay shut down Master was is 57%), no changes on Channels channel when I change volume on my Iphone And the issue remains as I stated in my previous post, 2nd case.

joerg-krause commented 6 years ago

I will create a separate branch with includes more debug messages in the next days. Maybe we can find why it is not working for you.

joerg-krause commented 6 years ago

@badbat75 I've reworked the volume handling. Feel free to test it using the separate volume2 branch of my fork: https://github.com/joerg-krause/bluez-alsa/tree/volume2

badbat75 commented 6 years ago

Hi @joerg-krause , thank you for your effort but unfortunately but the situation is the same as my previous post... I've just tested your code, is there something I can do to debug this problem?

joerg-krause commented 5 years ago

I've reworked the volume control again.

If anybody is interested in testing please try: https://github.com/joerg-krause/bluez-alsa/tree/volume. Note, that the branch is not rebased on Arkqs master branch, yet.

badbat75 commented 5 years ago

Sadly I have to say that behaviour didn't change. Hardware volume 100% and no control on it. Thank you anyway :-)

joerg-krause commented 5 years ago

@badbat75 Can you please provide your alsa.conf and how you start bluealsa and bluealsa-aplay?

badbat75 commented 5 years ago

Those are my commands:

/usr/bin/bluealsa -p a2dp-source -p a2dp-sink --a2dp-volume
/usr/bin/bluealsa-aplay --pcm-buffer-time=20000 --profile-a2dp -d plughw:0,0 --volume-control Master 98:10:E8:XX:XX:XX

And those alsa.conf and all conf.d

#

#  ALSA library configuration file
#

# pre-load the configuration files

@hooks [
        {
                func load
                files [
                        {
                                @func concat
                                strings [
                                        { @func datadir }
                                        "/alsa.conf.d/"
                                ]
                        }
                        "/etc/asound.conf"
                        "~/.asoundrc"
                ]
                errors false
        }
]

# load card-specific configuration files (on request)

cards.@hooks [
        {
                func load
                files [
                        {
                                @func concat
                                strings [
                                        { @func datadir }
                                        "/cards/aliases.conf"
                                ]
                        }
                ]
        }
        {
                func load_for_all_cards
                files [
                        {
                                @func concat
                                strings [
                                        { @func datadir }
                                        "/cards/"
                                        { @func private_string }
                                        ".conf"
                                ]
                        }
                ]
                errors false
        }
]

#
# defaults
#

# show all name hints also for definitions without hint {} section
defaults.namehint.showall on
# show just basic name hints
defaults.namehint.basic on
# show extended name hints
defaults.namehint.extended on
#
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
defaults.pcm.compat 0
defaults.pcm.minperiodtime 5000         # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0660
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.rate 48000
defaults.pcm.dmix.format "unchanged"
defaults.pcm.dmix.card defaults.pcm.card
defaults.pcm.dmix.device defaults.pcm.device
defaults.pcm.dsnoop.card defaults.pcm.card
defaults.pcm.dsnoop.device defaults.pcm.device
defaults.pcm.front.card defaults.pcm.card
defaults.pcm.front.device defaults.pcm.device
defaults.pcm.rear.card defaults.pcm.card
defaults.pcm.rear.device defaults.pcm.device
defaults.pcm.center_lfe.card defaults.pcm.card
defaults.pcm.center_lfe.device defaults.pcm.device
defaults.pcm.side.card defaults.pcm.card
defaults.pcm.side.device defaults.pcm.device
defaults.pcm.surround21.card defaults.pcm.card
defaults.pcm.surround21.device defaults.pcm.device
defaults.pcm.surround40.card defaults.pcm.card
defaults.pcm.surround40.device defaults.pcm.device
defaults.pcm.surround41.card defaults.pcm.card
defaults.pcm.surround41.device defaults.pcm.device
defaults.pcm.surround50.card defaults.pcm.card
defaults.pcm.surround50.device defaults.pcm.device
defaults.pcm.surround51.card defaults.pcm.card
defaults.pcm.surround51.device defaults.pcm.device
defaults.pcm.surround71.card defaults.pcm.card
defaults.pcm.surround71.device defaults.pcm.device
defaults.pcm.iec958.card defaults.pcm.card
defaults.pcm.iec958.device defaults.pcm.device
defaults.pcm.modem.card defaults.pcm.card
defaults.pcm.modem.device defaults.pcm.device
# truncate files via file or tee PCM
defaults.pcm.file_format        "raw"
defaults.pcm.file_truncate      true
defaults.rawmidi.card 0
defaults.rawmidi.device 0
defaults.rawmidi.subdevice -1
defaults.hwdep.card 0
defaults.hwdep.device 0
defaults.timer.class 2
defaults.timer.sclass 0
defaults.timer.card 0
defaults.timer.device 0
defaults.timer.subdevice 0

#
#  PCM interface
#

# redirect to load-on-demand extended pcm definitions
pcm.cards cards.pcm

pcm.default cards.pcm.default
pcm.sysdefault cards.pcm.default
pcm.front cards.pcm.front
pcm.rear cards.pcm.rear
pcm.center_lfe cards.pcm.center_lfe
pcm.side cards.pcm.side
pcm.surround21 cards.pcm.surround21
pcm.surround40 cards.pcm.surround40
pcm.surround41 cards.pcm.surround41
pcm.surround50 cards.pcm.surround50
pcm.surround51 cards.pcm.surround51
pcm.surround71 cards.pcm.surround71
pcm.iec958 cards.pcm.iec958
pcm.spdif iec958
pcm.hdmi cards.pcm.hdmi
pcm.dmix cards.pcm.dmix
pcm.dsnoop cards.pcm.dsnoop
pcm.modem cards.pcm.modem
pcm.phoneline cards.pcm.phoneline

pcm.hw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_PCM_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.pcm.card
                        }
                }
        }
        @args.DEV {
                type integer
                default {
                        @func igetenv
                        vars [
                                ALSA_PCM_DEVICE
                        ]
                        default {
                                @func refer
                                name defaults.pcm.device
                        }
                }
        }
        @args.SUBDEV {
                type integer
                default {
                        @func refer
                        name defaults.pcm.subdevice
                }
        }
        type hw
        card $CARD
        device $DEV
        subdevice $SUBDEV
        hint {
                show {
                        @func refer
                        name defaults.namehint.extended
                }
                description "Direct hardware device without any conversions"
        }
}

pcm.plughw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_PCM_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.pcm.card
                        }
                }
        }
        @args.DEV {
                type integer
                default {
                        @func igetenv
                        vars [
                                ALSA_PCM_DEVICE
                        ]
                        default {
                                @func refer
                                name defaults.pcm.device
                        }
                }
        }
        @args.SUBDEV {
                type integer
                default {
                        @func refer
                        name defaults.pcm.subdevice
                }
        }
        type plug
        slave.pcm {
                type hw
                card $CARD
                device $DEV
                subdevice $SUBDEV
        }
        hint {
                show {
                        @func refer
                        name defaults.namehint.extended
                }
                description "Hardware device with all software conversions"
        }
}

pcm.plug {
        @args [ SLAVE ]
        @args.SLAVE {
                type string
        }
        type plug
        slave.pcm $SLAVE
}

pcm.shm {
        @args [ SOCKET PCM ]
        @args.SOCKET {
                type string
        }
        @args.PCM {
                type string
        }
        type shm
        server $SOCKET
        pcm $PCM
}

pcm.tee {
        @args [ SLAVE FILE FORMAT ]
        @args.SLAVE {
                type string
        }
        @args.FILE {
                type string
        }
        @args.FORMAT {
                type string
                default {
                        @func refer
                        name defaults.pcm.file_format
                }
        }
        type file
        slave.pcm $SLAVE
        file $FILE
        format $FORMAT
        truncate {
                @func refer
                name defaults.pcm.file_truncate
        }
}

pcm.file {
        @args [ FILE FORMAT ]
        @args.FILE {
                type string
        }
        @args.FORMAT {
                type string
                default {
                        @func refer
                        name defaults.pcm.file_format
                }
        }
        type file
        slave.pcm null
        file $FILE
        format $FORMAT
        truncate {
                @func refer
                name defaults.pcm.file_truncate
        }
}

pcm.null {
        type null
        hint {
                show {
                        @func refer
                        name defaults.namehint.basic
                }
                description "Discard all samples (playback) or generate zero samples (capture)"
        }
}

#
#  Control interface
#

ctl.sysdefault {
        type hw
        card {
                @func getenv
                vars [
                        ALSA_CTL_CARD
                        ALSA_CARD
                ]
                default {
                        @func refer
                        name defaults.ctl.card
                }
        }
        hint.description "Default control device"
}
ctl.default ctl.sysdefault

ctl.hw {
        @args [ CARD ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_CTL_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.ctl.card
                        }
                }
        }
        type hw
        card $CARD
        hint.description "Direct control device"
}

ctl.shm {
        @args [ SOCKET CTL ]
        @args.SOCKET {
                type string
        }
        @args.CTL {
                type string
        }
        type shm
        server $SOCKET
        ctl $CTL
}

#
#  RawMidi interface
#

rawmidi.default {
        type hw
        card {
                @func getenv
                vars [
                        ALSA_RAWMIDI_CARD
                        ALSA_CARD
                ]
                default {
                        @func refer
                        name defaults.rawmidi.card
                }
        }
        device {
                @func igetenv
                vars [
                        ALSA_RAWMIDI_DEVICE
                ]
                default {
                        @func refer
                        name defaults.rawmidi.device
                }
        }
        hint.description "Default raw MIDI device"
}

rawmidi.hw {
        @args [ CARD DEV SUBDEV ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_RAWMIDI_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.rawmidi.card
                        }
                }
        }
        @args.DEV {
                type integer
                default {
                        @func igetenv
                        vars [
                                ALSA_RAWMIDI_DEVICE
                        ]
                        default {
                                @func refer
                                name defaults.rawmidi.device
                        }
                }
        }
        @args.SUBDEV {
                type integer
                default -1
        }
        type hw
        card $CARD
        device $DEV
        subdevice $SUBDEV
        hint {
                description "Direct rawmidi driver device"
                device $DEV
        }
}

rawmidi.virtual {
        @args [ MERGE ]
        @args.MERGE {
                type string
                default 1
        }
        type virtual
        merge $MERGE
}

#
#  Sequencer interface
#

seq.default {
        type hw
        hint.description "Default sequencer device"
}

seq.hw {
        type hw
}

#
#  HwDep interface
#

hwdep.default {
        type hw
        card {
                @func getenv
                vars [
                        ALSA_HWDEP_CARD
                        ALSA_CARD
                ]
                default {
                        @func refer
                        name defaults.hwdep.card
                }
        }
        device {
                @func igetenv
                vars [
                        ALSA_HWDEP_DEVICE
                ]
                default {
                        @func refer
                        name defaults.hwdep.device
                }
        }
        hint.description "Default hardware dependent device"
}

hwdep.hw {
        @args [ CARD DEV ]
        @args.CARD {
                type string
                default {
                        @func getenv
                        vars [
                                ALSA_HWDEP_CARD
                                ALSA_CARD
                        ]
                        default {
                                @func refer
                                name defaults.hwdep.card
                        }
                }
        }
        @args.DEV {
                type integer
                default {
                        @func igetenv
                        vars [
                                ALSA_HWDEP_DEVICE
                        ]
                        default {
                                @func refer
                                name defaults.hwdep.device
                        }
                }
        }
        type hw
        card $CARD
        device $DEV
        hint {
                description "Direct hardware dependent device"
                device $DEV
        }
}

#
#  Timer interface
#

timer_query.default {
        type hw
}

timer_query.hw {
        type hw
}

timer.default {
        type hw
        class {
                @func refer
                name defaults.timer.class
        }
        sclass {
                @func refer
                name defaults.timer.sclass
        }
        card {
                @func refer
                name defaults.timer.card
        }
        device {
                @func refer
                name defaults.timer.device
        }
        subdevice {
                @func refer
                name defaults.timer.subdevice
        }
        hint.description "Default timer device"
}

timer.hw {
        @args [ CLASS SCLASS CARD DEV SUBDEV ]
        @args.CLASS {
                type integer
                default {
                        @func refer
                        name defaults.timer.class
                }
        }
        @args.SCLASS {
                type integer
                default {
                        @func refer
                        name defaults.timer.sclass
                }
        }
        @args.CARD {
                type string
                default {
                        @func refer
                        name defaults.timer.card
                }
        }
        @args.DEV {
                type integer
                default {
                        @func refer
                        name defaults.timer.device
                }
        }
        @args.SUBDEV {
                type integer
                default {
                        @func refer
                        name defaults.timer.subdevice
                }
        }
        type hw
        class $CLASS
        sclass $SCLASS
        card $CARD
        device $DEV
        subdevice $SUBDEV
        hint {
                description "Direct timer device"
                device $DEV
        }
}
# BlueALSA integration setup

defaults.bluealsa.interface "hci0"
defaults.bluealsa.profile "a2dp"
defaults.bluealsa.delay 20000
defaults.bluealsa.battery "yes"

ctl.bluealsa {
        @args [ HCI BAT ]
        @args.HCI {
                type string
                default {
                        @func refer
                        name defaults.bluealsa.interface
                }
        }
        @args.BAT {
                type string
                default {
                        @func refer
                        name defaults.bluealsa.battery
                }
        }
        type bluealsa
        interface $HCI
        battery $BAT
}

pcm.bluealsa {
        @args [ HCI DEV PROFILE DELAY ]
        @args.HCI {
                type string
                default {
                        @func refer
                        name defaults.bluealsa.interface
                }
        }
        @args.DEV {
                type string
                default {
                        @func refer
                        name defaults.bluealsa.device
                }
        }
        @args.PROFILE {
                type string
                default {
                        @func refer
                        name defaults.bluealsa.profile
                }
        }
        @args.DELAY {
                type integer
                default {
                        @func refer
                        name defaults.bluealsa.delay
                }
        }
        type plug
        slave.pcm {
                type bluealsa
                interface $HCI
                device $DEV
                profile $PROFILE
                delay $DELAY
        }
        hint {
                show {
                        @func refer
                        name defaults.namehint.extended
                }
                description "Bluetooth Audio Hub"
        }
}
#
# 2018-01-26 TC moOde 4.0
#

pcm.btaplay_dmix {
    type plug
    slave.pcm "plug_btaplay_dmix"
}

pcm.plug_btaplay_dmix {
    type dmix
    ipc_key 321456
    slave {
        pcm {
            type hw
            card 0
            device 0
        }
        format "S16_LE"
        rate 44100
    }
}
#
# 2018-01-26 TC moOde 4.0
#

pcm.alsaequal {
    type plug
    slave.pcm "plug_alsaequal";
}

ctl.alsaequal {
    type equal
    controls "/usr/local/bin/alsaequal.bin";
}

pcm.plug_alsaequal {
    type equal
        slave.pcm "plughw:0,0";
    controls "/usr/local/bin/alsaequal.bin";
}
#
# 2018-01-26 TC moOde 4.0
#

pcm.btstream {
        type plug
        slave.pcm {
                type bluealsa
                device "XX:XX:XX:XX:XX:XX"
                profile "a2dp"
        }
}
# 2018-01-26 TC moOde 4.0
#
# crossfeed
# - lowpass filter cut frequency (Hz): 300 to 2000, default 725
# - feeding level (dB): 1 to 15, default 4.5
#

pcm.crossfeed {
    type plug
    slave.pcm "plug_bs2b";
}

pcm.plug_bs2b {
    type ladspa
        slave.pcm "plughw:0,0";
    path "/usr/lib/ladspa";
    plugins [ {
        label bs2b
        input {
                        controls [ 700 4.5 ]
        }
    } ]
}
#
# 2018-01-26 TC moOde 4.0
#

#
# Four Mitra-Regalia peaking equaliser filters in series; a vector arithmetic
# re-implementation of Fons Adriaensens "Parametric1" equaliser[fafil] with
# minor differences. Parallelisation of the serial filter organisation causes
# the output to lag by three samples. The bandwidth control sets the bandwidth
# of a single filter, lower values corresponding to increasing resonance (Q).
#
# Second order filters are capable of resonance (or anti-resonance) around a
# particular frequency. The response of a second order filter is specified not
# only by its frequency but its Q; a higher Q corresponds to a sharper response
# (narrower bandwidth) around a particular center frequency.
#
# There are four sets of four numbers (Enable/Disable, Frequency, Bandwidth, Gain). The final number is overall gain.
# - Enable/disable:     1/0
# - Frequency:          20 - 14000 Hz (Center Frequency)
# - Bandwidth:          0.12 - 8 (Q factor) must have leading 0 if < 1
# - Gain:                       -24 - 24 dB
# - Master Gain         -24 - 24 dB
#

pcm.eqfa4p {
    type plug
    slave.pcm "plug_eqfa4p"
}

pcm.plug_eqfa4p {
    type ladspa
        slave.pcm "plughw:0,0";
    path "/usr/lib/ladspa";
    plugins [ {
                id 2609
                label EqFA4p
                input {
                        controls [ 1 20 1 0  1 180 1 0  1 2000 1 0  1 11700 1 0  0 ]
                }
    } ]
}
gearhead commented 5 years ago

@badbat75 What audio card are you using? I have a couple PCM5012s which require software volume control and a number of PCM5122s which have hardware volume control. The 5102, I believe, is always 100% and needs to be adjusted by the amplitude of the PCM signal. The 5122, though has a hardware volume control

The 5122 shows up like this:

# amixer
Simple mixer control 'DSP Program',0
  Capabilities: enum
  Items: 'FIR interpolation with de-emphasis' 'Low latency IIR with de-emphasis' 'High attenuation with de-emphasis' 'Fixed process flow' 'Ringing-less low latency FIR'
  Item0: 'Ringing-less low latency FIR'
Simple mixer control 'Analogue',0
  Capabilities: pvolume
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 1
  Mono:
  Front Left: Playback 1 [100%] [0.00dB]
  Front Right: Playback 1 [100%] [0.00dB]
Simple mixer control 'Analogue Playback Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 1
  Front Left: 1 [100%] [0.80dB]
  Front Right: 1 [100%] [0.80dB]
Simple mixer control 'Auto Mute',0
  Capabilities: pswitch
  Playback channels: Front Left - Front Right
  Mono:
  Front Left: Playback [on]
  Front Right: Playback [on]
Simple mixer control 'Auto Mute Mono',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'Auto Mute Time Left',0
  Capabilities: enum
  Items: '21ms' '106ms' '213ms' '533ms' '1.07s' '2.13s' '5.33s' '10.66s'
  Item0: '21ms'
Simple mixer control 'Auto Mute Time Right',0
  Capabilities: enum
  Items: '21ms' '106ms' '213ms' '533ms' '1.07s' '2.13s' '5.33s' '10.66s'
  Item0: '21ms'
Simple mixer control 'Clock Missing Period',0
  Capabilities: enum
  Items: '1s' '2s' '3s' '4s' '5s' '6s' '7s' '8s'
  Item0: '1s'
Simple mixer control 'Deemphasis',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'Digital',0
  Capabilities: pvolume pswitch
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 207
  Mono:
  Front Left: Playback 122 [59%] [-42.50dB] [on]
  Front Right: Playback 122 [59%] [-42.50dB] [on]
Simple mixer control 'Max Overclock DAC',0
  Capabilities: volume volume-joined
  Playback channels: Mono
  Capture channels: Mono
  Limits: 0 - 40
  Mono: 0 [0%]
Simple mixer control 'Max Overclock DSP',0
  Capabilities: volume volume-joined
  Playback channels: Mono
  Capture channels: Mono
  Limits: 0 - 40
  Mono: 0 [0%]
Simple mixer control 'Max Overclock PLL',0
  Capabilities: volume volume-joined
  Playback channels: Mono
  Capture channels: Mono
  Limits: 0 - 20
  Mono: 0 [0%]
Simple mixer control 'Volume Ramp Down Emergency Rate',0
  Capabilities: enum
  Items: '1 sample/update' '2 samples/update' '4 samples/update' 'Immediate'
  Item0: '1 sample/update'
Simple mixer control 'Volume Ramp Down Emergency Step',0
  Capabilities: enum
  Items: '4dB/step' '2dB/step' '1dB/step' '0.5dB/step'
  Item0: '4dB/step'
Simple mixer control 'Volume Ramp Down Rate',0
  Capabilities: enum
  Items: '1 sample/update' '2 samples/update' '4 samples/update' 'Immediate'
  Item0: '1 sample/update'
Simple mixer control 'Volume Ramp Down Step',0
  Capabilities: enum
  Items: '4dB/step' '2dB/step' '1dB/step' '0.5dB/step'
  Item0: '1dB/step'
Simple mixer control 'Volume Ramp Up Rate',0
  Capabilities: enum
  Items: '1 sample/update' '2 samples/update' '4 samples/update' 'Immediate'
  Item0: '1 sample/update'
Simple mixer control 'Volume Ramp Up Step',0
  Capabilities: enum
  Items: '4dB/step' '2dB/step' '1dB/step' '0.5dB/step'
  Item0: '1dB/step'

The 5102 shows no mixer capability. No listing on alsamixer or amixer and will require the phone to modulate volume. I want to have the phone volume control to directly control the mixer volume control on my i2s chip. Will this allow this? I do not know how this would work... This is how shairport-sync and upmpdcli interacts with the i2s cards.

joerg-krause commented 5 years ago

I am using the TI PCM5102 as well. I can control the volume using the ALSA softvol plugin. Amixer is showing this:

# amixer 
Simple mixer control 'Master',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 255
  Front Left: 128 [50%]
  Front Right: 128 [50%]
joerg-krause commented 5 years ago

@badbat75 I do not see any ALSA mixer control configuration in your configuration. What is the output of cat /etc/asound.conf?

gearhead commented 5 years ago
# cat /etc/asound.conf
cat: /etc/asound.conf: No such file or directory

Don't have an asound.conf. Never had one or needed one. I run mpd/upmpdcli and shairport-sync on these pis and have no problem controlling the volume as long as it is set properly.

With the PCM5102, (in Shairport-sync) the access to the alsa device requires: output_device="hw:0";

With the PCM5122, (alsin in Shairport-sync): output_device="hw:0"; // alsa_output_device mixer_control_name="Digital"; // alsa_mixer_control_name mixer_device="hw:0";

I'm not that knowledgeable about how this all works, but this is what I have learned, that I need to specify the mixer device to get the volume to work correctly with the 5122 and the 5102 requires that I comment out all references to the mixer to get it to work.

badbat75 commented 5 years ago

@badbat75 I do not see any ALSA mixer control configuration in your configuration. What is the output of cat /etc/asound.conf?

Joerg I replied in the 3rd April post.

joerg-krause commented 5 years ago

@badbat75 Sorry for not replying earlier...

From what I can see I guess you are using Moode Audio. What DAC does your system has? What is the output of alsamixer and aplay -L?

tuomashamalainen commented 4 years ago

@joerg-krause I happened across this issue and your fork when searching for a solution to this very problem. How much would it take to merge new bluez-alsa changes to your fork? I'm pretty interested in testing this.

joerg-krause commented 4 years ago

Hi @tuomashamalainen , thanks for your interest! I rebase my branch from time to time. My latested private branch is somewhere between v2.1.0 and master. I will publish it soon.

joerg-krause commented 4 years ago

This is my volume branch based on v2.1.0 including some follow up fixes: https://github.com/joerg-krause/bluez-alsa/tree/volume-v2.1.0.

tuomashamalainen commented 4 years ago

Thanks Jörg, will give this a go with a Beocreate 4-Channel Amplifier.

tuomashamalainen commented 4 years ago

@joerg-krause, testing this just now and the volume sync works great, both ways. Thanks again. We would love to include this in HiFiBerryOS/Beocreate 2 if you've got no objections.

joerg-krause commented 4 years ago

I'm glad it works! This encourages me to make a pull request :smile: I have no objections, you are welcome to add it to HiFiBerryOS.

joerg-krause commented 4 years ago

@tuomashamalainen I rebased the commits to latest upstream master. Mind to test the branch https://github.com/joerg-krause/bluez-alsa/tree/alsa-volume-control, so I can prepare a PR? Thanks!

Note, that the ALSA PCM device parameter has changed in bluez-alsa from -d to -D.

hifiberry commented 4 years ago

@joerg-krause Latest commit on this branch is from September last year. Is this correct?

joerg-krause commented 4 years ago

Yes, it is the date of when the commit was created. I rebased the commits on top of master.

paul-1 commented 4 years ago

I was using my own rebased version, but I built yours, and it appears to be working fine.

hifiberry commented 4 years ago

@joerg-krause Yes, seems to work here.

gearhead commented 4 years ago

@Arkq Can you implement this in the current git?

joerg-krause commented 4 years ago

Thanks @paul-1 , @hifiberry for testing. @gearhead I'm preparing a PR soon, so @Arkq can review the code.

joerg-krause commented 4 years ago

I've rebased the branch again on latest master branch and changed the command line option to -M or --mixer=NAME.

arkq commented 3 years ago

With bluez >= 5.55, there is a fix for reporting volume for headsets, and in the current master of bluez-alsa, there is a fix for correct volume scaling (gauge on smartphone, e.g. iPhone, and volume on host with bluez-alsa should match). Please, check whether right now the volume control is as expected.

As for the issue request for disabling volume scaling. There is a possibility to disable software volume scaling with D-Bus call. The SoftVolume property of the PCM endpoint: https://github.com/Arkq/bluez-alsa/blob/a255e2483319b2eca7d50bd94a2e63dec3f28b9c/doc/bluealsa-api.txt#L110-L115

Because the requested feature has been implemented, I'm closing this issue.

Discussion for volume forwarding between ALSA mixer and Bluetooth device, please continue in the PR #321 or #390.