Skip to content

Commit

Permalink
Merge pull request #61 from kashiken/feature-player-filter
Browse files Browse the repository at this point in the history
Feature player filter
  • Loading branch information
sukumo28 committed Jul 15, 2024
2 parents 056a350 + d07dcae commit 1889222
Show file tree
Hide file tree
Showing 20 changed files with 882 additions and 50 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,41 @@ You can configure default value of player settings like example below.
default: true
*/
"enableSeekToPlay": true,

/*
Enable high-pass filter on playback.
true: enable high-pass filter, false: disable high-pass filter
default: false
*/
"enableHpf": true,

/*
Cut off frequency for the high-pass filter in Hz. [10, sampleRate/2]
default: 100
*/
"hpfFrequency": 100,

/*
Enable low-pass filter on playback.
true: enable low-pass filter, false: disable low-pass filter
default: false
*/
"enableLpf": true,

/*
Cut off frequency for the low-pass filter in Hz. [10, sampleRate/2]
default: 100
*/
"lpfFrequency": 10000,

/*
Match the filter frequencies to the frequency range of the analyzer.
Note that if this option is set to true, hpfFrequency and lpfFrequency is overridden by spectrogram frequency range settings.
true: automatically match the filter frequencies to the analyzer's frequency range
false: filter frequencies can be set independently of the analyzer's frequency range
default: false
*/
"matchFilterFrequencyToSpectrogram": true,
}
```

Expand Down
16 changes: 16 additions & 0 deletions src/__mocks__/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class MockAudioBuffer {

class MockAudioNode {
connect() {}
disconnect() {}
}

class MockAudioParam {
Expand All @@ -129,6 +130,17 @@ class MockGainNode extends MockAudioNode {
}
}

class MockBiquadFilterNode extends MockAudioNode {
frequency: MockAudioParam;
Q: MockAudioParam; // eslint-disable-line

constructor() {
super();
this.frequency = { value: 1000 };
this.Q = { value: 1.0 };
}
}

class MockAudioBufferSourceNode extends MockAudioNode {
buffer: MockAudioBuffer;

Expand Down Expand Up @@ -165,6 +177,10 @@ class MockAudioContext extends MockAudioNode {
createGain() {
return new MockGainNode();
}

createBiquadFilter() {
return new MockBiquadFilterNode();
}
}

export function createAudioContext(sampleRate: number) {
Expand Down
5 changes: 5 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export interface PlayerDefault {
initialVolume: number;
enableSpacekeyPlay: boolean;
enableSeekToPlay: boolean;
enableHpf: boolean;
hpfFrequency: number;
enableLpf: boolean;
lpfFrequency: number;
matchFilterFrequencyToSpectrogram: boolean;
}

export interface AnalyzeDefault {
Expand Down
17 changes: 17 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,23 @@ export function getValueInRange(
return targetValue;
}

export function getLimitedValueInRange(
targetValue: number,
validMin: number,
validMax: number,
defaultValue: number,
): number {
if (!Number.isFinite(targetValue)) {
return defaultValue;
} else if (validMax < targetValue) {
return validMax;
} else if (targetValue < validMin) {
return validMin;
}

return targetValue;
}

export function getValueInEnum(
targetValue: number,
enumType,
Expand Down
40 changes: 36 additions & 4 deletions src/webview/components/analyzer/analyzerComponent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@ describe("analyserComponent", () => {
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
const playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down Expand Up @@ -108,8 +116,16 @@ describe("auto analyze", () => {
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
const playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down Expand Up @@ -158,8 +174,16 @@ describe("auto analyze", () => {
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
const playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down Expand Up @@ -215,8 +239,16 @@ describe("position of seek-bar should be updated when recieving update-seekbar e
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingsService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down
30 changes: 27 additions & 3 deletions src/webview/components/player/playerComponent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ describe("playerComponent", () => {
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
playerSettingService = PlayerSettingsService.fromDefaultSetting(pd);
playerSettingService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down Expand Up @@ -108,8 +116,16 @@ describe("playerComponent", () => {
initialVolume: 1.0,
enableSpacekeyPlay: true,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
const playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down Expand Up @@ -186,8 +202,16 @@ describe("playerComponent", () => {
initialVolume: 1.0,
enableSpacekeyPlay: false,
enableSeekToPlay: true,
enableHpf: false,
hpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_HPF_DEFAULT,
enableLpf: false,
lpfFrequency: PlayerSettingsService.FILTER_FREQUENCY_LPF_DEFAULT,
matchFilterFrequencyToSpectrogram: false,
};
const playerSettingService = PlayerSettingsService.fromDefaultSetting(pd);
const playerSettingService = PlayerSettingsService.fromDefaultSetting(
pd,
audioBuffer,
);
const playerService = new PlayerService(
audioContext,
audioBuffer,
Expand Down
18 changes: 9 additions & 9 deletions src/webview/components/player/playerComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ export default class PlayerComponent extends Component {
private _playButton: HTMLButtonElement;
private _volumeBar: HTMLInputElement;
private _playerService: PlayerService;
private _playerSettingService: PlayerSettingsService;
private _playerSettingsService: PlayerSettingsService;

constructor(
componentRootID: string,
playerService: PlayerService,
playerSettingService: PlayerSettingsService,
playerSettingsService: PlayerSettingsService,
) {
super();
this._playerService = playerService;
this._playerSettingService = playerSettingService;
this._playerSettingsService = playerSettingsService;

// init base html
this._componentRoot = document.querySelector(componentRootID);

const volumeBar = this._playerSettingService.volumeUnitDb
const volumeBar = this._playerSettingsService.volumeUnitDb
? `<div class="volumeText">volume 0.0 dB</div>
<input type="range" class="volumeBar" value="0" min="-80" max="0" step="0.5">`
: `<div class="volumeText">volume 100</div>
Expand Down Expand Up @@ -80,7 +80,7 @@ export default class PlayerComponent extends Component {
this._componentRoot.querySelector(".volumeText")
);
const updateVolume = () => {
if (this._playerSettingService.volumeUnitDb) {
if (this._playerSettingsService.volumeUnitDb) {
// convert dB setting to linear gain
// -80 dB is treated as mute
const voldb = Number(this._volumeBar.value);
Expand All @@ -96,9 +96,9 @@ export default class PlayerComponent extends Component {
};
this._addEventlistener(this._volumeBar, EventType.INPUT, updateVolume);
this._volumeBar.value = String(
this._playerSettingService.volumeUnitDb
? this._playerSettingService.initialVolumeDb
: this._playerSettingService.initialVolume,
this._playerSettingsService.volumeUnitDb
? this._playerSettingsService.initialVolumeDb
: this._playerSettingsService.initialVolume,
);
updateVolume();

Expand Down Expand Up @@ -129,7 +129,7 @@ export default class PlayerComponent extends Component {

// register keyboard shortcuts
// don't use command.register at audioPreviewEditorProvider.openCustomDocument due to command confliction
if (this._playerSettingService.enableSpacekeyPlay) {
if (this._playerSettingsService.enableSpacekeyPlay) {
this._addEventlistener(window, EventType.KEY_DOWN, (e: KeyboardEvent) => {
if (e.isComposing || e.code !== "Space") {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.playerSetting {
margin: 0.5em;
}

.playerSetting__input {
width: auto;
display: inline-block;
margin: 0.5em;
}
Loading

0 comments on commit 1889222

Please sign in to comment.