File tree 2 files changed +34
-5
lines changed 2 files changed +34
-5
lines changed Original file line number Diff line number Diff line change @@ -38,4 +38,22 @@ context("OfflineContext", () => {
38
38
}
39
39
} ) ;
40
40
} ) ;
41
+
42
+ it ( "can render audio not async" , ( ) => {
43
+ const ctx = new OfflineContext ( 1 , 0.2 , 44100 ) ;
44
+ const osc = ctx . createOscillator ( ) ;
45
+ osc . connect ( ctx . rawContext . destination ) ;
46
+ osc . start ( 0.1 ) ;
47
+ return ctx . render ( false ) . then ( buffer => {
48
+ expect ( buffer ) . to . have . property ( "length" ) ;
49
+ expect ( buffer ) . to . have . property ( "sampleRate" ) ;
50
+ const array = buffer . getChannelData ( 0 ) ;
51
+ for ( let i = 0 ; i < array . length ; i ++ ) {
52
+ if ( array [ i ] !== 0 ) {
53
+ expect ( i / array . length ) . to . be . closeTo ( 0.5 , 0.01 ) ;
54
+ break ;
55
+ }
56
+ }
57
+ } ) ;
58
+ } ) ;
41
59
} ) ;
Original file line number Diff line number Diff line change @@ -66,23 +66,34 @@ export class OfflineContext extends Context {
66
66
}
67
67
68
68
/**
69
- * Render just the clock portion of the audiocontext .
69
+ * Render just the clock portion of the audio context .
70
70
*/
71
- private _renderClock ( ) : void {
71
+ private async _renderClock ( asynchronous : boolean ) : Promise < void > {
72
+ let index = 0 ;
72
73
while ( this . _duration - this . _currentTime >= 0 ) {
74
+
73
75
// invoke all the callbacks on that time
74
76
this . emit ( "tick" ) ;
75
- // increment the clock in 5ms chunks
77
+
78
+ // increment the clock in block-sized chunks
76
79
this . _currentTime += 128 / this . sampleRate ;
80
+
81
+ // yield once a second of audio
82
+ index ++ ;
83
+ const yieldEvery = Math . floor ( this . sampleRate / 128 ) ;
84
+ if ( asynchronous && index % yieldEvery === 0 ) {
85
+ await new Promise ( done => setTimeout ( done , 1 ) ) ;
86
+ }
77
87
}
78
88
}
79
89
80
90
/**
81
91
* Render the output of the OfflineContext
92
+ * @param async If the clock should be rendered asynchronously, which will not block the main thread, but be slightly slower.
82
93
*/
83
- async render ( ) : Promise < AudioBuffer > {
94
+ async render ( asynchronous : boolean = true ) : Promise < AudioBuffer > {
84
95
await this . workletsAreReady ( ) ;
85
- this . _renderClock ( ) ;
96
+ await this . _renderClock ( asynchronous ) ;
86
97
return this . _context . startRendering ( ) ;
87
98
}
88
99
You can’t perform that action at this time.
0 commit comments