|
| 1 | +# Syrinx - Sound Manager for Adobe AIR |
| 2 | + |
| 3 | +by Aurélien Da Campo ([Adolio](https://twitter.com/AurelienDaCampo)) |
| 4 | + |
| 5 | +## ⭐ Key features |
| 6 | + |
| 7 | +- MP3 & WAV formats support |
| 8 | +- Tracks registration / configuration management |
| 9 | +- Intuitive & friendly API |
| 10 | +- Seamless sound looping via silence trimming and/or WAV files format |
| 11 | +- Pitch capability |
| 12 | + |
| 13 | +## ▶️ Try it! |
| 14 | + |
| 15 | +Go to the [demo](./demo/) folder, configure the project & run it or if you get the latest [release](https://github.com/Adolio/AS3-Sound-Manager/releases), the demo binary should by available in the archive. |
| 16 | + |
| 17 | +## 📄 Full features |
| 18 | + |
| 19 | +- **Sound Manager** |
| 20 | + - Tracks registration management |
| 21 | + - Register / unregister track |
| 22 | + - Get all registered tracks |
| 23 | + - Has registered track? |
| 24 | + - **Track configuration** |
| 25 | + - Type |
| 26 | + - Sampling rate |
| 27 | + - Trimming (start / end) |
| 28 | + - Automatic trimming detection |
| 29 | + - Sound instantiation from registered tracks |
| 30 | + - Play sound (returns a *Sound Instance*) |
| 31 | + - Starting volume |
| 32 | + - Starting position |
| 33 | + - Loop & infinite looping |
| 34 | + - Starting paused |
| 35 | + - Sound format modularity |
| 36 | + - Supported formats: |
| 37 | + - MP3 |
| 38 | + - WAV |
| 39 | + - Sound instances management |
| 40 | + - Master volume |
| 41 | + - Get all sound instances |
| 42 | + - Get all sound instances by type |
| 43 | + - Stop all sound instances |
| 44 | + - Destroy all sound instances |
| 45 | + - Events |
| 46 | + - Track registered |
| 47 | + - Track unregistered |
| 48 | + - Sound instance added |
| 49 | + - Sound instance removed |
| 50 | +- **Sound Instance** |
| 51 | + - Controls |
| 52 | + - Execution (play / pause / resume / stop) |
| 53 | + - Volume |
| 54 | + - Position (time & ratio) |
| 55 | + - Mute |
| 56 | + - Pan |
| 57 | + - Pitch |
| 58 | + - Status & configuration |
| 59 | + - Length |
| 60 | + - Total length (incl. loops) |
| 61 | + - Volume / Mixed volume |
| 62 | + - Is muted? |
| 63 | + - Pan |
| 64 | + - Pitch |
| 65 | + - Loops / remaining loops |
| 66 | + - Position (time & ratio) |
| 67 | + - Is playing? |
| 68 | + - Is started? |
| 69 | + - Is paused? |
| 70 | + - Is destroyed? |
| 71 | + - Events |
| 72 | + - Started |
| 73 | + - Paused |
| 74 | + - Resumed |
| 75 | + - Stopped |
| 76 | + - Completed |
| 77 | + - Destroyed |
| 78 | + |
| 79 | +## ⌨️ How to use? |
| 80 | + |
| 81 | +### 📻 Sound Manager |
| 82 | + |
| 83 | +Main class to register tracks & instantiate sounds. The following example registers two tracks (MP3 & Wav), setups the trimming & sampling options. |
| 84 | +Then three sounds are instantiated. |
| 85 | + |
| 86 | +```actionscript |
| 87 | +// Embedded sounds (Note that WAV files requires a mime type) |
| 88 | +[Embed(source = "../media/sound/engine.mp3")] public static const EngineSoundMp3:Class; |
| 89 | +[Embed(source = "../media/sound/engine.wav", mimeType="application/octet-stream")] public static const EngineSoundWav:Class; |
| 90 | +
|
| 91 | +private var _soundManager:SoundManager; |
| 92 | +
|
| 93 | +public function SoundManagerExample() |
| 94 | +{ |
| 95 | + // Create Sound Manager |
| 96 | + _soundManager = new SoundManager(); |
| 97 | +
|
| 98 | + // Register sounds |
| 99 | + var engineSoundMp3Config:TrackConfiguration = _soundManager.registerTrack("Engine 1", new Mp3Track(new EngineSoundMp3())); // Register a MP3 track |
| 100 | + var engineSoundWavConfig:TrackConfiguration = _soundManager.registerTrack("Engine 2", new WavTrack(new EngineSoundWav())); // Register a WAV track |
| 101 | +
|
| 102 | + // Trimming configuration |
| 103 | + engineSoundMp3Config.findTrim(0.01); // Find start & end trim durations to remove silences inherent to mp3 format (with a silent threshold of 0.01) |
| 104 | +
|
| 105 | + // Sampling rate configuration |
| 106 | + engineSoundWavConfig.sampling = 4096; // This defines how much samples are read per sampling request. The value must be between 2048 (included) and 8192 (included). |
| 107 | +
|
| 108 | + // Play sounds |
| 109 | + var engine1_once:SoundInstance = _soundManager.play("Engine 1", 1.0); // Play once |
| 110 | + var engine1_twice:SoundInstance = _soundManager.play("Engine 1", 1.0, 0, 2); // Play twice |
| 111 | + var engine2_infinite:SoundInstance = _soundManager.play("Engine 2", 1.0, 0, -1); // Play infinite |
| 112 | +
|
| 113 | + // Control master volume |
| 114 | + _soundManager.volume = 0.8; |
| 115 | +} |
| 116 | +``` |
| 117 | + |
| 118 | +### 🎵 Sound Instance |
| 119 | + |
| 120 | +Instance of a sound that can be controlled. The following example shows how to listen to sound events, how to control a sound and how to get various information about it. |
| 121 | + |
| 122 | +```actionscript |
| 123 | +var si:SoundInstance = _soundManager.play("Engine 1", 1.0, 1337, 5); // Play at max volume, starting at 1,337 sec., 6 times (looping 5 times) |
| 124 | +
|
| 125 | +//----------------------------------------------------------------------------- |
| 126 | +//-- Events |
| 127 | +//----------------------------------------------------------------------------- |
| 128 | +
|
| 129 | +si.started.add(function (si:SoundInstance):void { trace("Sound started. " + si.type); } ); |
| 130 | +si.stopped.add(function (si:SoundInstance):void { trace("Sound stopped. " + si.type); } ); |
| 131 | +si.paused.add(function (si:SoundInstance):void { trace("Sound paused. " + si.type); } ); |
| 132 | +si.resumed.add(function (si:SoundInstance):void { trace("Sound resumed. " + si.type); } ); |
| 133 | +si.completed.add(function (si:SoundInstance):void { trace("Sound completed. " + si.type); } ); |
| 134 | +si.destroyed.add(function (si:SoundInstance):void { trace("Sound destroyed. " + si.type); } ); |
| 135 | +
|
| 136 | +//----------------------------------------------------------------------------- |
| 137 | +//-- Controls |
| 138 | +//----------------------------------------------------------------------------- |
| 139 | +
|
| 140 | +// Execution controls |
| 141 | +si.pause(); |
| 142 | +si.resume(); |
| 143 | +si.stop(); |
| 144 | +si.play(0.5, 0, 1.0); // (Re)play twice (repeat once) |
| 145 | +
|
| 146 | +// Position |
| 147 | +si.position = 1337; // In milliseconds |
| 148 | +si.positionRatio = 0.5; // This includes the loops so here it will play only the second loop! |
| 149 | +
|
| 150 | +// Mute |
| 151 | +si.isMuted = true; |
| 152 | +si.isMuted = false; |
| 153 | +
|
| 154 | +// Volume |
| 155 | +si.volume = 0; |
| 156 | +si.volume = 0.8; |
| 157 | +
|
| 158 | +// Pan |
| 159 | +si.pan = -0.5; // Half left |
| 160 | +
|
| 161 | +// Pitch |
| 162 | +si.pitch = 0.8; // 20% slower |
| 163 | +si.pitch = 1.2; // 20% faster |
| 164 | +si.pitch = 1.0; // Back to default |
| 165 | +
|
| 166 | +//----------------------------------------------------------------------------- |
| 167 | +//-- Status info |
| 168 | +//----------------------------------------------------------------------------- |
| 169 | +trace("Type: " + si.type); // Type |
| 170 | +trace("Volume: " + si.volume); // Volume |
| 171 | +trace("Mixed volume: " + si.mixedVolume); // Equals to _soundManager.volume * volume |
| 172 | +trace("Pan: " + si.pan); // Pan |
| 173 | +trace("Pitch: " + si.pitch); // Pitch |
| 174 | +trace("Sound length: " + si.length); // One loop length in milliseconds (trimmed) |
| 175 | +trace("Sound total length: " + si.totalLength); // Total length in milliseconds (including loops & trim durations) |
| 176 | +trace("Loops: " + si.loops); // Total loops |
| 177 | +trace("Remaining loops: " + si.loopsRemaining); // Remaining loops |
| 178 | +trace("Current position: " + si.position); // Current position in milliseconds |
| 179 | +trace("Current position (ratio): " + si.positionRatio); // Current position (ratio, between 0..1) |
| 180 | +trace("Is started: " + si.isStarted); // Is started? |
| 181 | +trace("Is playing: " + si.isPlaying); // Is playing? |
| 182 | +trace("Is paused: " + si.isPaused); // Is paused? |
| 183 | +trace("Is muted: " + si.isMuted); // Is muted? |
| 184 | +trace("Is destroyed: " + si.isDestroyed); // Is destroyed? |
| 185 | +``` |
| 186 | + |
| 187 | +### 💡 Recommendations |
| 188 | + |
| 189 | +- Wav file format is recommended for seamless looping sound since MP3 format introduces silent parts at the beginning & the end of the track. |
| 190 | + - Another option could be to use MP3 & configure trimming durations either manually or by using the `TrackConfiguration.findTrim()` utility method. |
| 191 | +- Use higher sampling rate for tracks that require more robustness against frame drop (e.g. during loading). |
| 192 | + |
| 193 | +## 📦 How to install? |
| 194 | + |
| 195 | +- Checkout this repository & add `src` folder in your `classpath` or copy paste the content of the `src` folder in your source folder. |
| 196 | + |
| 197 | +or |
| 198 | + |
| 199 | +- Use the `.swc` file provided in each release. |
| 200 | + |
| 201 | +Don't forget to include dependencies (see below). |
| 202 | + |
| 203 | +## ☝️ Limitations |
| 204 | + |
| 205 | +- Supported Wav formats: |
| 206 | + - PCM 16 bits, 1 channel, 44100 Hz |
| 207 | + - PCM 16 bits, 2 channels, 44100 Hz |
| 208 | + - IEEE Float 32 bits, 1 channel, 44100 Hz |
| 209 | + - IEEE Float 32 bits, 2 channels, 44100 Hz |
| 210 | + |
| 211 | +## 🔗 Minimum Requirements |
| 212 | + |
| 213 | +- Adobe AIR 32.0 in order to fix crackling artifacts: https://github.com/Gamua/Adobe-Runtime-Support/issues/46 |
| 214 | + |
| 215 | +## 🖇 Dependencies (included in `libs` folder) |
| 216 | + |
| 217 | +- AS3 Signals: https://github.com/robertpenner/as3-signals |
0 commit comments