Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stereo audio capture #122

Open
AdelKS opened this issue Jan 29, 2022 · 2 comments
Open

Stereo audio capture #122

AdelKS opened this issue Jan 29, 2022 · 2 comments

Comments

@AdelKS
Copy link

AdelKS commented Jan 29, 2022

Hello,

I am trying to capture the audio of my machine using the example from music_bot.py, and modified it accordingly:

#!/usr/bin/env python

#!/usr/bin/python3

import pymumble_py3
import subprocess as sp
import audioop, time
import argparse

parser = argparse.ArgumentParser(description='get parameters.')

parser.add_argument('--server', '-s', required=True)
parser.add_argument('--port', '-P', type=int, default=64738)
parser.add_argument('--name', '-n', required=True)
parser.add_argument('--passwd', '-p', default="")
args = parser.parse_args()

server = args.server
nick = args.name
passwd = args.passwd
port = args.port

mumble = pymumble_py3.Mumble(server, nick, password=passwd, port=port, stereo=False)
mumble.set_receive_sound(True)
mumble.start()
mumble.is_ready()   #wait for Mumble to get ready to avoid errors after startup

while True:
    print("start Processing")
    command = ["ffmpeg", "-f", "pulse", "-i", "alsa_output.usb-SteelSeries_SteelSeries_GameDAC_000000000000-00.pro-output-0.monitor", "-f", "s16le", "-ab", "320k", "-ac", "1", "-ar", "48000",  "-"]
    sound = sp.Popen(command, stdout=sp.PIPE, stderr=sp.DEVNULL, bufsize=1024)
    print("playing")
    while True:
        raw_music = sound.stdout.read(1024)
        if not raw_music:
            break
        #mumble.sound_output.add_sound(audioop.mul(raw_music, 2, vol))   #adjusting volume
        mumble.sound_output.add_sound(raw_music)
    print("finished")
    while mumble.sound_output.get_buffer_size() > 0.5:  #
        time.sleep(0.01)
    print("sleep")
    time.sleep(2)

and this script works. However, if I try to do stereo capturing like this

#!/usr/bin/env python

#!/usr/bin/python3

import pymumble_py3
import subprocess as sp
import audioop, time
import argparse

parser = argparse.ArgumentParser(description='get parameters.')

parser.add_argument('--server', '-s', required=True)
parser.add_argument('--port', '-P', type=int, default=64738)
parser.add_argument('--name', '-n', required=True)
parser.add_argument('--passwd', '-p', default="")
args = parser.parse_args()

server = args.server
nick = args.name
passwd = args.passwd
port = args.port

mumble = pymumble_py3.Mumble(server, nick, password=passwd, port=port, stereo=True)
mumble.set_receive_sound(True)
mumble.start()
mumble.is_ready()   #wait for Mumble to get ready to avoid errors after startup

while True:
    print("start Processing")
    command = ["ffmpeg", "-f", "pulse", "-i", "alsa_output.usb-SteelSeries_SteelSeries_GameDAC_000000000000-00.pro-output-0.monitor", "-f", "s16le", "-ab", "320k", "-ac", "2", "-ar", "48000",  "-"]
    sound = sp.Popen(command, stdout=sp.PIPE, stderr=sp.DEVNULL, bufsize=1024)
    print("playing")
    while True:
        raw_music = sound.stdout.read(1024)
        if not raw_music:
            break
        #mumble.sound_output.add_sound(audioop.mul(raw_music, 2, vol))   #adjusting volume
        mumble.sound_output.add_sound(raw_music)
    print("finished")
    while mumble.sound_output.get_buffer_size() > 0.5:  #
        time.sleep(0.01)
    print("sleep")
    time.sleep(2)

it does not work anymore: the bot does connect but plays no sound and doesn't appear to be playing sound. Some insights would be very helpful ! The audio card I am capturing from is stereo and is receiving stereo audio.

Thanks!

Adel

@ModellbahnFreak
Copy link

ModellbahnFreak commented Oct 18, 2023

Hi, I had the same problem and spend quite some time debugging in various places.

The trick that finally did it for me was to set the audio bandwidth using

mumble.set_bandwidth(115600)

after mumble.is_ready()
(Any value that is also a valid value in the mumble ui worked without trouble for me, I was even able to increase it further but for too high values I experienced dropouts until the Audio was gone completely)

It seems the opus encoder default bitrate is set too high for mumble to handle.

Edit:
The command above sets the total bandwidth used by tha audio stream including the overhead. The actual opus bitrate is calculated in

def _set_bandwidth(self):

Doing tha calculation backwards allows us to calculate which bandwidth we need to set for a specific opus bitrate:

  • For a UDP connection with default settings you need to add 14000b/s to your bitrate
  • For a TCP Tunneling connection, add 19600b/s

So if you need 96kb/s audio over a TCP connection, you should set the bandwidth to 115600

@AdelKS
Copy link
Author

AdelKS commented Oct 29, 2023

Oh thanks for your feedback ! I will report back as soon as I try it !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants