Skip to content

Commit

Permalink
Prevent audio speeding up when trimming (#7599)
Browse files Browse the repository at this point in the history
* fix trim region background colour and change showRedo -> show_redo

* tweak audio sampling logic

* add changeset

* add trim_region_color to py docs

* formatting

* use trim_region_color for trim border

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
  • Loading branch information
hannahblair and gradio-pr-bot committed Mar 5, 2024
1 parent 82263ed commit f26aba0
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changeset/solid-grapes-reply.md
@@ -0,0 +1,6 @@
---
"@gradio/audio": patch
"gradio": patch
---

fix:Prevent audio speeding up when trimming
6 changes: 4 additions & 2 deletions gradio/components/audio.py
Expand Up @@ -24,7 +24,8 @@ class WaveformOptions:
A dataclass for specifying options for the waveform display in the Audio component. An instance of this class can be passed into the `waveform_options` parameter of `gr.Audio`.
Parameters:
waveform_color: The color (as a hex string or valid CSS color) of the full waveform representing the amplitude of the audio. Defaults to a light gray color.
waveform_progress_color: The color (as a hex string or valid CSS color) that the waveform fills with to as the audio plays. Defaults to an orange color.
waveform_progress_color: The color (as a hex string or valid CSS color) that the waveform fills with to as the audio plays. Defaults to the accent color.
trim_region_color: The color (as a hex string or valid CSS color) of the trim region. Defaults to the accent color.
show_recording_waveform: Whether to show the waveform when recording audio. Defaults to True.
show_controls: Whether to show the standard HTML audio player below the waveform when recording audio or playing recorded audio. Defaults to False.
skip_length: The percentage (between 0 and 100) of the audio to skip when clicking on the skip forward / skip backward buttons. Defaults to 5.
Expand All @@ -33,6 +34,7 @@ class WaveformOptions:

waveform_color: str | None = None
waveform_progress_color: str | None = None
trim_region_color: str | None = None
show_recording_waveform: bool = True
show_controls: bool = False
skip_length: int | float = 5
Expand Down Expand Up @@ -118,7 +120,7 @@ def __init__(
editable: If True, allows users to manipulate the audio file if the component is interactive. Defaults to True.
min_length: The minimum length of audio (in seconds) that the user can pass into the prediction function. If None, there is no minimum length.
max_length: The maximum length of audio (in seconds) that the user can pass into the prediction function. If None, there is no maximum length.
waveform_options: A dictionary of options for the waveform display. Options include: waveform_color (str), waveform_progress_color (str), show_controls (bool), skip_length (int). Default is None, which uses the default values for these options.
waveform_options: A dictionary of options for the waveform display. Options include: waveform_color (str), waveform_progress_color (str), show_controls (bool), skip_length (int), trim_region_color (str). Default is None, which uses the default values for these options.
"""
valid_sources: list[Literal["upload", "microphone"]] = ["upload", "microphone"]
if sources is None:
Expand Down
9 changes: 9 additions & 0 deletions js/audio/Index.svelte
Expand Up @@ -114,6 +114,15 @@
resize: true
};
function set_trim_region_colour(): void {
document.documentElement.style.setProperty(
"--trim-region-color",
trim_region_settings.color || color_accent
);
}
set_trim_region_colour();
function handle_error({ detail }: CustomEvent<string>): void {
const [level, status] = detail.includes("Invalid file type")
? ["warning", "complete"]
Expand Down
2 changes: 1 addition & 1 deletion js/audio/player/AudioPlayer.svelte
Expand Up @@ -181,7 +181,7 @@
bind:mode
bind:trimDuration
bind:show_volume_slider
showRedo={interactive}
show_redo={interactive}
{handle_reset_value}
{waveform_options}
{trim_region_settings}
Expand Down
2 changes: 1 addition & 1 deletion js/audio/recorder/AudioRecorder.svelte
Expand Up @@ -242,7 +242,7 @@
{handle_trim_audio}
bind:trimDuration
bind:mode
showRedo
show_redo
{handle_reset_value}
{waveform_options}
/>
Expand Down
4 changes: 2 additions & 2 deletions js/audio/shared/WaveformControls.svelte
Expand Up @@ -14,7 +14,7 @@
export let audio_duration: number;
export let i18n: I18nFormatter;
export let playing: boolean;
export let showRedo = false;
export let show_redo = false;
export let interactive = false;
export let handle_trim_audio: (start: number, end: number) => void;
export let mode = "";
Expand Down Expand Up @@ -240,7 +240,7 @@

<div class="settings-wrapper">
{#if editable && interactive}
{#if showRedo && mode === ""}
{#if show_redo && mode === ""}
<button
class="action icon"
aria-label="Reset audio"
Expand Down
15 changes: 14 additions & 1 deletion js/audio/shared/WaveformRecordControls.svelte
Expand Up @@ -246,10 +246,23 @@
:global(::part(region)) {
border-radius: var(--radius-md);
height: 98% !important;
border: 1px solid var(--color-accent);
border: 1px solid var(--trim-region-color);
background-color: unset;
border-width: 1px 3px;
}
:global(::part(region))::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--trim-region-color);
opacity: 0.2;
border-radius: var(--radius-md);
}
:global(::part(region-handle)) {
width: 5px !important;
border: none;
Expand Down
11 changes: 6 additions & 5 deletions js/audio/shared/audioBufferToWav.ts
Expand Up @@ -44,11 +44,12 @@ export function audioBufferToWav(audioBuffer: AudioBuffer): Uint8Array {
offset += 4;

// Write PCM audio data
for (let i = 0; i < audioBuffer.numberOfChannels; i++) {
const channel = audioBuffer.getChannelData(i);
for (let j = 0; j < channel.length; j++) {
// Scaling Float32 to Int16
const sample = Math.max(-1, Math.min(1, channel[j]));
for (let i = 0; i < audioBuffer.length; i++) {
for (let channel = 0; channel < numOfChan; channel++) {
const sample = Math.max(
-1,
Math.min(1, audioBuffer.getChannelData(channel)[i])
);
view.setInt16(offset, sample * 0x7fff, true);
offset += 2;
}
Expand Down
2 changes: 2 additions & 0 deletions test/test_components.py
Expand Up @@ -844,6 +844,7 @@ def test_component_functions(self, gradio_temp_dir):
"skip_length": 5,
"waveform_color": None,
"waveform_progress_color": None,
"trim_region_color": None,
},
"_selectable": False,
}
Expand Down Expand Up @@ -897,6 +898,7 @@ def test_component_functions(self, gradio_temp_dir):
"skip_length": 5,
"waveform_color": None,
"waveform_progress_color": None,
"trim_region_color": None,
},
"_selectable": False,
}
Expand Down

0 comments on commit f26aba0

Please sign in to comment.