mirror of
https://github.com/markqvist/LXST.git
synced 2026-04-27 14:20:39 +00:00
Added audio backends for Windows and macOS
This commit is contained in:
parent
a69c9c676c
commit
cf476cacfb
35 changed files with 182 additions and 5 deletions
50
LXST/Codecs/libs/pyogg/libs/macos/README
Normal file
50
LXST/Codecs/libs/pyogg/libs/macos/README
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
The shared libraries for macOS were obtained by first
|
||||
installing/compiling the standard libraries using Homebrew:
|
||||
|
||||
brew install libogg opus opusfile libopusenc libvorbis flac
|
||||
|
||||
These libraries were then copied into this directory. However a
|
||||
number of the libraries were looking for eachother internally.
|
||||
|
||||
The paths the libraries are currently expecting can be seen by
|
||||
executing the command:
|
||||
|
||||
otool -L *.dylib
|
||||
|
||||
This shows, for example:
|
||||
|
||||
libopusfile.0.dylib:
|
||||
/usr/local/opt/opusfile/lib/libopusfile.0.dylib (compatibility version 5.0.0, current version 5.5.0)
|
||||
/usr/local/opt/libogg/lib/libogg.0.dylib (compatibility version 9.0.0, current version 9.4.0)
|
||||
/usr/local/opt/opus/lib/libopus.0.dylib (compatibility version 9.0.0, current version 9.0.0)
|
||||
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
|
||||
|
||||
Note the hard-coded location to libogg and libopus. These files are
|
||||
included with the PyOgg distribution, but not at those locations.
|
||||
|
||||
To fix the expected paths, we ran the following commands:
|
||||
|
||||
install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libFLAC.8.dylib
|
||||
install_name_tool -change /usr/local/opt/opus/lib/libopus.0.dylib @loader_path/libopus.0.dylib libopusenc.0.dylib
|
||||
install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libopusfile.0.dylib
|
||||
install_name_tool -change /usr/local/opt/opus/lib/libopus.0.dylib @loader_path/libopus.0.dylib libopusfile.0.dylib
|
||||
install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libvorbis.0.dylib
|
||||
install_name_tool -change /usr/local/Cellar/libvorbis/1.3.7/lib/libvorbis.0.dylib @loader_path/libvorbis.0.dylib libvorbisenc.2.dylib
|
||||
install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libvorbisenc.2.dylib
|
||||
install_name_tool -change /usr/local/Cellar/libvorbis/1.3.7/lib/libvorbis.0.dylib @loader_path/libvorbis.0.dylib libvorbisfile.3.dylib
|
||||
install_name_tool -change /usr/local/opt/libogg/lib/libogg.0.dylib @loader_path/libogg.0.dylib libvorbisfile.3.dylib
|
||||
|
||||
After changing the locations of the paths, we can rerun:
|
||||
|
||||
otool -L *.dylib
|
||||
|
||||
Which shows, in the case of libopusfile:
|
||||
|
||||
libopusfile.0.dylib:
|
||||
/usr/local/opt/opusfile/lib/libopusfile.0.dylib (compatibility version 5.0.0, current version 5.5.0)
|
||||
@loader_path/libogg.0.dylib (compatibility version 9.0.0, current version 9.4.0)
|
||||
@loader_path/libopus.0.dylib (compatibility version 9.0.0, current version 9.0.0)
|
||||
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
|
||||
|
||||
These relative paths mean the libraries will be found within the PyOgg
|
||||
package.
|
||||
BIN
LXST/Codecs/libs/pyogg/libs/macos/libFLAC.8.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libFLAC.8.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libogg.0.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libogg.0.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopus.0.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopus.0.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopusenc.0.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopusenc.0.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopusfile.0.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libopusfile.0.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbis.0.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbis.0.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbisenc.2.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbisenc.2.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbisfile.3.dylib
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/macos/libvorbisfile.3.dylib
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/libFLAC.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/libFLAC.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/libcrypto-1_1.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/libcrypto-1_1.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/libssl-1_1.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/libssl-1_1.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/libvorbis.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/libvorbis.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/libvorbisfile.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/libvorbisfile.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/ogg.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/ogg.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/opus.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/opus.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/opusenc.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/opusenc.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win32/opusfile.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win32/opusfile.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libFLAC.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libFLAC.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libcrypto-1_1-x64.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libcrypto-1_1-x64.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libssl-1_1-x64.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libssl-1_1-x64.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libvorbis.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libvorbis.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libvorbisfile.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/libvorbisfile.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/ogg.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/ogg.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opus.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opus.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opusenc.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opusenc.dll
Normal file
Binary file not shown.
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opusfile.dll
Normal file
BIN
LXST/Codecs/libs/pyogg/libs/win_amd64/opusfile.dll
Normal file
Binary file not shown.
|
|
@ -23,9 +23,61 @@ class LinuxBackend():
|
|||
def get_player(self, samples_per_frame=None):
|
||||
return self.device.player(samplerate=self.samplerate, blocksize=samples_per_frame)
|
||||
|
||||
def release_player(self): pass
|
||||
|
||||
class DarwinBackend():
|
||||
SAMPLERATE = 48000
|
||||
|
||||
def __init__(self, preferred_device=None, samplerate=SAMPLERATE):
|
||||
import soundcard
|
||||
self.samplerate = samplerate
|
||||
self.soundcard = soundcard
|
||||
if preferred_device:
|
||||
try: self.device = self.soundcard.get_speaker(preferred_device)
|
||||
except: self.device = soundcard.default_speaker()
|
||||
else: self.device = soundcard.default_speaker()
|
||||
RNS.log(f"Using output device {self.device}", RNS.LOG_DEBUG)
|
||||
|
||||
def flush(self):
|
||||
self.recorder.flush()
|
||||
|
||||
def get_player(self, samples_per_frame=None):
|
||||
return self.device.player(samplerate=self.samplerate, blocksize=samples_per_frame)
|
||||
|
||||
def release_player(self): pass
|
||||
|
||||
class WindowsBackend():
|
||||
SAMPLERATE = 48000
|
||||
|
||||
def __init__(self, preferred_device=None, samplerate=SAMPLERATE):
|
||||
import soundcard
|
||||
from pythoncom import CoInitializeEx, CoUninitialize
|
||||
self.com_init = CoInitializeEx
|
||||
self.com_release = CoUninitialize
|
||||
self.samplerate = samplerate
|
||||
self.soundcard = soundcard
|
||||
if preferred_device:
|
||||
try: self.device = self.soundcard.get_speaker(preferred_device)
|
||||
except: self.device = soundcard.default_speaker()
|
||||
else: self.device = soundcard.default_speaker()
|
||||
RNS.log(f"Using output device {self.device}", RNS.LOG_DEBUG)
|
||||
|
||||
def flush(self):
|
||||
self.recorder.flush()
|
||||
|
||||
def get_player(self, samples_per_frame=None):
|
||||
self.com_init(0)
|
||||
return self.device.player(samplerate=self.samplerate, blocksize=samples_per_frame)
|
||||
|
||||
def release_player(self): self.com_release()
|
||||
|
||||
def get_backend():
|
||||
if RNS.vendor.platformutils.is_linux():
|
||||
return LinuxBackend
|
||||
elif RNS.vendor.platformutils.is_windows():
|
||||
return WindowsBackend
|
||||
elif RNS.vendor.platformutils.is_darwin():
|
||||
return DarwinBackend
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
@ -132,5 +184,7 @@ class LineSink(LocalSink):
|
|||
else:
|
||||
time.sleep(self.frame_time*0.1)
|
||||
|
||||
self.backend.release_player()
|
||||
|
||||
class PacketSink(RemoteSink):
|
||||
pass
|
||||
BIN
LXST/Sounds/ringer.opus
Normal file
BIN
LXST/Sounds/ringer.opus
Normal file
Binary file not shown.
BIN
LXST/Sounds/soft.opus
Normal file
BIN
LXST/Sounds/soft.opus
Normal file
Binary file not shown.
|
|
@ -32,9 +32,65 @@ class LinuxBackend():
|
|||
def get_recorder(self, samples_per_frame):
|
||||
return self.device.recorder(samplerate=self.SAMPLERATE, blocksize=samples_per_frame)
|
||||
|
||||
def release_recorder(self): pass
|
||||
|
||||
class DarwinBackend():
|
||||
SAMPLERATE = 48000
|
||||
|
||||
def __init__(self, preferred_device=None, samplerate=SAMPLERATE):
|
||||
import soundcard
|
||||
self.samplerate = samplerate
|
||||
self.soundcard = soundcard
|
||||
if preferred_device:
|
||||
try: self.device = self.soundcard.get_microphone(preferred_device)
|
||||
except: self.device = self.soundcard.default_microphone()
|
||||
else: self.device = self.soundcard.default_microphone()
|
||||
self.channels = self.device.channels
|
||||
self.bitdepth = 32
|
||||
RNS.log(f"Using input device {self.device}", RNS.LOG_DEBUG)
|
||||
|
||||
def flush(self):
|
||||
self.recorder.flush()
|
||||
|
||||
def get_recorder(self, samples_per_frame):
|
||||
return self.device.recorder(samplerate=self.SAMPLERATE, blocksize=samples_per_frame)
|
||||
|
||||
def release_recorder(self): pass
|
||||
|
||||
class WindowsBackend():
|
||||
SAMPLERATE = 48000
|
||||
|
||||
def __init__(self, preferred_device=None, samplerate=SAMPLERATE):
|
||||
import soundcard
|
||||
from pythoncom import CoInitializeEx, CoUninitialize
|
||||
self.com_init = CoInitializeEx
|
||||
self.com_release = CoUninitialize
|
||||
self.samplerate = samplerate
|
||||
self.soundcard = soundcard
|
||||
if preferred_device:
|
||||
try: self.device = self.soundcard.get_microphone(preferred_device)
|
||||
except: self.device = self.soundcard.default_microphone()
|
||||
else: self.device = self.soundcard.default_microphone()
|
||||
self.channels = self.device.channels
|
||||
self.bitdepth = 32
|
||||
RNS.log(f"Using input device {self.device}", RNS.LOG_DEBUG)
|
||||
|
||||
def flush(self):
|
||||
self.recorder.flush()
|
||||
|
||||
def get_recorder(self, samples_per_frame):
|
||||
self.com_init(0)
|
||||
return self.device.recorder(samplerate=self.SAMPLERATE, blocksize=samples_per_frame)
|
||||
|
||||
def release_recorder(self): self.com_release()
|
||||
|
||||
def get_backend():
|
||||
if RNS.vendor.platformutils.is_linux():
|
||||
return LinuxBackend
|
||||
elif RNS.vendor.platformutils.is_windows():
|
||||
return WindowsBackend
|
||||
elif RNS.vendor.platformutils.is_darwin():
|
||||
return DarwinBackend
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,16 @@ class ReticulumTelephone():
|
|||
|
||||
if not os.path.isdir(self.storagedir):
|
||||
os.makedirs(self.storagedir)
|
||||
ringer_tones = ["ringer.opus", "soft.opus"]
|
||||
sounds_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Sounds"))
|
||||
if os.path.isdir(sounds_path):
|
||||
import shutil
|
||||
for filename in ringer_tones:
|
||||
src_path = os.path.join(sounds_path, filename)
|
||||
dst_path = os.path.join(self.configdir, filename)
|
||||
if os.path.isfile(src_path):
|
||||
RNS.log(f"Copying {src_path} to {dst_path}")
|
||||
shutil.copy(src_path, dst_path)
|
||||
|
||||
if not os.path.isfile(self.configpath):
|
||||
self.create_default_config()
|
||||
|
|
@ -691,7 +701,7 @@ __default_rnphone_config__ = """# This is an example rnphone config file.
|
|||
# phone is ringing. Must be in OPUS format, and
|
||||
# located in the rnphone config directory.
|
||||
|
||||
ringtone = ringtone.opus
|
||||
ringtone = ringer.opus
|
||||
|
||||
# You can define the preferred audio devices
|
||||
# to use as the speaker output, ringer output
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "0.2.4"
|
||||
__version__ = "0.2.5"
|
||||
|
|
@ -36,7 +36,7 @@ LXST uses encryption provided by [Reticulum](https://reticulum.network), and thu
|
|||
|
||||
## Project Status & License
|
||||
|
||||
This software is in a very early alpha state, and will change rapidly with ongoing development. Consider no APIs stable. Consider everything explosive.
|
||||
This software is in a very early alpha state, and will change rapidly with ongoing development. Consider no APIs stable. Consider everything explosive. Not all features are implemented. Nothing is documented. For a fully functional LXST program, take a look at the included `rnphone` program, which provides telephony service over Reticulum. Everything else will currently be a voyage of your own making.
|
||||
|
||||
While under early development, the project is kept under a `CC BY-NC-ND 4.0` license.
|
||||
|
||||
|
|
|
|||
11
setup.py
11
setup.py
|
|
@ -10,8 +10,14 @@ packages.append("LXST.Utilities")
|
|||
packages.append("LXST.Primitives.hardware")
|
||||
packages.append("LXST.Codecs.libs.pydub")
|
||||
packages.append("LXST.Codecs.libs.pyogg")
|
||||
print("Packages:")
|
||||
print(packages)
|
||||
|
||||
package_data = {
|
||||
"": [
|
||||
"Codecs/libs/pyogg/libs/win_amd64/*",
|
||||
"Codecs/libs/pyogg/libs/macos/*",
|
||||
"Sounds/*",
|
||||
]
|
||||
}
|
||||
|
||||
setuptools.setup(
|
||||
name="lxst",
|
||||
|
|
@ -23,6 +29,7 @@ setuptools.setup(
|
|||
long_description_content_type="text/markdown",
|
||||
url="https://git.unsigned.io/markqvist/lxst",
|
||||
packages=packages,
|
||||
package_data=package_data,
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: Other/Proprietary License",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue