mirror of
https://github.com/correl/turntable.git
synced 2024-12-27 11:09:53 +00:00
Add audio playback
This commit is contained in:
parent
57cdbf8ed3
commit
08834afe21
2 changed files with 58 additions and 8 deletions
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue