50_aec.conf 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. ### ALSA virtual device which combines recording and playback loopback for AEC processing
  2. # https://github.com/sanebow/alsa-aec
  3. # sanebow@gmail.com
  4. # Version: 0.3 (20210506)
  5. defaults.pcm.aec.playback_hw.card defaults.pcm.card # playback hw card
  6. defaults.pcm.aec.playback_hw.rate 48000 # sample rate supported by the playback card
  7. defaults.pcm.aec.capture_hw.card defaults.pcm.card # capture hw card
  8. defaults.pcm.aec.capture_hw.rate 16000 # sample rate supported by the capture card
  9. ## you may also directly set some PCM device as playback and capture device
  10. defaults.pcm.aec.playback_pcm "playback_hw"
  11. defaults.pcm.aec.capture_pcm "capture_hw"
  12. defaults.pcm.aec.pre_loopidx 4 # loopback subdevice index for stream before aec processing
  13. defaults.pcm.aec.post_loopidx 5 # loopback subdevice index for stream after aec processing
  14. pcm.playback_hw {
  15. @args [ CARD RATE ]
  16. @args.CARD {
  17. type string
  18. default {
  19. @func refer
  20. name defaults.pcm.aec.playback_hw.card
  21. }
  22. }
  23. @args.RATE {
  24. type integer
  25. default {
  26. @func refer
  27. name defaults.pcm.aec.playback_hw.rate
  28. }
  29. }
  30. type plug
  31. slave.rate "unchanged"
  32. slave.pcm {
  33. type rate
  34. slave.rate $RATE
  35. slave.pcm {
  36. type dmix
  37. ipc_key 10009
  38. ipc_key_add_uid yes
  39. slave {
  40. pcm {@func concat strings [ "hw:" $CARD ] }
  41. }
  42. }
  43. }
  44. }
  45. pcm.capture_hw {
  46. @args [ CARD RATE ]
  47. @args.CARD {
  48. type string
  49. default {
  50. @func refer
  51. name defaults.pcm.aec.capture_hw.card
  52. }
  53. }
  54. @args.RATE {
  55. type integer
  56. default {
  57. @func refer
  58. name defaults.pcm.aec.capture_hw.rate
  59. }
  60. }
  61. type rate
  62. slave.rate $RATE
  63. slave.pcm {
  64. type dsnoop
  65. ipc_key 20009
  66. ipc_key_add_uid yes
  67. slave {
  68. pcm {@func concat strings [ "hw:" $CARD ] }
  69. rate $RATE
  70. }
  71. bindings.0 0
  72. }
  73. }
  74. pcm.loopback_out {
  75. @args [ SUBDEVICE ]
  76. @args.SUBDEVICE { type integer }
  77. type empty
  78. slave.pcm {
  79. type hw
  80. card "Loopback"
  81. device 0
  82. subdevice $SUBDEVICE
  83. channels 1
  84. rate 16000
  85. format S16_LE
  86. }
  87. }
  88. pcm.loopback_in {
  89. @args [ SUBDEVICE ]
  90. @args.SUBDEVICE { type integer }
  91. type empty
  92. slave.pcm {
  93. type hw
  94. card "Loopback"
  95. device 1
  96. subdevice $SUBDEVICE
  97. channels 1
  98. rate 16000
  99. format S16_LE
  100. }
  101. }
  102. # audio play to this device will be duplicated to hw (stereo) and loopback (mono)
  103. pcm.mloopplay {
  104. @args [ PCM LOOPIDX ]
  105. @args.PCM {
  106. type string
  107. default {
  108. @func refer
  109. name defaults.pcm.aec.playback_pcm
  110. }
  111. }
  112. @args.LOOPIDX {
  113. type integer
  114. default 4
  115. }
  116. type route
  117. slave.pcm {
  118. type multi
  119. slaves.a.pcm $PCM
  120. slaves.a.channels 2
  121. slaves.b.pcm { # loopback null sink
  122. @func concat
  123. strings [ "plug:loopback_out:" $LOOPIDX ]
  124. }
  125. slaves.b.channels 1
  126. bindings.0 { slave a channel 0 }
  127. bindings.1 { slave a channel 1 }
  128. bindings.2 { slave b channel 0 }
  129. }
  130. slave.channels 3
  131. ttable.0.0 1
  132. ttable.1.1 1
  133. ttable.0.2 0.5
  134. ttable.1.2 0.5
  135. }
  136. # combine mic (ch 0) and loopback (ch 1) to single recording
  137. pcm.mlooprec {
  138. @args [ PCM LOOPIDX ]
  139. @args.PCM {
  140. type string
  141. default {
  142. @func refer
  143. name defaults.pcm.aec.capture_pcm
  144. }
  145. }
  146. @args.LOOPIDX {
  147. type integer
  148. default 4
  149. }
  150. type multi
  151. slaves.a.pcm $PCM
  152. slaves.a.channels 1
  153. slaves.b.pcm { # loopback capturing interface
  154. type dsnoop # to align with capture_hw, avoid PortAudio error
  155. ipc_key 10099
  156. slave.pcm {
  157. @func concat
  158. strings [ "loopback_in:" $LOOPIDX ]
  159. }
  160. }
  161. slaves.b.channels 1
  162. bindings.0 { slave a channel 0 }
  163. bindings.1 { slave b channel 0 }
  164. }
  165. pcm.aec_internal {
  166. @args [ CAPPCM PRELOOPIDX POSTLOOPIDX ]
  167. @args.CAPPCM {
  168. type string
  169. default {
  170. @func refer
  171. name defaults.pcm.aec.capture_pcm
  172. }
  173. }
  174. @args.PRELOOPIDX {
  175. type integer
  176. default {
  177. @func refer
  178. name defaults.pcm.aec.pre_loopidx
  179. }
  180. }
  181. @args.POSTLOOPIDX {
  182. type integer
  183. default {
  184. @func refer
  185. name defaults.pcm.aec.post_loopidx
  186. }
  187. }
  188. type asym
  189. capture.pcm { # -i for aec script
  190. @func concat
  191. strings [ "mlooprec:" $CAPPCM "," $PRELOOPIDX ]
  192. }
  193. playback.pcm { # -o for aec script
  194. @func concat
  195. strings [ "loopback_out:" $POSTLOOPIDX ]
  196. }
  197. }
  198. pcm.aec {
  199. @args [ PLYPCM PRELOOPIDX POSTLOOPIDX ]
  200. @args.PLYPCM {
  201. type string
  202. default {
  203. @func refer
  204. name defaults.pcm.aec.playback_pcm
  205. }
  206. }
  207. @args.PRELOOPIDX {
  208. type integer
  209. default {
  210. @func refer
  211. name defaults.pcm.aec.pre_loopidx
  212. }
  213. }
  214. @args.POSTLOOPIDX {
  215. type integer
  216. default {
  217. @func refer
  218. name defaults.pcm.aec.post_loopidx
  219. }
  220. }
  221. type asym
  222. playback.pcm {
  223. @func concat
  224. strings [ "mloopplay:" $PLYPCM "," $PRELOOPIDX ]
  225. }
  226. capture.pcm {
  227. @func concat
  228. strings [ "loopback_in:" $POSTLOOPIDX ]
  229. }
  230. }