mirror of
https://github.com/romanz/amodem.git
synced 2026-04-21 05:36:42 +08:00
audio: use specified config
This commit is contained in:
@@ -55,7 +55,7 @@ def main():
|
|||||||
'Fs={3:.1f} kHz')
|
'Fs={3:.1f} kHz')
|
||||||
description = fmt.format(config.modem_bps / 1e3, len(config.symbols),
|
description = fmt.format(config.modem_bps / 1e3, len(config.symbols),
|
||||||
config.Nfreq, config.Fs / 1e3)
|
config.Nfreq, config.Fs / 1e3)
|
||||||
interface = audio.Library('libportaudio.so')
|
interface = audio.Interface('libportaudio.so', config=config)
|
||||||
|
|
||||||
p = argparse.ArgumentParser(description=description)
|
p = argparse.ArgumentParser(description=description)
|
||||||
subparsers = p.add_subparsers()
|
subparsers = p.add_subparsers()
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import logging
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Library(object):
|
class Interface(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name, config):
|
||||||
self.lib = ctypes.CDLL(name)
|
self.lib = ctypes.CDLL(name)
|
||||||
|
self.config = config
|
||||||
self.streams = []
|
self.streams = []
|
||||||
assert self._error_string(0) == 'Success'
|
assert self._error_string(0) == 'Success'
|
||||||
|
|
||||||
@@ -32,10 +33,10 @@ class Library(object):
|
|||||||
self.call('Terminate')
|
self.call('Terminate')
|
||||||
|
|
||||||
def recorder(self):
|
def recorder(self):
|
||||||
return Stream(self, read=True)
|
return Stream(lib=self, config=self.config, read=True)
|
||||||
|
|
||||||
def player(self):
|
def player(self):
|
||||||
return Stream(self, write=True)
|
return Stream(lib=self, config=self.config, write=True)
|
||||||
|
|
||||||
|
|
||||||
class Stream(object):
|
class Stream(object):
|
||||||
@@ -46,29 +47,23 @@ class Stream(object):
|
|||||||
('channelCount', ctypes.c_int),
|
('channelCount', ctypes.c_int),
|
||||||
('sampleFormat', ctypes.c_ulong),
|
('sampleFormat', ctypes.c_ulong),
|
||||||
('suggestedLatency', ctypes.c_double),
|
('suggestedLatency', ctypes.c_double),
|
||||||
('hostApiSpecificStreamInfo', ctypes.POINTER(None)),
|
('hostApiSpecificStreamInfo', ctypes.POINTER(None))
|
||||||
]
|
]
|
||||||
|
|
||||||
sample_rate = 32000.0
|
def __init__(self, lib, config, read=False, write=False):
|
||||||
frames_per_buffer = 4096
|
|
||||||
suggested_latency = 0.1
|
|
||||||
channel_count = 1
|
|
||||||
sample_format = 0x00000008 # 16-bit samples (paInt16)
|
|
||||||
bytes_per_sample = 2
|
|
||||||
flags = 0 # no flags (paNoFlag)
|
|
||||||
|
|
||||||
def __init__(self, lib, read=False, write=False):
|
|
||||||
self.lib = lib
|
self.lib = lib
|
||||||
self.stream = ctypes.POINTER(ctypes.c_void_p)()
|
self.stream = ctypes.POINTER(ctypes.c_void_p)()
|
||||||
self.user_data = ctypes.c_void_p(None)
|
self.user_data = ctypes.c_void_p(None)
|
||||||
self.stream_callback = ctypes.c_void_p(None)
|
self.stream_callback = ctypes.c_void_p(None)
|
||||||
|
self.bytes_per_sample = config.sample_size
|
||||||
|
assert config.bits_per_sample == 16 # just to make sure :)
|
||||||
|
|
||||||
index = lib.call('GetDefaultInputDevice', restype=ctypes.c_int)
|
index = lib.call('GetDefaultInputDevice', restype=ctypes.c_int)
|
||||||
self.params = Stream.Parameters(
|
self.params = Stream.Parameters(
|
||||||
device=index,
|
device=index, # choose default device
|
||||||
channelCount=self.channel_count,
|
channelCount=1, # mono audio
|
||||||
sampleFormat=self.sample_format,
|
sampleFormat=0x00000008, # 16-bit samples (paInt16)
|
||||||
suggestedLatency=self.suggested_latency,
|
suggestedLatency=0.1, # 100ms should be good enough
|
||||||
hostApiSpecificStreamInfo=None)
|
hostApiSpecificStreamInfo=None)
|
||||||
|
|
||||||
self.lib.call(
|
self.lib.call(
|
||||||
@@ -76,9 +71,9 @@ class Stream(object):
|
|||||||
ctypes.byref(self.stream),
|
ctypes.byref(self.stream),
|
||||||
ctypes.byref(self.params) if read else None,
|
ctypes.byref(self.params) if read else None,
|
||||||
ctypes.byref(self.params) if write else None,
|
ctypes.byref(self.params) if write else None,
|
||||||
ctypes.c_double(self.sample_rate),
|
ctypes.c_double(config.Fs),
|
||||||
ctypes.c_ulong(self.frames_per_buffer),
|
ctypes.c_ulong(config.samples_per_buffer),
|
||||||
ctypes.c_ulong(self.flags),
|
ctypes.c_ulong(0), # no flags (paNoFlag)
|
||||||
self.stream_callback,
|
self.stream_callback,
|
||||||
self.user_data)
|
self.user_data)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class Configuration(object):
|
|||||||
# audio config
|
# audio config
|
||||||
bits_per_sample = 16
|
bits_per_sample = 16
|
||||||
sample_size = bits_per_sample // 8
|
sample_size = bits_per_sample // 8
|
||||||
samples_per_buffer = 1024
|
samples_per_buffer = 4096
|
||||||
|
|
||||||
# sender config
|
# sender config
|
||||||
silence_start = 1.0
|
silence_start = 1.0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from amodem import audio
|
from amodem import audio, config
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
@@ -13,7 +13,7 @@ def test():
|
|||||||
lib.Pa_GetDefaultInputDevice.return_value = 1
|
lib.Pa_GetDefaultInputDevice.return_value = 1
|
||||||
lib.Pa_OpenStream.return_value = 0
|
lib.Pa_OpenStream.return_value = 0
|
||||||
cdll.return_value = lib
|
cdll.return_value = lib
|
||||||
interface = audio.Library('portaudio')
|
interface = audio.Interface(name='portaudio', config=config.fastest())
|
||||||
with interface:
|
with interface:
|
||||||
s = interface.player()
|
s = interface.player()
|
||||||
s.stream = 1 # simulate non-zero output stream handle
|
s.stream = 1 # simulate non-zero output stream handle
|
||||||
|
|||||||
Reference in New Issue
Block a user