Add audio playback

This commit is contained in:
Correl Roush 2020-09-04 22:12:14 +01:00
parent 57cdbf8ed3
commit 08834afe21
2 changed files with 58 additions and 8 deletions

View file

@ -9,7 +9,7 @@ from typing import Any, Dict, Iterator
from dejavu import Dejavu # type: ignore
from turntable.audio import Listener
from turntable.audio import Listener, Player
from turntable.icecast import Icecast
from turntable.models import PCM
from turntable.turntable import (
@ -38,11 +38,12 @@ def run() -> "Iterator[Queue[Event]]":
pcm_in: "Queue[PCM]" = Queue()
pcm_out: "Queue[PCM]" = Queue()
events: "Queue[Event]" = Queue()
audio_config = config.get("audio", dict())
listener = Listener(
pcm_in,
[pcm_in, pcm_out],
events,
audio_config.get("device", "default"),
framerate=audio_config.get("framerate", 44100),
@ -50,9 +51,17 @@ def run() -> "Iterator[Queue[Event]]":
period_size=audio_config.get("period_size", 4096),
)
player = Player(
pcm_out,
audio_config.get("output_device", "null"),
framerate=audio_config.get("framerate", 44100),
channels=audio_config.get("channels", 2),
period_size=audio_config.get("period_size", 4096),
)
dejavu = Dejavu(config.get("dejavu", dict()))
player = Turntable(listener.framerate, listener.channels, dejavu, pcm_in, events)
turntable = Turntable(listener.framerate, listener.channels, dejavu, pcm_in, events)
icecast_config = config.get("icecast", dict())
icecast = Icecast(
@ -63,7 +72,7 @@ def run() -> "Iterator[Queue[Event]]":
password=icecast_config.get("admin_password", "hackme"),
)
processes = [listener, player]
processes = [listener, player, turntable]
for process in processes:
process.daemon = True
process.start()

View file

@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
class Listener(Process):
def __init__(
self,
pcm_in: "Queue[PCM]",
pcm_in: "List[Queue[PCM]]",
events: Queue,
device: str,
sample_length: int = 30,
@ -25,7 +25,7 @@ class Listener(Process):
period_size: int = 1024,
) -> None:
super().__init__()
logger.info("Initializing Listener")
logger.info(f"Initializing Listener using '{device}'")
self.pcm_in = pcm_in
self.events = events
self.framerate = framerate
@ -55,13 +55,54 @@ class Listener(Process):
)
def run(self) -> None:
framecount = 0
event_limit = self.framerate
while True:
length, data = self.capture.read()
if length > 0:
pcm = PCM(self.framerate, self.channels, data)
self.pcm_in.put(pcm)
self.events.put(Audio(pcm))
for queue in self.pcm_in:
queue.put(pcm)
framecount += length
if framecount >= event_limit:
framecount = 0
self.events.put(Audio(pcm))
else:
logger.warning(
"Sampler error (length={}, bytes={})".format(length, len(data))
)
class Player(Process):
def __init__(
self,
pcm_in: "Queue[PCM]",
device: str,
sample_length: int = 30,
framerate: int = 44100,
channels: int = 2,
period_size: int = 1024,
) -> None:
super().__init__()
logger.info(f"Initializing Player using '{device}'")
self.pcm_in = pcm_in
self.framerate = framerate
self.channels = channels
self.playback = alsaaudio.PCM(
device=device,
type=alsaaudio.PCM_PLAYBACK,
format=alsaaudio.PCM_FORMAT_S16_LE,
periodsize=period_size,
rate=framerate,
channels=channels,
)
logger.info(
"Player started on '%s' [rate=%d, channels=%d, periodsize=%d]",
device,
framerate,
channels,
period_size,
)
def run(self) -> None:
while pcm := self.pcm_in.get():
self.playback.write(pcm.raw)