diff options
-rw-r--r-- | conf.d/cmake/00-opensuse-osconfig.cmake | 2 | ||||
-rw-r--r-- | conf.d/project/etc/smixer-test-config.json (renamed from conf.d/project/etc/smixer-4a-test-config.json) | 6 | ||||
-rw-r--r-- | conf.d/project/htdocs/index.html | 136 | ||||
-rw-r--r-- | conf.d/project/lua.d/smixer-test-simple.lua (renamed from conf.d/project/lua.d/softmixer-simple-test.lua) | 8 | ||||
-rw-r--r-- | nbproject/configurations.xml | 350 | ||||
-rw-r--r-- | plugins/alsa/alsa-api-mixer.c | 126 | ||||
-rw-r--r-- | plugins/alsa/alsa-api-pcm.c | 241 | ||||
-rw-r--r-- | plugins/alsa/alsa-api-streams.c | 47 | ||||
-rw-r--r-- | plugins/alsa/alsa-core-pcm.c | 4 | ||||
-rw-r--r-- | plugins/alsa/alsa-effect-ramp.c | 2 | ||||
-rw-r--r-- | plugins/alsa/alsa-plug-vol.c | 2 |
11 files changed, 684 insertions, 240 deletions
diff --git a/conf.d/cmake/00-opensuse-osconfig.cmake b/conf.d/cmake/00-opensuse-osconfig.cmake index 3da2b4b..b750ece 100644 --- a/conf.d/cmake/00-opensuse-osconfig.cmake +++ b/conf.d/cmake/00-opensuse-osconfig.cmake @@ -1,4 +1,4 @@ message(STATUS "*** Notice: OpenSuSe LUA-5.3+DynApi") list(APPEND PKG_REQUIRED_LIST lua>=5.3) -set(USE_EFENCE 1) +set(USE_EFENCE 0) diff --git a/conf.d/project/etc/smixer-4a-test-config.json b/conf.d/project/etc/smixer-test-config.json index 6caf228..3ed9f29 100644 --- a/conf.d/project/etc/smixer-4a-test-config.json +++ b/conf.d/project/etc/smixer-test-config.json @@ -3,15 +3,15 @@ "metadata": { "uid": "Soft Mixer", "version": "1.0", - "api": "softmixer", + "api": "smixer", "info": "Soft Mixer emulating hardware mixer" }, "resources": [ { "uid": "softmixer", "info": "Map alsa-loop subdevices to 4A HAL streams", - "spath": "./lib/plugins:./var", - "libs": ["alsa-softmixer.ctlso", "softmixer-simple-test.lua"], + "spath": "./package/lib/plugins:./package/var:./lib/plugins:./var", + "libs": ["alsa-softmixer.ctlso", "smixer-test-simple.lua"], "lua": { "prefix": "smix", "functions": ["_mixer_new_"] diff --git a/conf.d/project/htdocs/index.html b/conf.d/project/htdocs/index.html index 5709eb2..59fbbac 100644 --- a/conf.d/project/htdocs/index.html +++ b/conf.d/project/htdocs/index.html @@ -5,125 +5,11 @@ <script type="text/javascript" src="AFB-websock.js"></script> <script type="text/javascript" src="AudioBinding.js"></script> <script type="text/javascript"> - - var frontend = { - "devices": { - "playback": 0, - "capture": 1 - }, - "ramps": [ - { - "uid": "ramp-fast", - "delay": 50, - "up": 10, - "down": 3 - }, - { - "uid": "ramp-slow", - "delay": 250, - "up": 3, - "down": 1 - }, - { - "uid": "ramp-normal", - "delay": 100, - "up": 6, - "down": 2 - } - ], - "subdevs": [ - { - "subdev": 0, - "numid": 51 - }, - { - "subdev": 1, - "numid": 57 - }, - { - "subdev": 2, - "numid": 63 - }, - { - "subdev": 3, - "numid": 69 - }, - { - "subdev": 4, - "numid": 75 - }, - { - "subdev": 5, - "numid": 81 - }, - { - "subdev": 6, - "numid": 87 - }, - { - "subdev": 7, - "numid": 93 - } - ] - }; - var audio_defaults = { - "rate": 48000 - }; - var usb_yamaha = { - uid: "YAMAHA-APU70", - devpath: "/dev/snd/by-id/usb-YAMAHA_Corporation_YAMAHA_AP-U70_USB_Audio_00-00", - params: snd_params, - sink: [ - {uid: "front-right", port: 0}, - {uid: "front-left", port: 1} - ] - }; - var zone_front = { - uid: "front-seats", - type: "playback", - mapping: [ - {target: "front-right", channel: 0}, - {target: "front-left", channel: 1} - ] - }; - - var stream_music = { - uid: "multimedia", - zone: "front-seats", - ramp: "ramp-slow", - volume: 60, - mute: false - }; - - var stream_navigation = { - uid: "navigation", - zone: "front-seats", - ramp: "ramp-normal", - volume: 70, - mute: false - }; - - var stream_emergency = { - uid: "emergency", - zone: "front-seats", - ramp: "ramp-fast", - volume: 80, - mute: false - }; - - var my_test_mixer = { - uid: 'simple_mixer', - backend: usb_yamaha, - frontend: frontend, - zones: zone_front, - streams: [stream_music, stream_navigation, stream_emergency] - }; - </script> </head> - <body onload="init('hal_registry', 'alsacore', 'hallist')"> + <body onload="init()"> <h1>Simple Mixer Test</h1> <button id="connected" onclick="init()">Binder WS Fail</button> @@ -132,20 +18,18 @@ <h2>V3 API CALL</h2> <ol> - <li><button onclick="callbinder('softmixer', 'simple_mixer', {list: {streams: true}});">Streams List</button></li> - <br> - <li><button onclick="callbinder('softmixer', 'simple_mixer/multimedia', {toggle: true});">Stream Multimedia pause/resume</button></li> - <li><button onclick="callbinder('softmixer', 'simple_mixer/navigation', {toggle: true});">Stream Navigation pause/resume</button></li> + <li><button onclick="callbinder('MyMixer', 'info', {streams: true});">Streams List</button></li> + <li><button onclick="callbinder('MyMixer', 'info', {ramps: true});">Ramps List</button></li> + <li><button onclick="callbinder('MyMixer', 'info', {zones: true});">Zones List</button></li> <br> - <li><button onclick="callbinder('softmixer', 'simple_mixer/multimedia', {volume: '+10'});">Stream Multimedia volume=+10"</button></li> - <li><button onclick="callbinder('softmixer', 'simple_mixer/multimedia', {volume: '-10'});">Stream Multimedia volume=-10"</button></li> + <li><button onclick="callbinder('MyMixer', 'multimedia', {toggle: true});">Stream Multimedia pause/resume</button></li> + <li><button onclick="callbinder('MyMixer', 'navigation', {toggle: true});">Stream Navigation pause/resume</button></li> <br> - <li><button onclick="callbinder('softmixer', 'simple_mixer/multimedia', {ramp: 30});">Stream Multimedia ramp=30"</button></li> - <li><button onclick="callbinder('softmixer', 'simple_mixer/multimedia', {ramp: 80});">Stream Multimedia ramp=80"</button></li> + <li><button onclick="callbinder('MyMixer', 'multimedia', {volume: '+10'});">Stream Multimedia volume=+10"</button></li> + <li><button onclick="callbinder('MyMixer', 'multimedia', {volume: '-10'});">Stream Multimedia volume=-10"</button></li> <br> - <li><button onclick="callbinder('softmixer', 'simple_mixer', {delete: true});">Close Mixer"</button></li> - <li><button onclick="callbinder('softmixer', 'create',{uid:'simple_mixer', backend: usb_yamaha, frontend: frontend, - zones: [zone_front],streams: [stream_music, stream_navigation, stream_emergency]});">New Mixer"</button></li> + <li><button onclick="callbinder('MyMixer', 'multimedia', {ramp: {uid:'ramp-slow', volume:30}});">Stream Multimedia ramp-slow=30"</button></li> + <li><button onclick="callbinder('MyMixer', 'multimedia', {ramp: {uid:'ramp-fast', volume:80}});">Stream Multimedia ramp-fast=80"</button></li> </ol> <div id="main" style="visibility:hidden"> diff --git a/conf.d/project/lua.d/softmixer-simple-test.lua b/conf.d/project/lua.d/smixer-test-simple.lua index 87fb866..3a5dc98 100644 --- a/conf.d/project/lua.d/softmixer-simple-test.lua +++ b/conf.d/project/lua.d/smixer-test-simple.lua @@ -171,7 +171,7 @@ function _mixer_simple_test_ (source, args) ["uid"] = "multimedia", ["zone"]= "full-stereo", ["source"]= "loop-multimedia", - ["volume"]= 60, + ["volume"]= 80, ["mute"] = false, ["params"]= audio_params.standard, } @@ -179,7 +179,7 @@ function _mixer_simple_test_ (source, args) local stream_navigation= { ["uid"] = "navigation", ["zone"]= "front-seats", - ["volume"]= 60, + ["volume"]= 80, ["mute"] = false, } @@ -195,7 +195,7 @@ function _mixer_simple_test_ (source, args) ["uid"] = "radio", ["zone"] = "full-stereo", --["source"]= snd_usb_8ch.uid, - ["volume"]= 60, + ["volume"]= 80, ["mute"] = false, } @@ -203,7 +203,7 @@ function _mixer_simple_test_ (source, args) ["uid"] = "pulseaudio", ["zone"] = "back-seats", ["source"]= "loop-legacy", - ["volume"]= 60, + ["volume"]= 80, ["mute"] = false, } diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 187c42f..7acd6c9 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -27,6 +27,7 @@ <df name="plugins"> <df name="alsa"> <in>alsa-api-loop.c</in> + <in>alsa-api-mixer.c</in> <in>alsa-api-pcm.c</in> <in>alsa-api-ramp.c</in> <in>alsa-api-sink.c</in> @@ -36,6 +37,7 @@ <in>alsa-capture.c</in> <in>alsa-core-ctl.c</in> <in>alsa-core-pcm.c</in> + <in>alsa-effect-ramp.c</in> <in>alsa-plug-dmix.c</in> <in>alsa-plug-rate.c</in> <in>alsa-plug-route.c</in> @@ -150,7 +152,6 @@ <incDir> <pElem>../../../opt/include/afb</pElem> <pElem>app-afb-helpers-submodule</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-afb-helpers-submodule</pElem> </incDir> @@ -163,7 +164,6 @@ <cTool flags="1"> <incDir> <pElem>app-afb-helpers-submodule</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> <pElem>build/app-afb-helpers-submodule</pElem> </incDir> </cTool> @@ -174,10 +174,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -190,11 +186,7 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> <pElem>app-afb-helpers-submodule</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> </incDir> @@ -206,10 +198,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -222,10 +210,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -238,7 +222,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>app-controller-submodule/ctl-lib</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> </incDir> </cTool> @@ -249,10 +232,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -265,10 +244,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -281,10 +256,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -297,10 +268,6 @@ flavor2="3"> <cTool flags="1"> <incDir> - <pElem>../../../opt/include/afb</pElem> - <pElem>app-controller-submodule/ctl-lib</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> - <pElem>/usr/include/lua5.3</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>../../../opt/include</pElem> <pElem>build/app-controller-submodule/ctl-lib</pElem> @@ -329,7 +296,6 @@ <incDir> <pElem>../../../opt/include/afb</pElem> <pElem>mixer-binding</pElem> - <pElem>/usr/lib64/gcc/x86_64-suse-linux/7/include</pElem> <pElem>../../../opt/include/alsa</pElem> <pElem>app-afb-helpers-submodule</pElem> <pElem>app-controller-submodule/ctl-lib</pElem> @@ -361,7 +327,6 @@ <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/4a-softmixer/lib/plugins:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins"</Elem> <Elem>CTL_PLUGIN_MAGIC=987456123</Elem> <Elem>USE_API_DYN=1</Elem> - <Elem>alsa_router_EXPORTS</Elem> </preprocessorList> </cTool> </folder> @@ -372,121 +337,432 @@ <item path="plugins/alsa/alsa-api-loop.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> + </cTool> + </item> + <item path="plugins/alsa/alsa-api-mixer.c" ex="false" tool="0" flavor2="2"> + <cTool flags="0"> + <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> + <pElem>/usr/include/lua5.3</pElem> + </incDir> + <preprocessorList> + <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/etc:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/etc:/home/fulup/opt/4a-smixer/etc"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d:/home/fulup/opt/4a-smixer/var"</Elem> + <Elem>CONTROL_PLUGIN_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins:/home/fulup/opt/4a-smixer/lib/plugins"</Elem> + <Elem>alsa_softmixer_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-pcm.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-ramp.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-sink.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-source.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-streams.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/etc:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/etc:/home/fulup/opt/4a-smixer/etc"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d:/home/fulup/opt/4a-smixer/var"</Elem> + <Elem>CONTROL_PLUGIN_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins:/home/fulup/opt/4a-smixer/lib/plugins"</Elem> + <Elem>alsa_softmixer_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-api-zones.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-capture.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> + <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> + </incDir> <preprocessorList> <Elem>CONTROL_LUA_PATH="/home/fulup/opt/4a-softmixer/data:/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d"</Elem> <Elem>NATIVE_LINUX</Elem> + <Elem>alsa_router_EXPORTS</Elem> </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-core-ctl.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-core-pcm.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/etc:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/etc:/home/fulup/opt/4a-smixer/etc"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d:/home/fulup/opt/4a-smixer/var"</Elem> + <Elem>CONTROL_PLUGIN_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins:/home/fulup/opt/4a-smixer/lib/plugins"</Elem> + <Elem>alsa_softmixer_EXPORTS</Elem> + </preprocessorList> + </cTool> + </item> + <item path="plugins/alsa/alsa-effect-ramp.c" ex="false" tool="0" flavor2="0"> + <cTool flags="0"> + <incDir> + <pElem>/usr/include/json-c</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>/usr/include/lua5.3</pElem> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> + </incDir> + <preprocessorList> + <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/etc:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/etc:/home/fulup/opt/4a-smixer/etc"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d:/home/fulup/opt/4a-smixer/var"</Elem> + <Elem>CONTROL_PLUGIN_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins:/home/fulup/opt/4a-smixer/lib/plugins"</Elem> + <Elem>alsa_softmixer_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-plug-dmix.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-plug-rate.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-plug-route.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-plug-vol.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/etc:/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/etc:/home/fulup/opt/4a-smixer/etc"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/conf.d/project/lua.d:/home/fulup/opt/4a-smixer/var"</Elem> + <Elem>CONTROL_PLUGIN_PATH="/home/fulup/Workspace/Audio-4a/4a-softmixer/build/package/lib/plugins:/home/fulup/opt/4a-smixer/lib/plugins"</Elem> + <Elem>alsa_softmixer_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-softmixer.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-utils-bypath.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> <item path="plugins/alsa/alsa-utils-dump.c" ex="false" tool="0" flavor2="2"> <cTool flags="0"> <incDir> + <pElem>app-controller-submodule/ctl-lib</pElem> + <pElem>build/app-controller-submodule/ctl-lib</pElem> + <pElem>/usr/include</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/alsa</pElem> + <pElem>../../../opt/include</pElem> + <pElem>/usr/include/p11-kit-1</pElem> + <pElem>/usr/include/uuid</pElem> + <pElem>../../../opt/include/alsa</pElem> + <pElem>mixer-binding</pElem> + <pElem>app-afb-helpers-submodule</pElem> + <pElem>build/plugins/alsa</pElem> <pElem>/usr/include/lua5.3</pElem> </incDir> + <preprocessorList> + <Elem>alsa_router_EXPORTS</Elem> + </preprocessorList> </cTool> </item> </conf> diff --git a/plugins/alsa/alsa-api-mixer.c b/plugins/alsa/alsa-api-mixer.c index d37497a..26de510 100644 --- a/plugins/alsa/alsa-api-mixer.c +++ b/plugins/alsa/alsa-api-mixer.c @@ -74,16 +74,21 @@ STATIC void MixerInfoVerb(AFB_ReqT request) { SoftMixerT *mixer = (SoftMixerT*) afb_request_get_vcbdata(request); json_object *argsJ = afb_request_json(request); - int error, stream = 0, quiet = 0, backend = 0, source = 0, zones = 0; + int error, streams = 0, quiet = 0, ramps = 0, zones = 0, captures = 0, playbacks = 0; if (json_object_get_type(argsJ) == json_type_null) { - stream = 1; + streams = 1; + ramps = 1; + zones = 1; + captures = 0; + playbacks = 0; } else { - error = wrap_json_unpack(argsJ, "{s?b,s?b,s?b,s?b,s?b !}" + error = wrap_json_unpack(argsJ, "{s?b,s?b,s?b,s?b,s?b,s?b !}" , "quiet", &quiet - , "stream", &stream - , "backend", &backend - , "source", &source + , "streams", &streams + , "ramps", &ramps + , "captures", &captures + , "playbacks", &playbacks , "zones", &zones ); if (error) { @@ -93,12 +98,12 @@ STATIC void MixerInfoVerb(AFB_ReqT request) { } json_object *responseJ = json_object_new_object(); - if (stream) { + if (streams) { json_object *streamsJ = json_object_new_array(); json_object *valueJ; AlsaStreamAudioT **streams = mixer->streams; - for (int idx = 0; streams[idx]->uid; idx++) { + for (int idx = 0; streams[idx]; idx++) { if (quiet) { json_object_array_add(streamsJ, json_object_new_string(streams[idx]->uid)); } else { @@ -112,14 +117,86 @@ STATIC void MixerInfoVerb(AFB_ReqT request) { , "numid", numidJ ); json_object_array_add(streamsJ, valueJ); - AFB_ApiWarning(request->dynapi, "stream=%s", json_object_get_string(streamsJ)); } } json_object_object_add(responseJ, "streams", streamsJ); } - if (backend || source || zones) { + if (ramps) { + json_object *rampsJ = json_object_new_array(); + json_object *valueJ; + + AlsaVolRampT **ramps = mixer->ramps; + for (int idx = 0; ramps[idx]; idx++) { + if (quiet) { + json_object_array_add(rampsJ, json_object_new_string(ramps[idx]->uid)); + } else { + wrap_json_pack(&valueJ, "{ss,si,si,si}" + , "uid", ramps[idx]->uid + , "delay", ramps[idx]->delay + , "step_down", ramps[idx]->stepDown + , "step_up", ramps[idx]->stepUp + ); + json_object_array_add(rampsJ, valueJ); + } + + } + json_object_object_add(responseJ, "ramps", rampsJ); + } + + if (zones) { + json_object *zonesJ = json_object_new_array(); + + AlsaSndZoneT **zones = mixer->zones; + for (int idx = 0; zones[idx]; idx++) { + if (quiet) { + json_object_array_add(zonesJ, json_object_new_string(zones[idx]->uid)); + } else { + json_object *zoneJ = json_object_new_object(); + if (zones[idx]->sinks) { + json_object *sinksJ = json_object_new_array(); + for (int jdx = 0; zones[idx]->sinks[jdx]; jdx++) { + json_object *channelJ; + wrap_json_pack(&channelJ, "{ss,si}" + , "uid", zones[idx]->sinks[jdx]->uid + , "port", zones[idx]->sinks[jdx]->port + ); + json_object_array_add(sinksJ, channelJ); + } + json_object_object_add(zoneJ, "sinks", sinksJ); + } + + if (zones[idx]->sources) { + json_object *sourcesJ = json_object_new_array(); + for (int jdx = 0; zones[idx]->sources[jdx]; jdx++) { + json_object *channelJ; + wrap_json_pack(&channelJ, "{ss,si}" + , "uid", zones[idx]->sources[jdx]->uid + , "port", zones[idx]->sources[jdx]->port + ); + json_object_array_add(sourcesJ, channelJ); + } + json_object_object_add(zoneJ, "source", sourcesJ); + } + + if (zones[idx]->params) { + + json_object *paramsJ; + wrap_json_pack(¶msJ, "{si,ss,si}" + , "rate", zones[idx]->params->rate + , "format", zones[idx]->params->formatS + , "channels", zones[idx]->params->channels + ); + json_object_object_add(zoneJ, "params", paramsJ); + } + json_object_array_add(zonesJ, zoneJ); + } + } + json_object_object_add(responseJ, "zones", zonesJ); + } + + if (captures || playbacks) { AFB_ReqFailF(request, "not implemented", "(Fulup) list action Still To Be Done"); goto OnErrorExit; } @@ -134,12 +211,12 @@ OnErrorExit: STATIC void MixerAttachVerb(AFB_ReqT request) { SoftMixerT *mixer = (SoftMixerT*) afb_request_get_vcbdata(request); - const char *uid=NULL; + const char *uid = NULL; json_object *playbackJ = NULL, *captureJ = NULL, *zonesJ = NULL, *streamsJ = NULL, *rampsJ = NULL, *loopsJ = NULL; json_object *argsJ = afb_request_json(request); json_object *responseJ; int error; - + error = wrap_json_unpack(argsJ, "{ss,s?o,s?o,s?o,s?o,s?o,s?o !}" , "uid", &uid , "ramps", &rampsJ @@ -150,7 +227,7 @@ STATIC void MixerAttachVerb(AFB_ReqT request) { , "streams", &streamsJ ); if (error) { - AFB_ApiError(mixer->api, "MixerAttachVerb: invalid-syntax mixer=%s error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); + AFB_ApiError(mixer->api, "MixerAttachVerb: invalid-syntax mixer=%s error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); AFB_ReqFailF(request, "invalid-syntax", "mixer=%s missing 'uid|ramps|playbacks|captures|zones|streams' error=%s args=%s", mixer->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); goto OnErrorExit; } @@ -185,8 +262,7 @@ STATIC void MixerAttachVerb(AFB_ReqT request) { if (error) goto OnErrorExit; } - AFB_ReqNotice(request, "**** mixer=%s response=%s", json_object_get_string(responseJ), mixer->uid); - AFB_ReqSucess(request, NULL, mixer->uid); + AFB_ReqSucess(request, responseJ, mixer->uid); return; OnErrorExit: @@ -234,7 +310,7 @@ STATIC int MixerInitCB(AFB_ApiT api) { SoftMixerT *mixer = (SoftMixerT*) afb_dynapi_get_userdata(api); assert(mixer); - + // attach AFB mainloop to mixer mixer->sdLoop = AFB_GetEventLoop(api); @@ -247,14 +323,14 @@ STATIC int MixerInitCB(AFB_ApiT api) { STATIC int MixerApiCB(void* handle, AFB_ApiT api) { SoftMixerT *mixer = (SoftMixerT*) handle; - mixer->api= api; + mixer->api = api; afb_dynapi_set_userdata(api, mixer); afb_dynapi_on_event(api, MixerEventCB); afb_dynapi_on_init(api, MixerInitCB); int error = LoadStaticVerbs(mixer, CtrlApiVerbs); if (error) goto OnErrorExit; - + return 0; OnErrorExit: @@ -287,7 +363,7 @@ CTLP_LUA2C(_mixer_new_, source, argsJ, responseJ) { , "max_ramp", &mixer->max.ramps ); if (error) { - AFB_ApiNotice(source->api, "_mixer_new_ missing 'uid|max_loop|max_sink|max_source|max_zone|max_stream|max_ramp' error=%s mixer=%s", wrap_json_get_error_string(error),json_object_get_string(argsJ)); + AFB_ApiNotice(source->api, "_mixer_new_ missing 'uid|max_loop|max_sink|max_source|max_zone|max_stream|max_ramp' error=%s mixer=%s", wrap_json_get_error_string(error), json_object_get_string(argsJ)); goto OnErrorExit; } @@ -295,12 +371,12 @@ CTLP_LUA2C(_mixer_new_, source, argsJ, responseJ) { mixer->uid = strdup(mixer->uid); if (mixer->info)mixer->info = strdup(mixer->info); - mixer->loops = calloc(mixer->max.loops+1, sizeof (AlsaSndLoopT)); - mixer->sinks = calloc(mixer->max.sinks+1, sizeof (AlsaSndPcmT)); - mixer->sources = calloc(mixer->max.sources+1, sizeof (AlsaSndPcmT)); - mixer->zones = calloc(mixer->max.zones+1, sizeof (AlsaSndZoneT)); - mixer->streams = calloc(mixer->max.streams+1, sizeof (AlsaStreamAudioT)); - mixer->ramps = calloc(mixer->max.ramps+1, sizeof (AlsaVolRampT)); + mixer->loops = calloc(mixer->max.loops + 1, sizeof (void*)); + mixer->sinks = calloc(mixer->max.sinks + 1, sizeof (void*)); + mixer->sources = calloc(mixer->max.sources + 1, sizeof (void*)); + mixer->zones = calloc(mixer->max.zones + 1, sizeof (void*)); + mixer->streams = calloc(mixer->max.streams + 1, sizeof (void*)); + mixer->ramps = calloc(mixer->max.ramps + 1, sizeof (void*)); // create mixer verb within API. error = afb_dynapi_new_api(source->api, mixer->uid, mixer->info, !MAINLOOP_CONCURENCY, MixerApiCB, mixer); diff --git a/plugins/alsa/alsa-api-pcm.c b/plugins/alsa/alsa-api-pcm.c index 5340f99..de9ed0c 100644 --- a/plugins/alsa/alsa-api-pcm.c +++ b/plugins/alsa/alsa-api-pcm.c @@ -25,6 +25,31 @@ #define CONVERT_RANGE(val, min, max) ceil((val) * ((max) - (min)) * 0.01 + (min)) #define CONVERT_VOLUME(val, min, max) (int) CONVERT_RANGE ((double)val, (double)min, (double)max) +// move from volume to percentage (extract from alsa-utils) + +STATIC int CONVERT_PERCENT(long val, long min, long max) { + long range = max - min; + int tmp; + if (range == 0) + return 0; + val -= min; + tmp = rint((double) val / (double) range * 100); + return tmp; +} + +typedef enum { + RVOL_ABS, + RVOL_ADD, + RVOL_DEL, + + RVOL_NONE +} volumeT; + +typedef struct { + const char *uid; + SoftMixerT *mixer; + AlsaSndPcmT* pcm; +} apiVerbHandleT; STATIC AlsaPcmChannelT *ProcessOneChannel(SoftMixerT *mixer, const char *uid, json_object *argsJ) { AlsaPcmChannelT *channel = calloc(1, sizeof (AlsaPcmChannelT)); @@ -40,7 +65,7 @@ OnErrorExit: return NULL; } -STATIC int ProcessOneControl(SoftMixerT *mixer, AlsaSndPcmT* pcm, json_object *argsJ, AlsaSndControlT *control) { +STATIC int PcmAttachOneCtl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, json_object *argsJ, AlsaSndControlT *control) { snd_ctl_elem_id_t* elemId = NULL; snd_ctl_elem_info_t *elemInfo; int numid = 0; @@ -54,21 +79,21 @@ STATIC int ProcessOneControl(SoftMixerT *mixer, AlsaSndPcmT* pcm, json_object *a , "value", &value ); if (error || (!numid && !name)) { - AFB_ApiError(mixer->api, "ProcessOneControl: sndcard=%s channel: missing (numid|name|value) error=%s json=%s", pcm->uid, wrap_json_get_error_string(error), json_object_get_string(argsJ)); + AFB_ApiError(mixer->api, "PcmAttachOneCtl: cardid=%s channel: missing (numid|name|value) error=%s json=%s", sndcard->cid.name, wrap_json_get_error_string(error), json_object_get_string(argsJ)); goto OnErrorExit; } if (numid > 0) { - elemId = AlsaCtlGetNumidElemId(mixer, pcm->sndcard, numid); + elemId = AlsaCtlGetNumidElemId(mixer, sndcard, numid); if (!elemId) { - AFB_ApiError(mixer->api, "ProcessOneControl sndard=%s fail to find control numid=%d", pcm->sndcard->cid.cardid, numid); + AFB_ApiError(mixer->api, "PcmAttachOneCtl sndard=%s fail to find control numid=%d", sndcard->cid.cardid, numid); goto OnErrorExit; } } else { - elemId = AlsaCtlGetNameElemId(mixer, pcm->sndcard, name); + elemId = AlsaCtlGetNameElemId(mixer, sndcard, name); if (!elemId) { - AFB_ApiError(mixer->api, "ProcessOneControl sndard=%s fail to find control name=%s", pcm->sndcard->cid.cardid, name); + AFB_ApiError(mixer->api, "PcmAttachOneCtl sndard=%s fail to find control name=%s", sndcard->cid.cardid, name); goto OnErrorExit; } } @@ -78,13 +103,13 @@ STATIC int ProcessOneControl(SoftMixerT *mixer, AlsaSndPcmT* pcm, json_object *a control->name = strdup(snd_ctl_elem_info_get_name(elemInfo)); control->numid = snd_ctl_elem_info_get_numid(elemInfo); - if (snd_ctl_elem_info(pcm->sndcard->ctl, elemInfo) < 0) { - AFB_ApiError(mixer->api, "ProcessOneControl: sndard=%s numid=%d name='%s' not loadable", pcm->sndcard->cid.cardid, control->numid, control->name); + if (snd_ctl_elem_info(sndcard->ctl, elemInfo) < 0) { + AFB_ApiError(mixer->api, "PcmAttachOneCtl: sndard=%s numid=%d name='%s' not loadable", sndcard->cid.cardid, control->numid, control->name); goto OnErrorExit; } if (!snd_ctl_elem_info_is_writable(elemInfo)) { - AFB_ApiError(mixer->api, "ProcessOneControl: sndard=%s numid=%d name='%s' not writable", pcm->sndcard->cid.cardid, control->numid, control->name); + AFB_ApiError(mixer->api, "PcmAttachOneCtl: sndard=%s numid=%d name='%s' not writable", sndcard->cid.cardid, control->numid, control->name); goto OnErrorExit; } @@ -94,7 +119,7 @@ STATIC int ProcessOneControl(SoftMixerT *mixer, AlsaSndPcmT* pcm, json_object *a control->min = 0; control->max = 1; control->step = 0; - error = CtlElemIdSetLong(mixer, pcm->sndcard, elemId, value); + error = CtlElemIdSetLong(mixer, sndcard, elemId, value); break; case SND_CTL_ELEM_TYPE_INTEGER: @@ -102,16 +127,16 @@ STATIC int ProcessOneControl(SoftMixerT *mixer, AlsaSndPcmT* pcm, json_object *a control->min = snd_ctl_elem_info_get_min(elemInfo); control->max = snd_ctl_elem_info_get_max(elemInfo); control->step = snd_ctl_elem_info_get_step(elemInfo); - error = CtlElemIdSetLong(mixer, pcm->sndcard, elemId, (int) CONVERT_VOLUME(value, control->min, control->max)); + error = CtlElemIdSetLong(mixer, sndcard, elemId, (int) CONVERT_VOLUME(value, control->min, control->max)); break; default: - AFB_ApiError(mixer->api, "ProcessOneControl: sndard=%s numid=%d name='%s' invalid/unsupported type=%d", pcm->sndcard->cid.cardid, control->numid, control->name, snd_ctl_elem_info_get_type(elemInfo)); + AFB_ApiError(mixer->api, "PcmAttachOneCtl: sndard=%s numid=%d name='%s' invalid/unsupported type=%d", sndcard->cid.cardid, control->numid, control->name, snd_ctl_elem_info_get_type(elemInfo)); goto OnErrorExit; } if (error) { - AFB_ApiError(mixer->api, "ProcessOneControl: sndard=%s numid=%d name='%s' not writable", pcm->sndcard->cid.cardid, control->numid, control->name); + AFB_ApiError(mixer->api, "PcmAttachOneCtl: sndard=%s numid=%d name='%s' not writable", sndcard->cid.cardid, control->numid, control->name); goto OnErrorExit; } @@ -124,7 +149,160 @@ OnErrorExit: return -1; } -PUBLIC AlsaPcmHwInfoT *ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json_object *paramsJ) { +STATIC int PcmSetControl(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaSndControlT *control, volumeT volType, int value) { + snd_ctl_elem_id_t* elemId = NULL; + snd_ctl_elem_info_t *elemInfo; + int error; + long curval; + + assert(control->numid); + + elemId = AlsaCtlGetNumidElemId(mixer, sndcard, control->numid); + if (!elemId) { + AFB_ApiError(mixer->api, "PcmSetControl sndard=%s fail to find control numid=%d", sndcard->cid.cardid, control->numid); + goto OnErrorExit; + } + + snd_ctl_elem_info_alloca(&elemInfo); + snd_ctl_elem_info_set_id(elemInfo, elemId); + + if (snd_ctl_elem_info(sndcard->ctl, elemInfo) < 0) { + AFB_ApiError(mixer->api, "PcmSetControl: sndard=%s numid=%d name='%s' not loadable", sndcard->cid.cardid, control->numid, control->name); + goto OnErrorExit; + } + + if (!snd_ctl_elem_info_is_writable(elemInfo)) { + AFB_ApiError(mixer->api, "PcmSetControl: sndard=%s numid=%d name='%s' not writable", sndcard->cid.cardid, control->numid, control->name); + goto OnErrorExit; + } + + error = CtlElemIdGetLong(mixer, sndcard, elemId, &curval); + if (!error) { + AFB_ApiError(mixer->api, "PcmSetControl sndard=%s fail to read control numid=%d", sndcard->cid.cardid, control->numid); + goto OnErrorExit; + } + + switch (snd_ctl_elem_info_get_type(elemInfo)) { + + case SND_CTL_ELEM_TYPE_BOOLEAN: + error = CtlElemIdSetLong(mixer, sndcard, elemId, value); + break; + + case SND_CTL_ELEM_TYPE_INTEGER: + case SND_CTL_ELEM_TYPE_INTEGER64: + + switch (volType) { + case RVOL_ADD: + value = CONVERT_PERCENT(curval, control->min, control->max) + value; + break; + case RVOL_DEL: + value = CONVERT_PERCENT(curval, control->min, control->max) - value; + break; + default: + value= CONVERT_VOLUME(value, control->min, control->max); + } + + error = CtlElemIdSetLong(mixer, sndcard, elemId, (int)value); + break; + + default: + AFB_ApiError(mixer->api, "PcmSetControl: sndard=%s numid=%d name='%s' invalid/unsupported type=%d", sndcard->cid.cardid, control->numid, control->name, snd_ctl_elem_info_get_type(elemInfo)); + goto OnErrorExit; + } + + if (error) { + AFB_ApiError(mixer->api, "PcmSetControl: sndard=%s numid=%d name='%s' not writable", sndcard->cid.cardid, control->numid, control->name); + goto OnErrorExit; + } + + free(elemId); + return 0; + +OnErrorExit: + if (elemId)free(elemId); + return -1; +} + +STATIC void ApiPcmVerbCB(AFB_ReqT request) { + apiVerbHandleT *handle = (apiVerbHandleT*) afb_request_get_vcbdata(request); + int error, doQuiet = 0, doToggle = 0, doMute = -1; + json_object *volumeJ = NULL; + json_object *responseJ = json_object_new_object(); + json_object *argsJ = afb_request_json(request); + + SoftMixerT *mixer = handle->mixer; + AlsaSndCtlT *sndcard = handle->pcm->sndcard; + assert(mixer && sndcard); + + error = wrap_json_unpack(argsJ, "{s?b s?b,s?b,s?o !}" + , "quiet", &doQuiet + , "mute", &doMute + , "toggle", &doToggle + , "volume", &volumeJ + ); + if (error) { + AFB_ReqFailF(request, "syntax-error", "Missing 'mute|volume|toggle|quiet' args=%s error=%s", json_object_get_string(argsJ), wrap_json_get_error_string(error)); + goto OnErrorExit; + } + + if (volumeJ) { + volumeT volType; + + int newvol; + const char*volString; + + switch (json_object_get_type(volumeJ)) { + case json_type_string: + volString = json_object_get_string(volumeJ); + switch (volString[0]) { + case '+': + sscanf(&volString[1], "%d", &newvol); + volType = RVOL_ADD; + break; + + case '-': + sscanf(&volString[1], "%d", &newvol); + volType = RVOL_DEL; + break; + default: + error = sscanf(&volString[0], "%d", &newvol); + volType = RVOL_ABS; + if (error != 1) { + AFB_ReqFailF(request, "not-integer", "relative volume should start by '+|-' value=%s", json_object_get_string(volumeJ)); + goto OnErrorExit; + } + } + break; + case json_type_int: + volType = RVOL_ABS; + newvol = json_object_get_int(volumeJ); + break; + default: + AFB_ReqFailF(request, "not-integer", "volume should be string or integer value=%s", json_object_get_string(volumeJ)); + goto OnErrorExit; + + } + + error = PcmSetControl(mixer, handle->pcm->sndcard, &handle->pcm->volume, volType, newvol); + if (error) { + AFB_ReqFailF(request, "invalid-ctl", "Fail to set volume hal=%s card=%s numid=%d name=%s value=%d" + , handle->uid, handle->pcm->sndcard->cid.cardid, handle->pcm->volume.numid, handle->pcm->volume.name, newvol); + goto OnErrorExit; + } + + if (!doQuiet) { + json_object_object_add(responseJ, "volume", json_object_new_int(newvol)); + } + } + + AFB_ReqSucess(request, responseJ, handle->uid); + return; + +OnErrorExit: + return; +} + +PUBLIC AlsaPcmHwInfoT * ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json_object * paramsJ) { AlsaPcmHwInfoT *params = calloc(1, sizeof (AlsaPcmHwInfoT)); const char *format = NULL, *access = NULL; @@ -168,7 +346,6 @@ PUBLIC AlsaPcmHwInfoT *ApiPcmSetParams(SoftMixerT *mixer, const char *uid, json_ } } - if (!access) params->access = SND_PCM_ACCESS_RW_INTERLEAVED; else if (!strcasecmp(access, "MMAP_INTERLEAVED")) params->access = SND_PCM_ACCESS_MMAP_INTERLEAVED; else if (!strcasecmp(access, "MMAP_NONINTERLEAVED")) params->access = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; @@ -188,7 +365,7 @@ OnErrorExit: return NULL; } -PUBLIC AlsaSndPcmT *ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_stream_t direction, json_object *argsJ) { +PUBLIC AlsaSndPcmT * ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_stream_t direction, json_object * argsJ) { AlsaSndPcmT *pcm = calloc(1, sizeof (AlsaSndPcmT)); json_object *sourceJ = NULL, *paramsJ = NULL, *sinkJ = NULL, *targetJ = NULL; int error; @@ -215,7 +392,7 @@ PUBLIC AlsaSndPcmT *ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_ AFB_ApiError(mixer->api, "ApiPcmAttachOne: hal=%s Fail to open sndcard uid=%s devpath=%s cardid=%s", uid, pcm->uid, pcm->sndcard->cid.devpath, pcm->sndcard->cid.cardid); goto OnErrorExit; } - + // check sndcard accepts params pcm->sndcard->params = ApiPcmSetParams(mixer, pcm->uid, paramsJ); if (!pcm->sndcard->params) { @@ -239,7 +416,7 @@ PUBLIC AlsaSndPcmT *ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_ targetJ = sourceJ; // we may have to register SMIXER_SUBDS_CTLS per subdev (Fulup ToBeDone when sndcard get multiple device/subdev) - pcm->sndcard->registry = calloc(SMIXER_SUBDS_CTLS+1, sizeof (RegistryEntryPcmT)); + pcm->sndcard->registry = calloc(SMIXER_SUBDS_CTLS + 1, sizeof (RegistryEntryPcmT)); pcm->sndcard->rcount = SMIXER_SUBDS_CTLS; } @@ -271,7 +448,7 @@ PUBLIC AlsaSndPcmT *ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_ } break; default: - AFB_ApiError(mixer->api, "ProcessPcmControls:%s invalid pcm=%s", pcm->uid, json_object_get_string(channelsJ)); + AFB_ApiError(mixer->api, "ApiPcmAttachOne:%s invalid pcm=%s", pcm->uid, json_object_get_string(channelsJ)); goto OnErrorExit; } } @@ -283,13 +460,33 @@ PUBLIC AlsaSndPcmT *ApiPcmAttachOne(SoftMixerT *mixer, const char *uid, snd_pcm_ , "mute", &muteJ ); if (error) { - AFB_ApiNotice(mixer->api, "ProcessPcmControls: source missing [volume]|[mute] error=%s control=%s", wrap_json_get_error_string(error), json_object_get_string(controlsJ)); + AFB_ApiNotice(mixer->api, "ApiPcmAttachOne: source missing [volume]|[mute] error=%s control=%s", wrap_json_get_error_string(error), json_object_get_string(controlsJ)); goto OnErrorExit; } - if (volJ) error += ProcessOneControl(mixer, pcm, volJ, &pcm->volume); - if (muteJ) error += ProcessOneControl(mixer, pcm, muteJ, &pcm->mute); + if (volJ) error += PcmAttachOneCtl(mixer, pcm->sndcard, volJ, &pcm->volume); + if (muteJ) error += PcmAttachOneCtl(mixer, pcm->sndcard, muteJ, &pcm->mute); if (error) goto OnErrorExit; + + // create master control for this sink + char *apiVerb, *apiInfo; + if (direction == SND_PCM_STREAM_PLAYBACK) { + (void) asprintf(&apiVerb, "%s/playback", pcm->uid); + (void) asprintf(&apiInfo, "HAL:%s SND_PCM_STREAM_PLAYBACK", uid); + } else { + (void) asprintf(&apiVerb, "%s/playback", pcm->uid); + (void) asprintf(&apiInfo, "HAL:%s SND_PCM_STREAM_PLAYBACK", uid); + } + apiVerbHandleT *handle = calloc(1, sizeof (apiVerbHandleT)); + handle->uid = uid; + handle->pcm = pcm; + handle->mixer = mixer; + + error = afb_dynapi_add_verb(mixer->api, apiVerb, apiInfo, ApiPcmVerbCB, handle, NULL, 0); + if (error) { + AFB_ApiError(mixer->api, "ApiPcmAttachOne mixer=%s verb=%s fail to Register Master control ", mixer->uid, apiVerb); + goto OnErrorExit; + } } // free useless resource and secure others diff --git a/plugins/alsa/alsa-api-streams.c b/plugins/alsa/alsa-api-streams.c index 262553a..6911dc2 100644 --- a/plugins/alsa/alsa-api-streams.c +++ b/plugins/alsa/alsa-api-streams.c @@ -76,7 +76,7 @@ STATIC void StreamApiVerbCB(AFB_ReqT request) { error = AlsaCtlNumidGetLong(mixer, handle->sndcard, handle->stream->volume, &curvol); if (error) { - AFB_ReqFailF(request, "invalid-numid", "Fail to set volume numid=%d value=%ld", handle->stream->volume, volume); + AFB_ReqFailF(request, "invalid-numid", "Fail to get volume numid=%d value=%ld", handle->stream->volume, volume); goto OnErrorExit; } @@ -95,8 +95,11 @@ STATIC void StreamApiVerbCB(AFB_ReqT request) { newvol = curvol - newvol; break; default: - AFB_ReqFailF(request, "not-integer", "relative volume should start by '+|-' value=%s", json_object_get_string(volumeJ)); - goto OnErrorExit; + error = sscanf(&volString[0], "%ld", &newvol); + if (error != 1) { + AFB_ReqFailF(request, "not-integer", "relative volume should start by '+|-' value=%s", json_object_get_string(volumeJ)); + goto OnErrorExit; + } } break; case json_type_int: @@ -153,7 +156,7 @@ OnErrorExit: PUBLIC json_object *CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) { int error; long value; - AlsaSndLoopT *loop=NULL; + AlsaSndLoopT *loop = NULL; AlsaPcmCtlT *streamPcm; AlsaSndCtlT *captureCard; AlsaDevInfoT *captureDev = alloca(sizeof (AlsaDevInfoT)); @@ -188,8 +191,8 @@ PUBLIC json_object *CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) // check PCM is valid and get its full name AlsaPcmCtlT *capturePcm = AlsaByPathOpenPcm(mixer, captureDev, SND_PCM_STREAM_CAPTURE); if (!capturePcm) goto OnErrorExit; - - // Registry capturePcm PCM for active/pause event + + // Registry capturePcm PCM for active/pause event if (loopDev && loopDev->numid) { error = AlsaCtlRegister(mixer, captureCard, capturePcm, FONTEND_NUMID_RUN, loopDev->numid); if (error) goto OnErrorExit; @@ -237,9 +240,9 @@ PUBLIC json_object *CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) AFB_ApiError(mixer->api, "StreamsAttach: mixer=%s stream=%s fail to create rate converter", mixer->uid, stream->uid); goto OnErrorExit; } - captureName=rateName; + captureName = rateName; } else { - captureName= (char*)streamPcm->cid.cardid; + captureName = (char*) streamPcm->cid.cardid; } // everything is not ready to open playback pcm @@ -269,27 +272,31 @@ PUBLIC json_object *CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) } // prepare response for application - json_object *paramsJ, *streamJ; + json_object *paramsJ, *streamJ, *numidsJ; char *appCardId = NULL; - + // return alsa URI only when loopback is used if (loop) { (void) asprintf(&appCardId, "hw:%d,%d,%d", captureDev->cardidx, loop->playback, capturePcm->cid.subdev); } else { - appCardId=""; + appCardId = ""; } + error += wrap_json_pack(¶msJ, "{si si si si}" , "rate", stream->params->rate , "channels", stream->params->channels , "format", stream->params->format , "access", stream->params->access ); - error += wrap_json_pack(&streamJ, "{ss ss si si so}", "uid" - , stream->uid, "alsa" - , appCardId - , "volid", volNumid - , "runid", pauseNumid + error += wrap_json_pack(&numidsJ, "{si si}" + , "volume", volNumid + , "pause", pauseNumid + ); + error += wrap_json_pack(&streamJ, "{ss ss so so}" + , "uid", stream->uid + , "alsa", appCardId + , "numid", numidsJ , "params", paramsJ ); if (error) { @@ -302,8 +309,12 @@ PUBLIC json_object *CreateOneStream(SoftMixerT *mixer, AlsaStreamAudioT *stream) apiHandle->mixer = mixer; apiHandle->stream = stream; - apiHandle->sndcard =captureCard; + apiHandle->sndcard = captureCard; apiHandle->pcm = capturePcm->handle; + + // replace stream volume/mute values with corresponding ctl control + stream->volume=volNumid; + stream->mute=pauseNumid; error = afb_dynapi_add_verb(mixer->api, stream->uid, stream->info, StreamApiVerbCB, apiHandle, NULL, 0); if (error) { @@ -399,7 +410,7 @@ PUBLIC int ApiStreamAttach(SoftMixerT *mixer, AFB_ReqT request, const char *uid, case json_type_array: *responseJ = json_object_new_array(); - + count = json_object_array_length(argsJ); if (count > (mixer->max.streams - count)) { AFB_ReqFailF(request, "too-small", "mixer=%s max stream=%d argsJ= %s", mixer->uid, mixer->max.streams, json_object_get_string(argsJ)); diff --git a/plugins/alsa/alsa-core-pcm.c b/plugins/alsa/alsa-core-pcm.c index b69d8c6..de2c437 100644 --- a/plugins/alsa/alsa-core-pcm.c +++ b/plugins/alsa/alsa-core-pcm.c @@ -222,8 +222,8 @@ STATIC int AlsaPcmReadCB(sd_event_source* src, int fd, uint32_t revents, void* u } // In/Out frames transfer through buffer copy - //framesOut = snd_pcm_writei(pcmCopyHandle->pcmOut, pcmCopyHandle->buffer, framesIn); - framesOut = snd_pcm_mmap_writei (pcmCopyHandle->pcmOut, pcmCopyHandle->buffer, framesIn); + framesOut = snd_pcm_writei(pcmCopyHandle->pcmOut, pcmCopyHandle->buffer, framesIn); + //framesOut = snd_pcm_mmap_writei (pcmCopyHandle->pcmOut, pcmCopyHandle->buffer, framesIn); if (framesOut < 0 || framesOut != framesIn) { AFB_ApiNotice(pcmCopyHandle->api, "AlsaPcmReadCB PcmOut=%s UNDERUN frame=%ld", ALSA_PCM_UID(pcmCopyHandle->pcmOut, string), (framesIn - framesOut)); snd_pcm_prepare(pcmCopyHandle->pcmOut); diff --git a/plugins/alsa/alsa-effect-ramp.c b/plugins/alsa/alsa-effect-ramp.c index 361ff05..312bdfa 100644 --- a/plugins/alsa/alsa-effect-ramp.c +++ b/plugins/alsa/alsa-effect-ramp.c @@ -90,7 +90,7 @@ PUBLIC int AlsaVolRampApply(SoftMixerT *mixer, AlsaSndCtlT *sndcard, AlsaStreamA error = wrap_json_unpack(rampJ, "{ss so !}" , "uid", &uid - , "vol", &volJ + , "volume", &volJ ); if (error) { AFB_ApiError(mixer->api, "AlsaVolRampApply:mixer=%s stream=%s invalid-json should {uid:ramp, vol:[+,-,=]value} ramp=%s", mixer->uid, stream->uid, json_object_get_string(rampJ)); diff --git a/plugins/alsa/alsa-plug-vol.c b/plugins/alsa/alsa-plug-vol.c index f16b0a9..ab06cc1 100644 --- a/plugins/alsa/alsa-plug-vol.c +++ b/plugins/alsa/alsa-plug-vol.c @@ -22,7 +22,7 @@ ALSA_PLUG_PROTO(softvol); // stream uses solftvol plugin -PUBLIC AlsaPcmCtlT* AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaSndZoneT *zone, AlsaSndCtlT *sndcard, char* ctlName, int max, int open) { +PUBLIC AlsaPcmCtlT *AlsaCreateSoftvol(SoftMixerT *mixer, AlsaStreamAudioT *stream, AlsaSndZoneT *zone, AlsaSndCtlT *sndcard, char* ctlName, int max, int open) { snd_config_t *streamConfig, *elemConfig, *slaveConfig, *controlConfig,*pcmConfig; AlsaPcmCtlT *pcmVol= calloc(1,sizeof(AlsaPcmCtlT)); int error = 0; |