Skip to content

Commit

Permalink
[#1476] Add duration and processed event, visual test migration (#1474)
Browse files Browse the repository at this point in the history
Closes #1476

## Changes:

- Fixes #1476: Ensure all sounds stop when game is stopped and `Sound.play()` respects when game is in stopped state
- Added: Add `duration` to `Sound` and `AudioInstance`, when using `AudioBuffer`
- Added: Add `processed` event to `Sound` that receives processed data (`string | AudioBuffer`)
- Changed: Change `Sound.stop()` to always stop and rewind the track, even if sound is not playing
- Add `wireEngine` test coverage in addition to new changes
- Migrate audio visual tests to Storybook
  - Uses Campire and Forest 1 loops from [PremiumBeat](https://www.premiumbeat.com/blog/free-ambient-background-tracks/)
  • Loading branch information
kamranayub authored Apr 13, 2020
1 parent 06a438d commit ea301f7
Show file tree
Hide file tree
Showing 21 changed files with 433 additions and 167 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).
bounding box constructor.
- Added the `ex.vec(x, y)` shorthand for creating vectors.
([#1340](https://github.com/excaliburjs/Excalibur/issues/1340))
- Added new event `processed` to `Sound` that passes processed `string | AudioBuffer` data. ([#1474](https://github.com/excaliburjs/Excalibur/pull/1474))
- Added new property `duration` to `Sound` and `AudioInstance` that exposes the track's duration in seconds when Web Audio API is used. ([#1474](https://github.com/excaliburjs/Excalibur/pull/1474))

### Changed

- Animation no longer mutate underlying sprites, instead they draw the sprite using the animations parameters. This allows more robust flipping at runtime. ([#1258](https://github.com/excaliburjs/Excalibur/issues/1258))
- Changed obsolete decorator to only log the same message 5 times. ([#1281](https://github.com/excaliburjs/Excalibur/issues/1281))
- Switched to core-js based polyfills instead of custom written ones ([#1214](https://github.com/excaliburjs/Excalibur/issues/1214))
- Updated to [email protected] and node 10 LTS build
- `Sound.stop()` now always rewinds the track, even when the sound is paused. ([#1474](https://github.com/excaliburjs/Excalibur/pull/1474))

### Deprecated

Expand All @@ -38,6 +41,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fixed iframe event handling, excalibur will respond to keyboard events from the top window ([#1294](https://github.com/excaliburjs/Excalibur/issues/1294))
- Fixed camera to be vector backed so `ex.Camera.x = ?` and `ex.Camera.pos.setTo(...)` both work as expected([#1299](https://github.com/excaliburjs/Excalibur/issues/1299))
- Fixed missing on/once/off signatures on `ex.Pointer` ([#1345](https://github.com/excaliburjs/Excalibur/issues/1345))
- Fixed sounds not being stopped when `Engine.stop()` is called. ([#1476](https://github.com/excaliburjs/Excalibur/pull/1476))

<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
<!--------------------------------- DO NOT EDIT BELOW THIS LINE --------------------------------->
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
},
"devDependencies": {
"@babel/core": "7.9.0",
"@fortawesome/fontawesome-free": "5.13.0",
"@storybook/addon-actions": "5.3.17",
"@storybook/addon-console": "1.2.1",
"@storybook/addon-docs": "5.3.17",
Expand Down
3 changes: 0 additions & 3 deletions sandbox/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
<li><a href="tests/camera/zoom.html">Camera Zoom over time</a></li>
<li><a href="tests/camera/strategy.html">Camera Strategies</a></li>
<li><a href="tests/group/index.html">Groups</a></li>
<li><a href="tests/audio/index.html">Audio</a></li>
<li><a href="tests/audio/longsound.html">Audio: Long-running sound muting</a></li>
<li><a href="tests/audio/setvolume.html">Set volume with argument to play></a></li>
<li><a href="tests/label/label.html">Label</a></li>
<li><a href="tests/label/fonts.html">Label - Fonts</a></li>
<li><a href="tests/within/within.html">Within distance</a></li>
Expand Down
11 changes: 0 additions & 11 deletions sandbox/tests/audio/index.html

This file was deleted.

64 changes: 0 additions & 64 deletions sandbox/tests/audio/index.ts

This file was deleted.

12 changes: 0 additions & 12 deletions sandbox/tests/audio/longsound.html

This file was deleted.

25 changes: 0 additions & 25 deletions sandbox/tests/audio/longsound.ts

This file was deleted.

11 changes: 0 additions & 11 deletions sandbox/tests/audio/setvolume.html

This file was deleted.

31 changes: 0 additions & 31 deletions sandbox/tests/audio/setvolume.ts

This file was deleted.

10 changes: 10 additions & 0 deletions src/engine/Events/MediaEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,13 @@ export class NativeSoundEvent extends MediaEvent {
super(target, 'NativeSoundEvent');
}
}

export class NativeSoundProcessedEvent extends MediaEvent {
public data: string | AudioBuffer;

constructor(target: Sound, private processedData: string | AudioBuffer) {
super(target, 'NativeSoundProcessedEvent');

this.data = this.processedData;
}
}
11 changes: 11 additions & 0 deletions src/engine/Resources/Sound/AudioInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,19 @@ export class AudioInstance implements Audio {
public get volume(): number {
return this._volume;
}
public set duration(value: number | undefined) {
this._duration = value;
}

/**
* Duration of the sound, in seconds.
*/
public get duration() {
return this._duration;
}

protected _volume = 1;
protected _duration: number | undefined = undefined;
protected _loop = false;
protected _playingPromise: Promise<boolean>;
protected _isPlaying = false;
Expand Down
31 changes: 25 additions & 6 deletions src/engine/Resources/Sound/Sound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Engine } from '../../Engine';
import { Resource } from '../Resource';
import { AudioInstance, AudioInstanceFactory } from './AudioInstance';
import { AudioContextFactory } from './AudioContext';
import { NativeSoundEvent } from '../../Events/MediaEvents';
import { NativeSoundEvent, NativeSoundProcessedEvent } from '../../Events/MediaEvents';
import { Promise } from '../../Promises';
import { canPlayFile } from '../../Util/Sound';

Expand Down Expand Up @@ -48,6 +48,10 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {
return this._volume;
}

public get duration(): number | undefined {
return this._duration;
}

/**
* Return array of Current AudioInstances playing or being paused
*/
Expand All @@ -59,6 +63,8 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {

private _loop = false;
private _volume = 1;
private _duration: number | undefined = undefined;
private _isStopped = false;
private _isPaused = false;
private _tracks: AudioInstance[] = [];
private _engine: Engine;
Expand Down Expand Up @@ -109,6 +115,15 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {
this._wasPlayingOnHidden = false;
}
});

this._engine.on('start', () => {
this._isStopped = false;
});

this._engine.on('stop', () => {
this.stop();
this._isStopped = true;
});
}
}

Expand Down Expand Up @@ -137,6 +152,11 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {
return Promise.resolve(true);
}

if (this._isStopped) {
this.logger.warn('Cannot start playing. Engine is in a stopped state.');
return Promise.resolve(false);
}

this.volume = volume || this.volume;

if (this._isPaused) {
Expand Down Expand Up @@ -166,13 +186,9 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {
}

/**
* Stop the sound and rewind
* Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.
*/
public stop() {
if (!this.isPlaying()) {
return;
}

for (const track of this._tracks) {
track.stop();
}
Expand Down Expand Up @@ -278,6 +294,8 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {

private _setProcessedData(processedData: string | AudioBuffer): void {
this._processedData.resolve(processedData);
this._duration = typeof processedData === 'object' ? processedData.duration : undefined;
this.emit('processed', new NativeSoundProcessedEvent(this, processedData));
}

private _createNewTrack(): Promise<AudioInstance> {
Expand Down Expand Up @@ -306,6 +324,7 @@ export class Sound extends Resource<Blob | ArrayBuffer> implements Audio {

newTrack.loop = this.loop;
newTrack.volume = this.volume;
newTrack.duration = this.duration;

this._tracks.push(newTrack);

Expand Down
3 changes: 3 additions & 0 deletions src/engine/files.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ declare module '*.png' {
export default value;
}

declare module '*.mp3';
declare module '*.svg';

declare module '*.css' {
const value: { toString: () => string };
export default value;
Expand Down
Loading

0 comments on commit ea301f7

Please sign in to comment.