Skip to content
This repository has been archived by the owner on May 29, 2023. It is now read-only.

Commit

Permalink
improved demo
Browse files Browse the repository at this point in the history
  • Loading branch information
waterplea committed Mar 26, 2020
1 parent 19627ab commit ce71e80
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 35 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 5 additions & 18 deletions package.json
Expand Up @@ -2,15 +2,7 @@
"name": "@ng-web-apis/midi",
"version": "1.0.1",
"description": "An Observable based library for the use of Web MIDI API with Angular",
"keywords": [
"angular",
"ng",
"midi",
"audio",
"music",
"synth",
"keyboard"
],
"keywords": ["angular", "ng", "midi", "audio", "music", "synth", "keyboard"],
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand Down Expand Up @@ -42,9 +34,7 @@
"name": "Alexander Inkin",
"email": "alexander@inkin.ru"
},
"contributors": [
"Roman Sedov <79601794011@ya.ru>"
],
"contributors": ["Roman Sedov <79601794011@ya.ru>"],
"repository": "https://github.com/ng-web-apis/midi",
"bugs": "https://github.com/ng-web-apis/midi/issues",
"homepage": "https://github.com/ng-web-apis/midi#README",
Expand All @@ -59,8 +49,8 @@
"@angular/platform-browser-dynamic": "^7.2.15",
"@angular/platform-server": "^7.2.15",
"@angular/router": "^7.2.15",
"@ng-web-apis/audio": "^1.2.1",
"@ng-web-apis/common": "^1.0.1",
"@ng-web-apis/audio": "latest",
"@ng-web-apis/common": "latest",
"@nguniversal/common": "^7.1.1",
"@nguniversal/express-engine": "^7.1.1",
"@nguniversal/module-map-ngfactory-loader": "^7.1.1",
Expand Down Expand Up @@ -113,10 +103,7 @@
}
},
"lint-staged": {
"*.{js,ts,html,md,less,json}": [
"prettier --write",
"git add"
],
"*.{js,ts,html,md,less,json}": ["prettier --write", "git add"],
"*.ts": "tslint"
},
"standard-version": {
Expand Down
1 change: 1 addition & 0 deletions projects/demo/package.json
Expand Up @@ -15,6 +15,7 @@
"@angular/platform-browser": "^8.2.4",
"@angular/platform-browser-dynamic": "8.2.0",
"@angular/router": "8.2.0",
"@ng-web-apis/audio": "latest",
"@ng-web-apis/midi": "latest",
"@ng-web-apis/common": "latest",
"core-js": "2.6.9",
Expand Down
46 changes: 46 additions & 0 deletions projects/demo/src/app/adsr.pipe.ts
@@ -0,0 +1,46 @@
import {Pipe, PipeTransform} from '@angular/core';
import {AudioParamInput} from '@ng-web-apis/audio';

@Pipe({
name: 'adsr',
})
export class AdsrPipe implements PipeTransform {
transform(
value: number,
attack: number,
decay: number,
sustain: number,
release: number,
): AudioParamInput {
return value
? [
{
value: 0,
duration: 0,
mode: 'instant',
},
{
value,
duration: attack,
mode: 'linear',
},
{
value: sustain,
duration: decay,
mode: 'linear',
},
]
: [
{
value: sustain,
duration: 0,
mode: 'instant',
},
{
value: 0,
duration: release,
mode: 'linear',
},
];
}
}
3 changes: 2 additions & 1 deletion projects/demo/src/app/app.browser.module.ts
Expand Up @@ -8,6 +8,7 @@ import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {WebAudioModule} from '@ng-web-apis/audio';
import {AdsrPipe} from './adsr.pipe';
import {AppComponent} from './app.component';
import {AppRoutingModule} from './app.routes';

Expand All @@ -20,7 +21,7 @@ import {AppRoutingModule} from './app.routes';
AppRoutingModule,
WebAudioModule,
],
declarations: [AppComponent],
declarations: [AppComponent, AdsrPipe],
providers: [
{
provide: LocationStrategy,
Expand Down
45 changes: 36 additions & 9 deletions projects/demo/src/app/app.component.html
Expand Up @@ -6,15 +6,42 @@
</button>
<ng-template #piano>
<section *ngIf="notes$ | async as notes" class="piano">
<ng-container
*ngFor="let note of notes | keyvalue; trackBy: noteKey"
waOscillatorNode
type="sawtooth"
autoplay
[frequency]="toFrequency(note.key)"
>
<ng-container waGainNode gain="0" [gain]="note.value | waAudioParam: 0.01">
<ng-container waAudioDestinationNode></ng-container>
<ng-container *ngFor="let note of notes | keyvalue; trackBy: noteKey">
<ng-container *ngIf="note.value !== null">
<ng-container
waOscillatorNode
detune="5"
autoplay
[frequency]="toFrequency(note.key)"
>
<ng-container
waGainNode
gain="0"
[gain]="note.value | adsr: 0:0.1:0.02:1"
>
<ng-container waAudioDestinationNode></ng-container>
</ng-container>
</ng-container>
<ng-container
waOscillatorNode
type="sawtooth"
autoplay
[frequency]="toFrequency(note.key)"
>
<ng-container
waGainNode
gain="0"
[gain]="note.value | adsr: 0:0.1:0.02:1"
>
<ng-container waAudioDestinationNode></ng-container>
<ng-container waConvolverNode buffer="assets/audio/response.wav">
<ng-container
waAudioDestinationNode
(quiet)="onQuiet(note.key)"
></ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>
</ng-container>

Expand Down
14 changes: 13 additions & 1 deletion projects/demo/src/app/app.component.ts
Expand Up @@ -16,12 +16,14 @@ export class AppComponent {

readonly octaves = Array.from({length: 24}, (_, i) => i + 48);

readonly notes$: Observable<Map<number, number>>;
readonly notes$: Observable<Map<number, number | null>>;

readonly mousedown$ = new Subject<number>();

readonly mouseup$ = new Subject<void>();

readonly silent$ = new Subject<number>();

constructor(
@Inject(MIDI_SUPPORT) readonly supported: boolean,
@Inject(MIDI_MESSAGES) messages$: Observable<MIDIMessageEvent>,
Expand All @@ -44,6 +46,12 @@ export class AppComponent {
mouseInitiated$,
).pipe(
scan((map, [_, note, volume]) => map.set(note, volume / 512), new Map()),
switchMap(notes =>
this.silent$.pipe(
map(key => notes.set(key, null)),
startWith(notes),
),
),
startWith(new Map()),
);
}
Expand All @@ -67,6 +75,10 @@ export class AppComponent {
return `${className} key-${key % 12 || 12}`;
}

onQuiet(key: number) {
this.silent$.next(key);
}

onMouseDown(note: number) {
this.mousedown$.next(note);
}
Expand Down
Binary file added projects/demo/src/assets/audio/response.wav
Binary file not shown.

0 comments on commit ce71e80

Please sign in to comment.