Skip to content

Commit

Permalink
Merge pull request #70 from dlepaux/feature/debug-tests-envs
Browse files Browse the repository at this point in the history
Handle different SampleRate due to OS, 48000 / 44100
  • Loading branch information
dlepaux committed Feb 9, 2024
2 parents 3e78924 + feeed63 commit 051710d
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 368,718 deletions.
11 changes: 7 additions & 4 deletions src/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
BiquadFilterOptions,
} from './types';
import * as consts from './consts';
import * as utils from './utils';

/**
* Find peaks when the signal if greater than the threshold, then move 10_000 indexes (represents ~0.23s) to ignore the descending phase of the parabol
Expand All @@ -19,8 +20,9 @@ import * as consts from './consts';
* @param skipForwardIndexes Numbers of index to skip when a peak is detected
* @returns Peaks found that are greater than the threshold
*/
export function findPeaksAtThreshold(data: Float32Array, threshold: Threshold, offset = 0, skipForwardIndexes = consts.skipForwardIndexes): PeaksAndThreshold {
export function findPeaksAtThreshold(data: Float32Array, threshold: Threshold, audioSampleRate: number, offset = 0): PeaksAndThreshold {
const peaks: Peaks = [];
const skipForwardIndexes = utils.computeIndexesToSkip(0.25, audioSampleRate);

const {length} = data;

Expand Down Expand Up @@ -49,12 +51,12 @@ export function findPeaksAtThreshold(data: Float32Array, threshold: Threshold, o
* @param channelData Channel data
* @returns Suffisent amount of peaks in order to continue further the process
*/
export async function findPeaks(channelData: Float32Array): Promise<PeaksAndThreshold> {
export async function findPeaks(channelData: Float32Array, audioSampleRate: number): Promise<PeaksAndThreshold> {
let validPeaks: Peaks = [];
let validThreshold = 0;

await descendingOverThresholds(async threshold => {
const {peaks} = findPeaksAtThreshold(channelData, threshold);
const {peaks} = findPeaksAtThreshold(channelData, threshold, audioSampleRate);

/**
* Loop over peaks
Expand Down Expand Up @@ -85,6 +87,7 @@ export async function findPeaks(channelData: Float32Array): Promise<PeaksAndThre
*/
export function getBiquadFilter(context: OfflineAudioContext | AudioContext, options?: BiquadFilterOptions): BiquadFilterNode {
const lowpass = context.createBiquadFilter();

lowpass.type = 'lowpass';
lowpass.frequency.value = options?.frequencyValue ?? consts.frequencyValue;
lowpass.Q.value = options?.qualityValue ?? consts.qualityValue;
Expand Down Expand Up @@ -316,7 +319,7 @@ export function groupByTempo(audioSampleRate: number, intervalCounts: Interval[]
export async function analyzeFullBuffer(originalBuffer: AudioBuffer, options?: BiquadFilterOptions): Promise<Tempo[]> {
const buffer = await getOfflineLowPassSource(originalBuffer, options);
const channelData = buffer.getChannelData(0);
const {peaks} = await findPeaks(channelData);
const {peaks} = await findPeaks(channelData, buffer.sampleRate);
const intervals = identifyIntervals(peaks);
const tempos = groupByTempo(buffer.sampleRate, intervals);
const topCandidates = getTopCandidates(tempos);
Expand Down
1 change: 0 additions & 1 deletion src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ export const startThreshold = 0.95;
export const minValidThreshold = 0.2;
export const minPeaks = 15;
export const thresholdStep = 0.05;
export const skipForwardIndexes = 10000;
export const frequencyValue = 200;
export const qualityValue = 1;

27 changes: 19 additions & 8 deletions src/realtime-bpm-analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
NextIndexPeaks,
BpmCandidates,
Threshold,
FindPeaksOptions,
PostMessageEvents,
} from './types';
import {
Expand Down Expand Up @@ -130,7 +131,14 @@ export class RealTimeBpmAnalyzer {
/**
* Mutate nextIndexPeaks and validPeaks if possible
*/
await this.findPeaks(channelData, bufferSize, currentMinIndex, currentMaxIndex, postMessage);
await this.findPeaks({
channelData,
bufferSize,
audioSampleRate,
currentMinIndex,
currentMaxIndex,
postMessage,
});

/**
* Increment chunk
Expand Down Expand Up @@ -160,13 +168,16 @@ export class RealTimeBpmAnalyzer {

/**
* Find the best threshold with enought peaks
* @param channelData Channel data
* @param bufferSize Buffer size
* @param currentMinIndex Current minimum index
* @param currentMaxIndex Current maximum index
* @param postMessage Function to post a message to the processor node
* @param options Find Peaks Options
*/
async findPeaks(channelData: Float32Array, bufferSize: number, currentMinIndex: number, currentMaxIndex: number, postMessage: (data: PostMessageEvents) => void): Promise<void> {
async findPeaks({
channelData,
bufferSize,
audioSampleRate,
currentMinIndex,
currentMaxIndex,
postMessage,
}: FindPeaksOptions): Promise<void> {
await descendingOverThresholds(async threshold => {
if (this.nextIndexPeaks[threshold] >= currentMaxIndex) {
return false;
Expand All @@ -177,7 +188,7 @@ export class RealTimeBpmAnalyzer {
*/
const offsetForNextPeak = this.nextIndexPeaks[threshold] % bufferSize; // 0 - 4095

const {peaks, threshold: atThreshold} = findPeaksAtThreshold(channelData, threshold, offsetForNextPeak);
const {peaks, threshold: atThreshold} = findPeaksAtThreshold(channelData, threshold, audioSampleRate, offsetForNextPeak);

/**
* Loop over peaks
Expand Down
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ export type RealTimeBpmAnalyzerOptions = {
debug: boolean;
};

export type FindPeaksOptions = {
channelData: Float32Array;
bufferSize: number;
audioSampleRate: number;
currentMinIndex: number;
currentMaxIndex: number;
postMessage: (data: PostMessageEvents) => void;
};

export type ValidPeaks = Record<string, Peaks>;

export type NextIndexPeaks = Record<string, number>;
Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,7 @@ export function chunckAggregator(): (pcmData: Float32Array) => AggregateData {
};
};
}

export function computeIndexesToSkip(durationSeconds: number, sampleRate: number): number {
return Math.round(durationSeconds * sampleRate);
}
Loading

0 comments on commit 051710d

Please sign in to comment.