Add playing over left, right or both channels, fixes #10

pull/14/head
Ewald de Wit 2022-09-25 12:00:26 +02:00
rodzic a17f14c6fc
commit d0c9f9a1bf
2 zmienionych plików z 22 dodań i 9 usunięć

Wyświetl plik

@ -54,10 +54,15 @@ class App(qt.QMainWindow):
if self.paused or lo >= hi or secs <= 0 or not ampl:
await asyncio.sleep(0.1)
continue
ch = self.channelsBox.currentIndex()
analyzer = hifi.Analyzer(lo, hi, secs, audio.rate, ampl,
self.calibration, self.target)
audio.play(analyzer.chirp)
sound = analyzer.chirp
if ch:
silence = np.zeros_like(sound)
sound = [sound, silence] if ch == 1 else [silence, sound]
audio.play(sound)
async for recording in audio.record():
if self.paused:
audio.cancelPlay()
@ -199,6 +204,8 @@ class App(qt.QMainWindow):
value=1.0, step=0.1, bounds=[0.1, 30], suffix='s')
self.ampl = pg.SpinBox(
value=40, step=1, bounds=[0, 100], suffix='%')
self.channelsBox = qt.QComboBox()
self.channelsBox.addItems(['Stereo', 'Left', 'Right'])
self.spectrumSmoothing = pg.SpinBox(
value=15, step=1, bounds=[0, 30])
self.spectrumSmoothing.sigValueChanging.connect(self.plot)
@ -216,6 +223,7 @@ class App(qt.QMainWindow):
hbox.addSpacing(32)
hbox.addWidget(qt.QLabel('Amplitude: '))
hbox.addWidget(self.ampl)
hbox.addWidget(self.channelsBox)
hbox.addSpacing(32)
hbox.addWidget(qt.QLabel('Smoothing: '))
hbox.addWidget(self.spectrumSmoothing)

Wyświetl plik

@ -5,6 +5,7 @@ from typing import AsyncIterator, Deque
import eventkit as ev
import numpy as np
import numpy.typing as npt
import sounddevice as sd
@ -21,7 +22,7 @@ class Audio:
self.recorded = ev.Event()
self.playQ: Deque[PlayItem] = deque()
self.stream = sd.Stream(
channels=1,
channels=2,
callback=self._onStream)
self.stream.start()
self.rate = self.stream.samplerate
@ -42,16 +43,19 @@ class Audio:
idx = 0
while self.playQ and idx < frames:
playItem = self.playQ[0]
chunk = playItem.pop(frames - idx)
idx2 = idx + chunk.size
out_data[idx:idx2, 0] = chunk
chunk = playItem.pop(frames - idx).T
idx2 = idx + len(chunk)
out_data[idx:idx2, :] = chunk
idx = idx2
if not playItem.remaining():
self.playQ.popleft()
self.recorded.emit_threadsafe(in_data.copy())
self.recorded.emit_threadsafe(in_data.copy().T)
def play(self, sound: np.ndarray):
def play(self, sound: npt.ArrayLike):
"""Add a sound to the play queue."""
sound = np.asarray(sound)
if len(sound.shape) == 1:
sound = np.vstack([sound, sound])
self.playQ.append(PlayItem(sound))
def cancelPlay(self):
@ -69,7 +73,8 @@ class Audio:
"""
recording = array.array('f')
return self.recorded.map(
recording.extend).constant(recording).aiter(skip_to_last=True)
lambda rec: recording.extend(0.5 * (rec[0] + rec[1]))) \
.constant(recording).aiter(skip_to_last=True)
@dataclass
@ -82,6 +87,6 @@ class PlayItem:
def pop(self, num: int) -> np.ndarray:
idx = self.index + min(num, self.remaining())
chunk = self.sound[self.index:idx]
chunk = self.sound[:, self.index:idx]
self.index = idx
return chunk