gradio/js/audio/shared/utils.ts
tsukumi e8b2d8b2f8
Add sample rate config option to gr.Audio() (#6826)
* Fix a bug that caused the sample rate of audio to be 8000 Hz after trimming and a bug that caused volume amplification and clipping each time trimming was performed

* Fix format

* add changeset

* add sample_rate param to waveform_options

* add changeset

* set WaveformOptions defaults

* formatting

* formatting

* add changeset

* audio

* changes

* add changeset

* tweak sample rate logic + docstring

* Tweak docstring

* formatting

* linting

* type tweak

* remove redundant None check

* tweak waveform lifecycle

* fix test

---------

Co-authored-by: tsukumi <tsukumijima@users.noreply.github.com>
Co-authored-by: Hannah <hannahblair@users.noreply.github.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
2024-01-22 10:56:48 -08:00

80 lines
2.0 KiB
TypeScript

import type WaveSurfer from "wavesurfer.js";
import { audioBufferToWav } from "./audioBufferToWav";
export interface LoadedParams {
autoplay?: boolean;
}
export function blob_to_data_url(blob: Blob): Promise<string> {
return new Promise((fulfill, reject) => {
let reader = new FileReader();
reader.onerror = reject;
reader.onload = () => fulfill(reader.result as string);
reader.readAsDataURL(blob);
});
}
export const process_audio = async (
audioBuffer: AudioBuffer,
start?: number,
end?: number,
waveform_sample_rate?: number
): Promise<Uint8Array> => {
const audioContext = new AudioContext({
sampleRate: waveform_sample_rate || audioBuffer.sampleRate
});
const numberOfChannels = audioBuffer.numberOfChannels;
const sampleRate = waveform_sample_rate || audioBuffer.sampleRate;
let trimmedLength = audioBuffer.length;
let startOffset = 0;
if (start && end) {
startOffset = Math.round(start * sampleRate);
const endOffset = Math.round(end * sampleRate);
trimmedLength = endOffset - startOffset;
}
const trimmedAudioBuffer = audioContext.createBuffer(
numberOfChannels,
trimmedLength,
sampleRate
);
for (let channel = 0; channel < numberOfChannels; channel++) {
const channelData = audioBuffer.getChannelData(channel);
const trimmedData = trimmedAudioBuffer.getChannelData(channel);
for (let i = 0; i < trimmedLength; i++) {
trimmedData[i] = channelData[startOffset + i];
}
}
return audioBufferToWav(trimmedAudioBuffer);
};
export function loaded(
node: HTMLAudioElement,
{ autoplay }: LoadedParams = {}
): void {
async function handle_playback(): Promise<void> {
if (!autoplay) return;
node.pause();
await node.play();
}
}
export const skip_audio = (waveform: WaveSurfer, amount: number): void => {
if (!waveform) return;
waveform.skip(amount);
};
export const get_skip_rewind_amount = (
audio_duration: number,
skip_length?: number | null
): number => {
if (!skip_length) {
skip_length = 5;
}
return (audio_duration / 100) * skip_length || 5;
};