-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from Picovoice/v1.1
- Loading branch information
Showing
23 changed files
with
770 additions
and
594 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,153 @@ | ||
# flutter-voice-processor | ||
# Flutter Voice Processor | ||
|
||
[![GitHub release](https://img.shields.io/github/release/Picovoice/flutter-voice-processor.svg)](https://github.com/Picovoice/flutter-voice-processor/releases) | ||
[![GitHub](https://img.shields.io/github/license/Picovoice/flutter-voice-processor)](https://github.com/Picovoice/flutter-voice-processor/) | ||
|
||
[![Pub Version](https://img.shields.io/pub/v/flutter_voice_processor)](https://pub.dev/packages/flutter_voice_processor) | ||
|
||
Made in Vancouver, Canada by [Picovoice](https://picovoice.ai) | ||
|
||
A Flutter plugin for real-time voice processing. | ||
<!-- markdown-link-check-disable --> | ||
[![Twitter URL](https://img.shields.io/twitter/url?label=%40AiPicovoice&style=social&url=https%3A%2F%2Ftwitter.com%2FAiPicovoice)](https://twitter.com/AiPicovoice) | ||
<!-- markdown-link-check-enable --> | ||
[![YouTube Channel Views](https://img.shields.io/youtube/channel/views/UCAdi9sTCXLosG1XeqDwLx7w?label=YouTube&style=social)](https://www.youtube.com/channel/UCAdi9sTCXLosG1XeqDwLx7w) | ||
|
||
The Flutter Voice Processor is an asynchronous audio capture library designed for real-time audio | ||
processing on mobile devices. Given some specifications, the library delivers frames of raw audio | ||
data to the user via listeners. | ||
|
||
## Table of Contents | ||
|
||
- [Flutter Voice Processor](#flutter-voice-processor) | ||
- [Table of Contents](#table-of-contents) | ||
- [Requirements](#requirements) | ||
- [Compatibility](#compatibility) | ||
- [Installation](#installation) | ||
- [Permissions](#permissions) | ||
- [Usage](#usage) | ||
- [Capturing with Multiple Listeners](#capturing-with-multiple-listeners) | ||
- [Example](#example) | ||
|
||
## Requirements | ||
|
||
- [Flutter SDK](https://docs.flutter.dev/get-started/install) | ||
- [Android SDK](https://developer.android.com/about/versions/12/setup-sdk) (21+) | ||
- [JDK](https://www.oracle.com/java/technologies/downloads/) (8+) | ||
- [Xcode](https://developer.apple.com/xcode/) (11+) | ||
- [CocoaPods](https://cocoapods.org/) | ||
|
||
## Compatibility | ||
|
||
- Flutter 1.20.0+ | ||
- Android 5.0+ (API 21+) | ||
- iOS 11.0+ | ||
|
||
## Installation | ||
|
||
Flutter Voice Processor is available via [pub.dev](https://pub.dev/packages/flutter_voice_processor). | ||
To import it into your Flutter project, add the following line to your `pubspec.yaml`: | ||
```yaml | ||
dependencies: | ||
flutter_voice_processor: ^<version> | ||
``` | ||
## Permissions | ||
To enable recording with the hardware's microphone, you must first ensure that you have enabled the proper permission on both iOS and Android. | ||
On iOS, open the `Info.plist` file and add the following line: | ||
```xml | ||
<key>NSMicrophoneUsageDescription</key> | ||
<string>[Permission explanation]</string> | ||
``` | ||
|
||
On Android, open the `AndroidManifest.xml` and add the following line: | ||
```xml | ||
<uses-permission android:name="android.permission.RECORD_AUDIO" /> | ||
``` | ||
|
||
See our [example app](./example) for how to properly request this permission from your users. | ||
|
||
## Usage | ||
|
||
Create: | ||
Access the singleton instance of `VoiceProcessor`: | ||
|
||
```dart | ||
int frameLength = 512; | ||
int sampleRate = 16000; | ||
VoiceProcessor _voiceProcessor = VoiceProcessor.getVoiceProcessor(frameLength, sampleRate); | ||
Function _removeListener = _voiceProcessor.addListener((buffer) { | ||
print("Listener received buffer of size ${buffer.length}!"); | ||
}); | ||
import 'package:flutter_voice_processor/flutter_voice_processor.dart'; | ||
VoiceProcessor? _voiceProcessor = VoiceProcessor.instance; | ||
``` | ||
|
||
Start audio: | ||
Add listeners for audio frames and errors: | ||
|
||
```dart | ||
try { | ||
if (await _voiceProcessor.hasRecordAudioPermission()) { | ||
await _voiceProcessor.start(); | ||
} else { | ||
print("Recording permission not granted"); | ||
VoiceProcessorFrameListener frameListener = (List<int> frame) { | ||
// use audio | ||
} | ||
VoiceProcessorErrorListener errorListener = (VoiceProcessorException error) { | ||
// handle error | ||
} | ||
_voiceProcessor?.addFrameListener(frameListener); | ||
_voiceProcessor?.addErrorListener(errorListener); | ||
``` | ||
|
||
Ask for audio record permission and start recording with the desired frame length and audio sample rate: | ||
|
||
```dart | ||
final int frameLength = 512; | ||
final int sampleRate = 16000; | ||
if (await _voiceProcessor?.hasRecordAudioPermission() ?? false) { | ||
try { | ||
await _voiceProcessor?.start(frameLength, sampleRate); | ||
} on PlatformException catch (ex) { | ||
// handle start error | ||
} | ||
} else { | ||
// user did not grant permission | ||
} | ||
``` | ||
|
||
Stop audio capture: | ||
```dart | ||
try { | ||
await _voiceProcessor?.stop(); | ||
} on PlatformException catch (ex) { | ||
print("Failed to start recorder: " + ex.toString()); | ||
// handle stop error | ||
} | ||
``` | ||
|
||
Stop audio: | ||
Once audio capture has started successfully, any frame listeners assigned to the `VoiceProcessor` will start receiving audio frames with the given `frameLength` and `sampleRate`. | ||
|
||
### Capturing with Multiple Listeners | ||
|
||
Any number of listeners can be added to and removed from the `VoiceProcessor` instance. However, | ||
the instance can only record audio with a single audio configuration (`frameLength` and `sampleRate`), | ||
which all listeners will receive once a call to `start()` has been made. To add multiple listeners: | ||
```dart | ||
await _voiceProcessor.stop(); | ||
_removeListener(); | ||
``` | ||
VoiceProcessorFrameListener listener1 = (frame) { } | ||
VoiceProcessorFrameListener listener2 = (frame) { } | ||
List<VoiceProcessorFrameListener> listeners = [listener1, listener2]; | ||
_voiceProcessor?.addFrameListeners(listeners); | ||
_voiceProcessor?.removeFrameListeners(listeners); | ||
// or | ||
_voiceProcessor?.clearFrameListeners(); | ||
``` | ||
|
||
## Example | ||
|
||
The [Flutter Voice Processor app](./example) demonstrates how to ask for user permissions and capture output from the `VoiceProcessor`. | ||
|
||
## Releases | ||
|
||
### v1.1.0 - August 4, 2023 | ||
- Numerous API improvements | ||
- Error handling improvements | ||
- Allow for multiple listeners instead of a single callback function | ||
- Upgrades to testing infrastructure and example app | ||
|
||
### v1.0.0 - December 8, 2020 | ||
|
||
- Initial public release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
#Mon Jul 31 11:07:10 PDT 2023 | ||
distributionBase=GRADLE_USER_HOME | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip | ||
distributionPath=wrapper/dists | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip | ||
zipStoreBase=GRADLE_USER_HOME |
Empty file.
Oops, something went wrong.