sound_recipes 0.5.0-dev
sound_recipes: ^0.5.0-dev copied to clipboard
Game sounds with no audio files: write a recipe, it is synthesised to WAV at start-up and played through flutter_soloud. A stock set by material, and music crossfaded by context.
sound_recipes #
Game audio with no audio files: a sound is a recipe — a length and a function
of time — rendered to WAV when the game starts and played through
flutter_soloud. Comes with a stock set of sounds for every material, and
music that crossfades by mood.
Nothing here is specific to voxels, or to any genre: it is one file of synthesis, a bank and a player.
Status: 0.5.0-dev, beta. The API can still change.
Features #
SoundRecipe+renderWav: a sound is a length and a waveform function.StockSounds:break_,place_andstep_for everySoundFamily,step_sandandstep_snow, plushit,hurt,pickup,explodeand more.SoundBank: plays sounds by name, from recipes or asset files.AudioDevice: the one audio device every bank shares, opened by the first and closed after the last.SoundPlayer/SilentSounds: play through an interface, so tests and servers stay silent.MusicScore/StockMusic: background music synthesised from notes, six stock loops.MusicDirector: one track per mood, crossfaded; a file when the app bundles it, else its recipe.
Install #
dependencies:
sound_recipes: ^0.5.0-dev
Dart SDK ^3.13.0.
Needs Flutter (it plays through flutter_soloud).
Usage #
-
Make a bank of the stock sounds, plus your own if you like.
final bank = SoundBank(recipes: { ...StockSounds.all, 'chime': SoundRecipe(0.5, (t, p, rng) => math.sin(t * 880 * math.pi * 2) * (1 - p) * 0.4), }); -
Open the device once, at start-up. It returns false where there is no audio, and the bank then stays silent. Every bank holds the one
AudioDevice, anddisposelets go of it, so the device closes only after the last bank is disposed. Code that plays through SoLoud itself holds the device the same way, withAudioDevice.instance.acquire()andrelease().WidgetsFlutterBinding.ensureInitialized(); await bank.init(); -
Play by name.
volumeDb0 is full and -6 is about half.bank.play('break_${SoundFamily.stone}', volumeDb: -3); -
Music (optional): a mood maps to a file, a recipe, or both — the file plays when the app bundles it, the recipe until then.
setMood('night')crossfades.final music = MusicDirector( {'day': 'assets/music/day.mp3', 'night': 'assets/music/night.mp3'}, recipes: {'day': StockMusic.pastoral.toRecipe(), 'night': StockMusic.frozen.toRecipe()}, ); await music.setMood('day'); -
In tests, pass a
SilentSoundswherever aSoundPlayeris asked for, and setAudioDevice.instanceto a device of your own, so no test opens SoLoud:AudioDevice.instance = AudioDevice(open: () async => false, close: () async {});
Example #
example/main.dart is a sound board: one button for
each sound. Copy it into a Flutter app's lib/main.dart and flutter run.