fixed audio rendering
This commit is contained in:
3
src/project.py
Normal file
3
src/project.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
class Project:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
@@ -9,7 +9,7 @@ from ui.widgets.project_settings import ProjectSettings
|
|||||||
class AppUI(App):
|
class AppUI(App):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.zoom_level = 0.1
|
self.zoom_level = 0.05
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Sidebar()
|
yield Sidebar()
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import librosa
|
import librosa
|
||||||
import pyloudnorm as pyln
|
import pyloudnorm as pyln
|
||||||
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from textual.containers import Vertical
|
from textual.containers import Vertical
|
||||||
from textual.widgets import Sparkline
|
|
||||||
from textual_plot import HiResMode, PlotWidget
|
from textual_plot import HiResMode, PlotWidget
|
||||||
|
|
||||||
from ui.widgets.chunk_types.chunk import Chunk
|
from ui.widgets.chunk_types.chunk import Chunk
|
||||||
@@ -14,11 +14,14 @@ from ui.widgets.chunk_types.chunk import Chunk
|
|||||||
class AudioChunk(Chunk):
|
class AudioChunk(Chunk):
|
||||||
DEFAULT_CSS = """
|
DEFAULT_CSS = """
|
||||||
AudioChunk {
|
AudioChunk {
|
||||||
align: left middle;
|
PlotWidget {
|
||||||
Sparkline {
|
height: 1fr;
|
||||||
margin: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.plot--axis {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -28,7 +31,6 @@ class AudioChunk(Chunk):
|
|||||||
self.file_path = file_path
|
self.file_path = file_path
|
||||||
self.audio, self.sample_rate = librosa.load(self.file_path, sr=None, mono=False)
|
self.audio, self.sample_rate = librosa.load(self.file_path, sr=None, mono=False)
|
||||||
|
|
||||||
|
|
||||||
self.num_channels = None
|
self.num_channels = None
|
||||||
if len(self.audio.shape) == 1:
|
if len(self.audio.shape) == 1:
|
||||||
self.num_samples = self.audio.shape[0]
|
self.num_samples = self.audio.shape[0]
|
||||||
@@ -36,7 +38,6 @@ class AudioChunk(Chunk):
|
|||||||
else:
|
else:
|
||||||
self.num_samples = self.audio.shape[1]
|
self.num_samples = self.audio.shape[1]
|
||||||
self.num_channels = self.audio.shape[0]
|
self.num_channels = self.audio.shape[0]
|
||||||
self.notify(str(self.num_samples))
|
|
||||||
|
|
||||||
self.meter = pyln.Meter(self.sample_rate)
|
self.meter = pyln.Meter(self.sample_rate)
|
||||||
self.loudness_values = []
|
self.loudness_values = []
|
||||||
@@ -49,6 +50,50 @@ class AudioChunk(Chunk):
|
|||||||
plot.margin_left = 0
|
plot.margin_left = 0
|
||||||
plot.margin_bottom = 0
|
plot.margin_bottom = 0
|
||||||
|
|
||||||
|
num_values = len(list(range(0, int(self.num_samples), int(self.sample_rate * 0.05))))
|
||||||
|
x = range(num_values)
|
||||||
|
|
||||||
|
y = []
|
||||||
|
if self.num_channels == 1:
|
||||||
|
# get rms
|
||||||
|
rms = librosa.feature.rms(y=self.audio)[0]
|
||||||
|
|
||||||
|
# split into N chunks
|
||||||
|
rms = np.array([
|
||||||
|
np.mean(chunk) if len(chunk) > 0 else 0.0
|
||||||
|
for chunk in np.array_split(rms, num_values)
|
||||||
|
])
|
||||||
|
|
||||||
|
# get the decibel values from that
|
||||||
|
y = list(librosa.amplitude_to_db(rms, ref=np.min))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# get rms
|
||||||
|
rms = librosa.feature.rms(y=self.audio[int(plot.id[-1])])[0]
|
||||||
|
|
||||||
|
# split into N chunks
|
||||||
|
rms = np.array([
|
||||||
|
np.mean(chunk) if len(chunk) > 0 else 0.0
|
||||||
|
for chunk in np.array_split(rms, num_values)
|
||||||
|
])
|
||||||
|
|
||||||
|
# get the decibel values from that
|
||||||
|
y = librosa.amplitude_to_db(rms, ref=np.min)
|
||||||
|
|
||||||
|
|
||||||
|
plot.bar(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
1.0,
|
||||||
|
bar_style=self.app.theme_variables["primary"],
|
||||||
|
hires_mode=HiResMode.HALFBLOCK
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
plot.set_xticks([])
|
||||||
|
plot.set_yticks([])
|
||||||
|
plot.set_ylimits(ymin=0)
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
|
|
||||||
|
|
||||||
@@ -57,19 +102,23 @@ class AudioChunk(Chunk):
|
|||||||
# loop over each channel in the audio and display it seperately
|
# loop over each channel in the audio and display it seperately
|
||||||
for channel in range(self.num_channels):
|
for channel in range(self.num_channels):
|
||||||
|
|
||||||
samples = []
|
"""samples = []
|
||||||
|
|
||||||
for sample in range(0, self.num_samples, int(self.sample_rate*0.1)):
|
for sample in range(0, self.num_samples, int(self.sample_rate*0.1)):
|
||||||
samples.append(self.audio[channel, sample])
|
samples.append(self.audio[channel, sample])"""
|
||||||
|
|
||||||
yield Sparkline(data=samples)
|
yield PlotWidget(allow_pan_and_zoom=False, id=f"channel-{channel}")
|
||||||
|
|
||||||
|
#yield Sparkline(data=samples)
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# just display the one channel
|
# just display the one channel
|
||||||
samples = []
|
"""samples = []
|
||||||
|
|
||||||
for sample in range(0, self.num_samples, int(self.sample_rate*0.1)):
|
for sample in range(0, self.num_samples, int(self.sample_rate*0.1)):
|
||||||
samples.append(self.audio[sample])
|
samples.append(self.audio[sample])"""
|
||||||
|
|
||||||
yield Sparkline(data=samples)
|
yield PlotWidget(allow_pan_and_zoom=False)
|
||||||
|
|
||||||
|
#yield Sparkline(data=samples)
|
||||||
Reference in New Issue
Block a user