diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b2df57..28125fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,46 @@ +### 2.0.0 (5 Apr 2024) +- A giant leap forward from the previous version (many thanks to Filip Hráček). +- Major changes to API. There are quick fixes (`dart fix`) to automatically rename many changed APIs. +- `SoLoud` methods now throw instead of returning a PlayerErrors object. +- added `getActiveVoiceCount()` to get concurrent sounds that are playing at the moment. +- added `countAudioSource()` to get concurrent sounds that are playing a specific audio source. +- added `getVoiceCount()` to get the number of voices the application has told SoLoud to play. +- added `getMaxActiveVoiceCount()` to get the current maximum active voice count. +- added `setMaxActiveVoiceCount()` to set the current maximum active voice count. +- added `setProtectVoice()` and `getProtectVoice()` to get/set the protect voice flag. +- `SoLoud.activeSounds` is now an `Iterable` instead of a `List`. +- All time-related parameters and return values are now `Duration` type. + Before, they were `double`. +- Added new (experimental) `AudioSource.allInstancesFinished` stream. + This can be used to more easily await times when it's safe to dispose + the sound. For example: + + ```dart + final source = soloud.loadAsset('...'); + // Wait for the first time all the instances of the sound are finished + // (finished playing or were stopped with soloud.stop()). + source.allInstancesFinished.first.then( + // Dispose of the sound. + (_) => soloud.disposeSound(source) + ); + soloud.play(source); + ``` +- added `looping` and `loopingStartAt` properties to `SoLoud.play()` and `SoLoud.play3d()`. +- added `SoLoud.getLooping()` to retrieve the looping state of a sound. +- added `SoLoud.getLoopPoint()` and `SoLoud.setLoopPoint()` to get and set the looping start position of a sound. +- New methods `SoLoud.loadAsset()` and `SoLoud.loadUrl()` to load audio from assets and URLs, respectively. +- added `mode` property to `SoLoud.loadFile()` and `SoloudTools.loadFrom*` to prevent to load the whole audio data into memory: + - *LoadMode.memory* by default. Means less CPU, more memory allocated. + - *LoadMode.disk* means more CPU, less memory allocated. Lags can occurs while seeking MP3s, especially when using a slider. +- Switched from `print()` logging to using the standard `package:logging`. + See `README.md` to learn how to capture log messages and how to filter them. +- The capture feature is on experimental stage to be fine tuned in the near future. All methods related to audio capture have been extracted to a separate class. + So now, there are two classes: + - `SoLoud` for _playing_ audio + - `SoLoudCapture` for _capturing_ audio +- The Web platform is a work in progress, stay tuned! +- Switched LICENSE from Apache-2.0 to MIT. + ### 2.0.0-pre.5 (4 Apr 2024) - getLoopPoint now returns Duration. - Major changes to API docs and README. diff --git a/README.md b/README.md index b4812ba3..d4806c8e 100755 --- a/README.md +++ b/README.md @@ -151,8 +151,6 @@ Since I needed to modify the generated `.dart` file, I followed this flow: 2. The file `lib/flutter_soloud_FFIGEN.dart` will be generated. 3. Copy the relevant code for the new functions from `lib/flutter_soloud_FFIGEN.dart` into `lib/flutter_soloud_bindings_ffi.dart`. -Additionally, I have forked the [SoLoud](https://github.com/jarikomppa/soloud) repository and made modifications to include the latest [Miniaudio](https://github.com/mackron/miniaudio) audio backend. This backend is in the [new_miniaudio] branch of my [fork](https://github.com/alnitak/soloud) and is set as the default. - #### Project structure This plugin uses the following structure: @@ -165,8 +163,8 @@ This plugin uses the following structure: The `flutter_soloud` plugin utilizes a [forked](https://github.com/alnitak/soloud) repository of [SoLoud](https://github.com/jarikomppa/soloud), -where the [miniaudio](https://github.com/mackron/miniaudio) audio backend has been updated and -is located in `src/soloud/src/backend/miniaudio`. +where the [miniaudio](https://github.com/mackron/miniaudio) audio backend (used by default) has been updated and +it is located in `src/soloud/src/backend/miniaudio`. #### Debugging @@ -207,11 +205,6 @@ For Windows users, SoLoud utilizes *Openmpt* through a DLL, which can be obtaine ***Openmpt*** functions as a module-playing engine, capable of replaying a wide variety of multichannel music formats (669, amf, ams, dbm, digi, dmf, dsm, far, gdm, ice, imf, it, itp, j2b, m15, mdl, med, mid, mo3, mod, mptm, mt2, mtm, okt, plm, psm, ptm, s3m, stm, ult, umx, wow, xm). Additionally, it can load wav files and may offer better support for wav files compared to the stand-alone wav audio source. -#### iOS -There are some problems with Impeller engine when running the *visualizer* example on the simulator (20 Lug 2023). To disable it, run the following command: -`flutter run --no-enable-impeller` -Unfortunately, I don't have a real device to test it. - #### Web Work on web support (using WASM) is tracked in diff --git a/example/README.md b/example/README.md index 1ef4ea8f..8e3bf336 100755 --- a/example/README.md +++ b/example/README.md @@ -2,6 +2,9 @@ Demonstrates how to use the `flutter_soloud` plugin. +There are some problems with Impeller engine in iOS when running the *visualizer* example (the 2nd) on the simulator (20 Lug 2023). To disable it, run the following command: +`flutter run --no-enable-impeller`. + There are 5 examples: *(to use microphone on MacOs or iOS you should add audio input permission in the example app)* diff --git a/example/tests/tests.dart b/example/tests/tests.dart index 24e09a7d..ab62e078 100644 --- a/example/tests/tests.dart +++ b/example/tests/tests.dart @@ -49,8 +49,8 @@ void main() async { } tests = Function()>[ - // testSynchronousDeinit, - // testAsynchronousDeinit, + testSynchronousDeinit, + testAsynchronousDeinit, ]; for (final f in tests) { await runZonedGuarded( @@ -79,6 +79,7 @@ void main() async { ..writeln('See logs above for details.') ..writeln(); } else { + debugPrint('===== TESTS PASSED! ====='); stdout ..writeln('===== TESTS PASSED! =====') ..writeln(); diff --git a/lib/src/audio_isolate.dart b/lib/src/audio_isolate.dart index bdbaa060..4f11a8ff 100644 --- a/lib/src/audio_isolate.dart +++ b/lib/src/audio_isolate.dart @@ -21,9 +21,7 @@ void debugIsolates(String text) { enum MessageEvents { exitIsolate, initEngine, - disposeEngine, startLoop, - stopLoop, loop, loadFile, loadWaveform, @@ -116,13 +114,6 @@ void audioIsolate(SendPort isolateToMainStream) { .send({'event': event['event'], 'args': args, 'return': ret}); break; - case MessageEvents.disposeEngine: - final args = event['args']! as ArgsDisposeEngine; - soLoudController.soLoudFFI.deinit(); - isolateToMainStream - .send({'event': event['event'], 'args': args, 'return': ()}); - break; - case MessageEvents.loadFile: final args = event['args']! as ArgsLoadFile; final ret = soLoudController.soLoudFFI.loadFile( @@ -369,12 +360,6 @@ void audioIsolate(SendPort isolateToMainStream) { ); break; - case MessageEvents.stopLoop: - loopRunning = false; - isolateToMainStream - .send({'event': MessageEvents.stopLoop, 'args': (), 'return': ()}); - break; - case MessageEvents.loop: if (loopRunning) { for (final sound in activeSounds) { diff --git a/lib/src/audio_source.dart b/lib/src/audio_source.dart index f21deb21..2ccbc9c0 100644 --- a/lib/src/audio_source.dart +++ b/lib/src/audio_source.dart @@ -5,14 +5,6 @@ import 'package:flutter_soloud/src/sound_handle.dart'; import 'package:flutter_soloud/src/sound_hash.dart'; import 'package:meta/meta.dart'; -/// Deprecated alias to [SoundEventType]. -@Deprecated('Use SoundEventType instead') -typedef SoundEvent = SoundEventType; - -/// A deprecated alias for [AudioSource]. -@Deprecated("Use 'AudioSource' instead") -typedef SoundProps = AudioSource; - /// the type sent back to the user when a sound event occurs typedef StreamSoundEvent = ({ SoundEventType event, @@ -74,11 +66,7 @@ class AudioSource { late final StreamController soundEventsController = StreamController.broadcast(); - /// This getter is [deprecated] and will be removed. Use [handles] instead. - @Deprecated("Use 'handles' instead") - UnmodifiableSetView get handle => handles; - - /// the user can listen ie when a sound ends or key events (TODO) + /// the user can listen when a sound ends Stream get soundEvents => soundEventsController.stream; /// Backing controller for [allInstancesFinished]. diff --git a/lib/src/soloud.dart b/lib/src/soloud.dart index cc49cfe2..e332308e 100644 --- a/lib/src/soloud.dart +++ b/lib/src/soloud.dart @@ -42,23 +42,6 @@ enum AudioEvent { /// /// For methods that _capture_ sounds, use [SoLoudCapture]. interface class SoLoud { - /// A deprecated way to access the singleton [instance] of SoLoud. - /// - /// The reason this is deprecated is that it leads to code that misrepresents - /// what is actually happening. For example: - /// - /// ```dart - /// // BAD - /// var sound = await SoLoud().loadFile('path/to/sound.mp3'); - /// await SoLoud().play(sound) - /// ``` - /// - /// The code above suggests, on the face of it, that we're _constructing_ - /// two instances of [SoLoud], although we're in fact only accessing - /// the singleton instance. - @Deprecated('Use SoLoudPlayer.instance instead') - factory SoLoud() => instance; - /// The private constructor of [SoLoud]. This prevents developers from /// instantiating new instances. SoLoud._(); @@ -205,15 +188,6 @@ interface class SoLoud { .then((_) => true, onError: (_) => false); } - /// Stream audio events - @Deprecated( - 'Instead of listening to events, just await initialize() and shutdown()') - StreamController audioEvent = StreamController.broadcast(); - - /// status of player - @Deprecated('Use SoLoud.isInitialized (or await SoLoud.initialized) instead') - bool get isPlayerInited => _isInitialized; - /// Status of the engine. /// /// Since the engine is initialized as a part of the @@ -227,10 +201,6 @@ interface class SoLoud { // TODO(filiph): check if still needed bool _isEngineInitialized = false; - /// status of capture - @Deprecated('Use SoLoudCapture.isCaptureInited instead') - bool get isCaptureInited => SoLoudCapture.instance.isCaptureInited; - /// Used both in main and audio isolates /// should be synchronized with each other /// @@ -273,21 +243,6 @@ interface class SoLoud { return completer.future; } - /// Initializes the audio engine. - /// - /// Use [init] instead. This method is simply an alias for [init] - /// for backwards compatibility. It will be removed in a future version. - @Deprecated('use init() instead') - Future startIsolate() => init(); - - /// Deprecated alias of [init]. - @Deprecated("Use 'init()' instead") - Future initialize({ - Duration timeout = const Duration(seconds: 10), - bool automaticCleanup = false, - }) => - init(timeout: timeout, automaticCleanup: automaticCleanup); - /// Initializes the audio engine. /// /// Run this before anything else, and `await` its result in a try/catch. @@ -376,8 +331,6 @@ interface class SoLoud { 'one _initializeCompleter running at any given time.'); if (error == PlayerErrors.noError) { - // ignore: deprecated_member_use_from_same_package - audioEvent.add(AudioEvent.isolateStarted); _isInitialized = true; /// get the visualization flag from the player on C side. @@ -477,21 +430,6 @@ interface class SoLoud { _isEngineInitialized = false; } - /// An alias for [shutdown], for backwards compatibility. - /// - /// Use [shutdown] instead. The [stopIsolate] alias will be removed - /// in a future version. - @Deprecated('use dispose() instead') - Future stopIsolate() => shutdown(); - - /// Deprecated alias of [deinit]. - @Deprecated("Use 'deinit()' instead") - Future shutdown() async { - _log.finest('shutdown() called'); - deinit(); - return true; - } - /// Stops the engine and disposes of all resources, including sounds /// and the audio isolate in a synchronous way. /// @@ -526,13 +464,6 @@ interface class SoLoud { _activeSounds.clear(); } - /// return true if the audio isolate is running - /// - @Deprecated('Use isInitialized (or await SoLoud.initialized) instead') - bool isIsolateRunning() { - return _isolate != null; - } - // ////////////////////////////////// // / isolate loop events management / // ////////////////////////////////// @@ -561,33 +492,10 @@ interface class SoLoud { return true; } - /// stop the [SoundEventType]s loop - /// - Future _stopLoop() async { - _log.finest('_stopLoop() called'); - if (_isolate == null || !_isEngineInitialized) return false; - - _mainToIsolateStream?.send( - { - 'event': MessageEvents.stopLoop, - 'args': (), - }, - ); - await _waitForEvent(MessageEvents.stopLoop, ()); - return true; - } - // //////////////////////////////////////////////// // Below all the methods implemented with FFI for the player // //////////////////////////////////////////////// - /// A deprecated method that manually starts the engine. - /// - /// Do not use. The engine is fully started with [init]. - /// This method will be removed in a future version. - @Deprecated('Use initialize() instead') - Future initEngine() => _initEngine(); - /// Initialize the audio engine. /// /// Defaults are: @@ -618,40 +526,6 @@ interface class SoLoud { return ret; } - /// A deprecated method that manually disposes the engine - /// (and only the engine). - /// - /// Do not use. The engine is fully disposed within [shutdown]. - /// This method will be removed in a future version. - @Deprecated('Use shutdown() instead') - Future disposeEngine() => _disposeEngine(); - - /// Stop the engine - /// The audio isolate doesn't get killed - /// - /// Returns true if success - /// - Future _disposeEngine() async { - _log.finest('_disposeEngine() called'); - if (_isolate == null || !_isEngineInitialized) return false; - - await disposeAllSources(); - - /// first stop the loop - await _stopLoop(); - _isEngineInitialized = false; - - /// then ask to audio isolate to dispose the engine - _mainToIsolateStream?.send( - { - 'event': MessageEvents.disposeEngine, - 'args': (), - }, - ); - await _waitForEvent(MessageEvents.disposeEngine, ()); - return true; - } - /// Load a new sound to be played once or multiple times later, from /// the file system. /// @@ -1099,10 +973,6 @@ interface class SoLoud { } } - /// A deprecated alias of [disposeSource]. - @Deprecated("Use 'disposeSource' instead") - Future disposeSound(AudioSource sound) => disposeSource(sound); - /// Stops all handles of the already loaded [source], and reclaims memory. /// /// After an audio source has been disposed in this way, @@ -1132,10 +1002,6 @@ interface class SoLoud { ); } - /// A deprecated alias to [disposeAllSources]. - @Deprecated("Use 'disposeAllSources()' instead") - Future disposeAllSound() => disposeAllSources(); - /// Disposes all audio sources that are currently loaded. /// Also stops all sound instances if anything is playing. /// @@ -1722,94 +1588,6 @@ interface class SoLoud { } } - // //////////////////////////////////////////////// - // Below all the methods implemented with FFI for the capture - // //////////////////////////////////////////////// - - /// List available input devices. Useful on desktop to choose - /// which input device to use. - @Deprecated('Use SoLoudCapture.listCaptureDevices instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - List listCaptureDevices() => - SoLoudCapture.instance.listCaptureDevices(); - - /// Initialize input device with [deviceID]. - /// - /// Return [CaptureErrors.captureNoError] if no error. - /// - @Deprecated('Use SoLoudCapture.initialize() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - CaptureErrors initCapture({int deviceID = -1}) => - SoLoudCapture.instance.initialize(); - - /// Get the status of the device. - /// - @Deprecated('Use SoLoudCapture.isCaptureInitialized() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - bool isCaptureInitialized() => SoLoudCapture.instance.isCaptureInitialized(); - - /// Returns true if the device is capturing audio. - /// - @Deprecated('Use SoLoudCapture.isCaptureStarted() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - bool isCaptureStarted() => SoLoudCapture.instance.isCaptureStarted(); - - /// Stop and deinit capture device. - /// - /// Return [CaptureErrors.captureNoError] if no error. - /// - @Deprecated('Use SoLoudCapture.stopCapture() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - CaptureErrors stopCapture() => SoLoudCapture.instance.stopCapture(); - - /// Start capturing audio data. - /// - /// Return [CaptureErrors.captureNoError] if no error - /// - @Deprecated('Use SoLoudCapture.startCapture() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - CaptureErrors startCapture() => SoLoudCapture.instance.startCapture(); - - /// Return a floats matrix of 256x512 - /// Every row are composed of 256 FFT values plus 256 of wave data - /// Every time is called, a new row is stored in the - /// first row and all the previous rows are shifted - /// up (the last one will be lost). - /// - /// Return [CaptureErrors.captureNoError] if no error. - /// - @Deprecated('Use SoLoudCapture.getCaptureAudioTexture2D() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - CaptureErrors getCaptureAudioTexture2D( - ffi.Pointer> audioData) => - SoLoudCapture.instance.getCaptureAudioTexture2D(audioData); - - /// Smooth FFT data. - /// - /// When new data is read and the values are decreasing, the new value will be - /// decreased with an amplitude between the old and the new value. - /// This will resul on a less shaky visualization. - /// [smooth] must be in the [0.0 ~ 1.0] range. - /// 0 = no smooth - /// 1 = full smooth - /// the new value is calculated with: - /// newFreq = smooth * oldFreq + (1 - smooth) * newFreq - /// - /// Return [CaptureErrors.captureNoError] if no error. - /// - @Deprecated('Use SoLoudCapture.setCaptureFftSmoothing() instead ' - '(all capture-related methods were moved to SoLoudCapture class)') - @experimental - CaptureErrors setCaptureFftSmoothing(double smooth) => - SoLoudCapture.instance.setCaptureFftSmoothing(smooth); - // /////////////////////////////////////// // / Filters // /////////////////////////////////////// @@ -1867,11 +1645,6 @@ interface class SoLoud { } } - /// Deprecated alias of [setFilterParameter]. - @Deprecated("Use 'setFilterParams' instead") - void setFxParams(FilterType filterType, int attributeId, double value) => - setFilterParameter(filterType, attributeId, value); - /// Sets a parameter of the given [filterType]. /// /// Specify the [attributeId] of the parameter (which you can learn from diff --git a/lib/src/soloud_capture.dart b/lib/src/soloud_capture.dart index 8dbe5aba..7a2f3339 100644 --- a/lib/src/soloud_capture.dart +++ b/lib/src/soloud_capture.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'dart:ffi' as ffi; import 'package:flutter_soloud/src/enums.dart'; @@ -21,23 +20,6 @@ import 'package:meta/meta.dart'; /// breaking changes in the future without a major version bump. @experimental interface class SoLoudCapture { - /// A deprecated way to access the singleton [instance] of [SoLoudCapture]. - /// - /// The reason this is deprecated is that it leads to code that misrepresents - /// what is actually happening. For example: - /// - /// ```dart - /// // BAD - /// var sound = await SoLoudCapture().loadFile('path/to/sound.mp3'); - /// await SoLoudCapture().play(sound) - /// ``` - /// - /// The code above suggests, on the face of it, that we're _constructing_ - /// two instances of [SoLoudCapture], although we're in fact only accessing - /// the singleton instance. - @Deprecated('Use SoLoudCapture.instance instead') - factory SoLoudCapture() => instance; - /// The private constructor of [SoLoudCapture]. This prevents developers from /// instantiating new instances. SoLoudCapture._(); @@ -89,12 +71,6 @@ interface class SoLoudCapture { /// status of capture bool isCaptureInited = false; - /// Stream of audio events. Deprecated. - @Deprecated( - 'Instead of listening to events, just await initialize() and shutdown()', - ) - StreamController get audioEvent => SoLoud.instance.audioEvent; - // //////////////////////////////////////////////// // Below all the methods implemented with FFI for the capture // //////////////////////////////////////////////// @@ -134,11 +110,6 @@ interface class SoLoudCapture { return CaptureErrors.captureNoError; } - /// Deprecated alias of [initialize]. - @Deprecated('Use initialize() instead') - CaptureErrors initCapture({int deviceID = -1}) => - initialize(deviceID: deviceID); - /// Initialize input device with [deviceID]. /// /// Return [CaptureErrors.captureNoError] if no error. @@ -198,10 +169,6 @@ interface class SoLoudCapture { CaptureErrors startCapture() { final ret = SoLoudController().captureFFI.startCapture(); _logCaptureError(ret, from: 'startCapture() result'); - if (ret == CaptureErrors.captureNoError) { - // ignore: deprecated_member_use_from_same_package - audioEvent.add(AudioEvent.captureStarted); - } return ret; } @@ -214,8 +181,6 @@ interface class SoLoudCapture { _logCaptureError(ret, from: 'stopCapture() result'); if (ret == CaptureErrors.captureNoError) { isCaptureInited = false; - // ignore: deprecated_member_use_from_same_package - SoLoud.instance.audioEvent.add(AudioEvent.captureStopped); } return ret; } diff --git a/lib/src/tools/soloud_tools.dart b/lib/src/tools/soloud_tools.dart index 87a98890..c0aea5cb 100644 --- a/lib/src/tools/soloud_tools.dart +++ b/lib/src/tools/soloud_tools.dart @@ -1,117 +1,13 @@ -import 'dart:io'; import 'dart:math'; -import 'package:flutter/foundation.dart'; import 'package:flutter_soloud/src/audio_source.dart'; import 'package:flutter_soloud/src/enums.dart'; import 'package:flutter_soloud/src/soloud.dart'; -import 'package:flutter_soloud/src/utils/assets_manager.dart'; -import 'package:http/http.dart' as http; -import 'package:logging/logging.dart'; -import 'package:path/path.dart' as path; -import 'package:path_provider/path_provider.dart'; - -/// Old spelling of [SoLoudTools]. -@Deprecated('Use SoLoudTools instead') -typedef SoloudTools = SoLoudTools; /// The `SoloudTools` class provides static methods to load audio files /// from various sources, including assets, local files, and URLs. /// class SoLoudTools { - static final Logger _log = Logger('flutter_soloud.SoloudTools'); - - /// Loads an audio file from the assets folder. - @Deprecated('Use SoLoud.loadAsset() instead') - static Future loadFromAssets( - String path, { - LoadMode mode = LoadMode.memory, - }) async { - final f = await AssetsManager.getAssetFile(path); - if (f == null) { - _log.severe('Load from assets failed: Sound is null'); - return null; - } - - return _finallyLoadFile(f, mode: mode); - } - - /// Loads an audio file from the local file system. - @Deprecated('Use SoLoud.loadFile() instead') - static Future loadFromFile( - String path, { - LoadMode mode = LoadMode.memory, - }) async { - final file = File(path); - if (file.existsSync()) { - return _finallyLoadFile(file, mode: mode); - } else { - _log.severe('Load from file failed: File does not exist'); - return null; - } - } - - /// Fetches an audio file from a URL and loads it into the memory. - @Deprecated('Use SoLoud.loadUrl() instead') - static Future loadFromUrl( - String url, { - LoadMode mode = LoadMode.memory, - }) async { - try { - final tempDir = await getTemporaryDirectory(); - final tempPath = tempDir.path; - final filePath = path.join(tempPath, shortHash(url)); - final file = File(filePath); - - if (!file.existsSync()) { - final response = await http.get(Uri.parse(url)); - if (response.statusCode == 200) { - final byteData = response.bodyBytes; - final buffer = byteData.buffer; - await file.create(recursive: true); - await file.writeAsBytes( - buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes), - ); - } else { - _log.severe(() => 'Failed to fetch file from URL: $url'); - return null; - } - } - return _finallyLoadFile(file, mode: mode); - } catch (e, s) { - _log.severe('Error while fetching file', e, s); - return null; - } - } - - /// Let SoLoud try to load the file - /// - @Deprecated('Only used internally by deprecated methods') - static Future _finallyLoadFile( - File file, { - LoadMode mode = LoadMode.memory, - }) async { - try { - final result = await SoLoud.instance.loadFile(file.path, mode: mode); - return result; - } catch (e) { - return null; - } - } - - /// Deprecated: Use [createNotes] instead. - @Deprecated("Use 'createNotes' instead.") - static Future> initSounds({ - int octave = 3, - WaveForm waveForm = WaveForm.sin, - bool superwave = true, - }) => - createNotes( - octave: octave, - waveForm: waveForm, - superwave: superwave, - ); - /// Returns a list of the 12 [AudioSource] notes of the given octave /// /// [octave] usually from 0 to 4 diff --git a/lib/src/utils/assets_manager.dart b/lib/src/utils/assets_manager.dart deleted file mode 100644 index 15645990..00000000 --- a/lib/src/utils/assets_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/services.dart'; -import 'package:logging/logging.dart'; -import 'package:path_provider/path_provider.dart'; - -/// Thanks to Maks Klimko - -/// The [AssetsManager] class provides a static method to retrieve an asset -/// file and save it to the local file system. -/// -@Deprecated('Use SoLoud.loadAsset instead') -class AssetsManager { - static final Logger _log = Logger('flutter_soloud.AssetsManager'); - - /// Loads asset audio to temp file - /// - static Future getAssetFile(String assetsFile) async { - final tempDir = await getTemporaryDirectory(); - final tempPath = tempDir.path; - final filePath = '$tempPath/$assetsFile'; - final file = File(filePath); - if (file.existsSync()) { - return file; - } else { - final ByteData byteData; - try { - byteData = await rootBundle.load(assetsFile); - } catch (e, s) { - // TODO(filiph): This probably shouldn't be a caught exception? - // Let the developer deal with it instead of silently - // failing. - _log.severe("getAssetFile() couldn't load asset file", e, s); - return null; - } - - try { - final buffer = byteData.buffer; - await file.create(recursive: true); - await file.writeAsBytes( - buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes), - ); - } catch (e, s) { - // TODO(filiph): This probably shouldn't be a caught exception? - // Let the developer deal with it instead of silently - // failing. - _log.severe("getAssetFile() couldn't write $file to disk", e, s); - return null; - } - return file; - } - } -} diff --git a/pubspec.yaml b/pubspec.yaml index d8ada2e9..e151838f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: >- A low-level audio plugin for Flutter, mainly meant for games and immersive apps. Based on the SoLoud (C++) audio engine. -version: 2.0.0-pre.5 +version: 2.0.0 issue_tracker: https://github.com/alnitak/flutter_soloud/issues homepage: https://github.com/alnitak/flutter_soloud maintainer: Marco Bavagnoli (@lildeimos)