sound fixes
This commit is contained in:
parent
31bed51455
commit
ac6999924f
32 changed files with 765 additions and 113 deletions
|
@ -3,9 +3,9 @@ import time
|
|||
import threading
|
||||
import itertools
|
||||
|
||||
from tox_wrapper.toxav_enums import *
|
||||
from tox_wrapper.tests import support_testing as ts
|
||||
from tox_wrapper.tests.support_testing import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE
|
||||
from toxygen_wrapper.toxav_enums import *
|
||||
from toxygen_wrapper.tests import support_testing as ts
|
||||
from toxygen_wrapper.tests.support_testing import LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG, LOG_TRACE
|
||||
|
||||
with ts.ignoreStderr():
|
||||
import pyaudio
|
||||
|
@ -14,7 +14,7 @@ from av.call import Call
|
|||
import common.tox_save
|
||||
|
||||
from utils import ui as util_ui
|
||||
import tox_wrapper.tests.support_testing as ts
|
||||
import toxygen_wrapper.tests.support_testing as ts
|
||||
from middleware.threads import invoke_in_main_thread
|
||||
from middleware.threads import BaseThread
|
||||
|
||||
|
@ -38,10 +38,10 @@ class AV(common.tox_save.ToxAvSave):
|
|||
s = settings
|
||||
if 'video' not in s:
|
||||
LOG.warn("AV.__init__ 'video' not in s" )
|
||||
LOG.debug(f"AV.__init__ {s!r}" )
|
||||
LOG.debug(f"AV.__init__ {s}" )
|
||||
elif 'device' not in s['video']:
|
||||
LOG.warn("AV.__init__ 'device' not in s.video" )
|
||||
LOG.debug(f"AV.__init__ {s['video']!r}" )
|
||||
LOG.debug(f"AV.__init__ {s['video']}" )
|
||||
|
||||
self._calls = {} # dict: key - friend number, value - Call instance
|
||||
|
||||
|
@ -71,12 +71,15 @@ class AV(common.tox_save.ToxAvSave):
|
|||
# was iOutput = self._settings._args.audio['output']
|
||||
iInput = self._settings['audio']['input']
|
||||
self.lPaSampleratesI = ts.lSdSamplerates(iInput)
|
||||
if not self.lPaSampleratesI: LOG.warn(f"empty self.lPaSampleratesI iInput={iInput}")
|
||||
iOutput = self._settings['audio']['output']
|
||||
self.lPaSampleratesO = ts.lSdSamplerates(iOutput)
|
||||
if not self.lPaSampleratesO: LOG.warn(f"empty self.lPaSampleratesO iOutput={iOutput}")
|
||||
global oPYA
|
||||
oPYA = self._audio = pyaudio.PyAudio()
|
||||
|
||||
def stop(self):
|
||||
LOG_DEBUG(f"AV.CA stop {self._video_thread}")
|
||||
self._running = False
|
||||
self.stop_audio_thread()
|
||||
self.stop_video_thread()
|
||||
|
@ -126,8 +129,7 @@ class AV(common.tox_save.ToxAvSave):
|
|||
self._audio_krate_tox_audio if audio_enabled else 0,
|
||||
self._audio_krate_tox_video if video_enabled else 0)
|
||||
except Exception as e:
|
||||
LOG.debug(f"AV accept_call error from {friend_number} {self._running}" +
|
||||
f"{e}")
|
||||
LOG.debug(f"AV accept_call error from {friend_number} {self._running} {e}")
|
||||
raise
|
||||
if audio_enabled:
|
||||
# may raise
|
||||
|
@ -194,26 +196,34 @@ class AV(common.tox_save.ToxAvSave):
|
|||
LOG_WARN(f"start_audio_thread device={iInput}")
|
||||
return
|
||||
LOG_DEBUG(f"start_audio_thread device={iInput}")
|
||||
lPaSamplerates = ts.lSdSamplerates(iInput)
|
||||
lPaSamplerates = ts.lSdSamplerates(iInput)
|
||||
if not(len(lPaSamplerates)):
|
||||
e = f"No supported sample rates for device: audio[input]={iInput!r}"
|
||||
e = f"No sample rates for device: audio[input]={iInput}"
|
||||
LOG_ERROR(f"start_audio_thread {e}")
|
||||
#?? dunno - cancel call?
|
||||
return
|
||||
if not self._audio_rate_pa in lPaSamplerates:
|
||||
LOG_WARN(f"{self._audio_rate_pa} not in {lPaSamplerates!r}")
|
||||
if False:
|
||||
self._audio_rate_pa = oPYA.get_device_info_by_index(iInput)['defaultSampleRate']
|
||||
else:
|
||||
LOG_WARN(f"Setting audio_rate to: {lPaSamplerates[0]}")
|
||||
self._audio_rate_pa = lPaSamplerates[0]
|
||||
|
||||
#?? dunno - cancel call? - no let the user do it
|
||||
# return
|
||||
# just guessing here in case that's a false negative
|
||||
lPaSamplerates = [round(oPYA.get_device_info_by_index(iInput)['defaultSampleRate'])]
|
||||
if lPaSamplerates and self._audio_rate_pa in lPaSamplerates:
|
||||
pass
|
||||
elif lPaSamplerates:
|
||||
LOG_WARN(f"{self._audio_rate_pa} not in {lPaSamplerates}")
|
||||
self._audio_rate_pa = lPaSamplerates[0]
|
||||
LOG_WARN(f"Setting audio_rate to: {lPaSamplerates[0]}")
|
||||
elif 'defaultSampleRate' in oPYA.get_device_info_by_index(iInput):
|
||||
self._audio_rate_pa = oPYA.get_device_info_by_index(iInput)['defaultSampleRate']
|
||||
else:
|
||||
LOG_WARN(f"{self._audio_rate_pa} not in {lPaSamplerates}")
|
||||
# a float is in here - must it be int?
|
||||
if type(self._audio_rate_pa) == float:
|
||||
self._audio_rate_pa = round(self._audio_rate_pa)
|
||||
try:
|
||||
LOG_DEBUG( f"start_audio_thread framerate: {self._audio_rate_pa}" \
|
||||
+f" device: {iInput}"
|
||||
+f" supported: {lPaSamplerates!r}")
|
||||
+f" supported: {lPaSamplerates}")
|
||||
if self._audio_rate_pa not in lPaSamplerates:
|
||||
LOG_WARN(f"PAudio sampling rate was {self._audio_rate_pa} changed to {lPaSamplerates[0]}")
|
||||
LOG_DEBUG(f"lPaSamplerates={lPaSamplerates}")
|
||||
self._audio_rate_pa = lPaSamplerates[0]
|
||||
|
||||
if bSTREAM_CALLBACK:
|
||||
|
@ -256,9 +266,10 @@ class AV(common.tox_save.ToxAvSave):
|
|||
# raise RuntimeError(e)
|
||||
return
|
||||
else:
|
||||
LOG_DEBUG(f"start_audio_thread {self._audio_stream!r}")
|
||||
LOG_DEBUG(f"start_audio_thread {self._audio_stream}")
|
||||
|
||||
def stop_audio_thread(self):
|
||||
LOG_DEBUG(f"stop_audio_thread {self._audio_stream}")
|
||||
|
||||
if self._audio_thread is None:
|
||||
return
|
||||
|
@ -279,11 +290,11 @@ class AV(common.tox_save.ToxAvSave):
|
|||
s = self._settings
|
||||
if 'video' not in s:
|
||||
LOG.warn("AV.__init__ 'video' not in s" )
|
||||
LOG.debug(f"start_video_thread {s!r}" )
|
||||
LOG.debug(f"start_video_thread {s}" )
|
||||
raise RuntimeError("start_video_thread not 'video' in s)" )
|
||||
elif 'device' not in s['video']:
|
||||
LOG.error("start_video_thread not 'device' in s['video']" )
|
||||
LOG.debug(f"start_video_thread {s['video']!r}" )
|
||||
LOG.debug(f"start_video_thread {s['video']}" )
|
||||
raise RuntimeError("start_video_thread not 'device' ins s['video']" )
|
||||
self._video_width = s['video']['width']
|
||||
self._video_height = s['video']['height']
|
||||
|
@ -321,6 +332,7 @@ class AV(common.tox_save.ToxAvSave):
|
|||
self._video_thread.start()
|
||||
|
||||
def stop_video_thread(self) -> None:
|
||||
LOG_DEBUG(f"stop_video_thread {self._video_thread}")
|
||||
if self._video_thread is None:
|
||||
return
|
||||
|
||||
|
@ -331,7 +343,6 @@ class AV(common.tox_save.ToxAvSave):
|
|||
try:
|
||||
if not self._video_thread.is_alive(): break
|
||||
except:
|
||||
# AttributeError: 'NoneType' object has no attribute 'join'
|
||||
break
|
||||
i = i + 1
|
||||
else:
|
||||
|
@ -349,12 +360,20 @@ class AV(common.tox_save.ToxAvSave):
|
|||
if self._out_stream is None:
|
||||
# was iOutput = self._settings._args.audio['output']
|
||||
iOutput = self._settings['audio']['output']
|
||||
if not rate in self.lPaSampleratesO:
|
||||
LOG.warn(f"{rate} not in {self.lPaSampleratesO!r}")
|
||||
if False:
|
||||
rate = oPYA.get_device_info_by_index(iOutput)['defaultSampleRate']
|
||||
if self.lPaSampleratesO and rate in self.lPaSampleratesO:
|
||||
pass
|
||||
elif self.lPaSampleratesO:
|
||||
LOG.warn(f"{rate} not in {self.lPaSampleratesO}")
|
||||
LOG.warn(f"Setting audio_rate to: {self.lPaSampleratesO[0]}")
|
||||
rate = self.lPaSampleratesO[0]
|
||||
elif 'defaultSampleRate' in oPYA.get_device_info_by_index(iOutput):
|
||||
rate = round(oPYA.get_device_info_by_index(iOutput)['defaultSampleRate'])
|
||||
LOG.warn(f"Setting rate to {rate} empty self.lPaSampleratesO")
|
||||
else:
|
||||
LOG.warn(f"Using rate {rate} empty self.lPaSampleratesO")
|
||||
if type(rate) == float:
|
||||
rate = round(rate)
|
||||
|
||||
try:
|
||||
with ts.ignoreStderr():
|
||||
self._out_stream = oPYA.open(format=pyaudio.paInt16,
|
||||
|
@ -372,7 +391,7 @@ class AV(common.tox_save.ToxAvSave):
|
|||
return
|
||||
|
||||
iOutput = self._settings['audio']['output']
|
||||
LOG.debug(f"audio_chunk output_device_index={iOutput} rate={rate} channels={channels_count}")
|
||||
#trace LOG.debug(f"audio_chunk output_device_index={iOutput} rate={rate} channels={channels_count}")
|
||||
self._out_stream.write(samples)
|
||||
|
||||
# AV sending
|
||||
|
@ -389,7 +408,6 @@ class AV(common.tox_save.ToxAvSave):
|
|||
for friend_num in self._calls:
|
||||
if self._calls[friend_num].out_audio:
|
||||
try:
|
||||
# app.av.calls ERROR Error send_audio: One of the frame parameters was invalid. E.g. the resolution may be too small or too large, or the audio sampling rate may be unsupported
|
||||
# app.av.calls ERROR Error send_audio audio_send_frame: This client is currently not in a call with the friend.
|
||||
self._toxav.audio_send_frame(friend_num,
|
||||
pcm,
|
||||
|
@ -402,7 +420,8 @@ class AV(common.tox_save.ToxAvSave):
|
|||
# invoke_in_main_thread(util_ui.message_box,
|
||||
# str(e),
|
||||
# util_ui.tr("Error send_audio audio_send_frame"))
|
||||
pass
|
||||
# raise #? stop ? endcall?
|
||||
self.stop_audio_thread()
|
||||
|
||||
def send_audio(self) -> None:
|
||||
"""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue