├── ios ├── Assets │ └── .gitkeep ├── Frameworks │ ├── lame.framework │ │ ├── lame │ │ └── Headers │ │ │ └── lame.h │ └── TAISDK.framework │ │ ├── TAISDK │ │ ├── Info.plist │ │ ├── Modules │ │ └── module.modulemap │ │ ├── PrivateHeaders │ │ └── TAISDK.h │ │ └── Headers │ │ ├── TAIManager.h │ │ ├── TAIError.h │ │ ├── TAICommonParam.h │ │ ├── TAIMathCorrection.h │ │ └── TAIOralEvaluation.h ├── Classes │ ├── FlutterTaiPlugin.h │ └── FlutterTaiPlugin.m ├── .gitignore └── flutter_tai.podspec ├── LICENSE ├── android ├── gradle.properties ├── settings.gradle ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── jlcool │ │ └── flutter_tai │ │ └── FlutterTaiPlugin.java └── build.gradle ├── CHANGELOG.md ├── example ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── jlcool │ │ │ │ │ │ └── flutter_tai_example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ └── build.gradle ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── AppDelegate.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── main.m │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Podfile.lock │ └── Podfile ├── .metadata ├── test │ └── widget_test.dart ├── README.md ├── lib │ ├── PermissionUtil.dart │ └── main.dart ├── .gitignore └── pubspec.yaml ├── .gitignore ├── test └── flutter_tai_test.dart ├── .metadata ├── lib ├── response.dart └── flutter_tai.dart ├── flutter_tai.iml ├── pubspec.yaml └── README.md /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_tai' 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true -------------------------------------------------------------------------------- /ios/Frameworks/lame.framework/lame: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/ios/Frameworks/lame.framework/lame -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/TAISDK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/ios/Frameworks/TAISDK.framework/TAISDK -------------------------------------------------------------------------------- /ios/Classes/FlutterTaiPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterTaiPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/ios/Frameworks/TAISDK.framework/Info.plist -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | /example/pubspec.lock 9 | /.idea 10 | /pubspec.lock 11 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module TAISDK { 2 | umbrella header "TAISDK.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /test/flutter_tai_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:flutter_tai/flutter_tai.dart'; 4 | 5 | void main() { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlcool/flutter_tai/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/PrivateHeaders/TAISDK.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAISDK.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/11/27. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 60e6ddeb9217133e809318166f3fbd8eb3c7ca06 8 | channel: unknown 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 60e6ddeb9217133e809318166f3fbd8eb3c7ca06 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Headers/TAIManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAIManager.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/11/27. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TAIManager : NSObject 12 | /* 13 | 获取版本号 14 | */ 15 | + (NSString *)getVersion; 16 | @end 17 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /lib/response.dart: -------------------------------------------------------------------------------- 1 | class ProgressResponse { 2 | final int volume; 3 | ProgressResponse({this.volume}); 4 | } 5 | class ResultResponse { 6 | final String err; 7 | ResultResponse({this.err}); 8 | } 9 | class EvaluationDataResponse { 10 | final int seqId; 11 | final int end; 12 | final String err; 13 | final String ret; 14 | EvaluationDataResponse({this.seqId,this.end,this.err,this.ret}); 15 | } 16 | class StopResponse { 17 | final String err; 18 | StopResponse({this.err}); 19 | } -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/jlcool/flutter_tai_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jlcool.flutter_tai_example; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | 12 | void main() { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_tai_example 2 | 3 | Demonstrates how to use the flutter_tai plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.jlcool.flutter_tai' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.2.1' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | testInstrumentationRunner "androidx.support.test.runner.AndroidJUnitRunner" 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation 'com.google.code.gson:gson:2.8.0' 38 | implementation 'com.tencent.taisdk:taisdk:1.2.3.3' 39 | } 40 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_tai (0.0.1): 4 | - Flutter 5 | - permission_handler (3.1.0): 6 | - Flutter 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `.symlinks/flutter/ios`) 10 | - flutter_tai (from `.symlinks/plugins/flutter_tai/ios`) 11 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`) 12 | 13 | EXTERNAL SOURCES: 14 | Flutter: 15 | :path: ".symlinks/flutter/ios" 16 | flutter_tai: 17 | :path: ".symlinks/plugins/flutter_tai/ios" 18 | permission_handler: 19 | :path: ".symlinks/plugins/permission_handler/ios" 20 | 21 | SPEC CHECKSUMS: 22 | Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296 23 | flutter_tai: aee62e7dce0223289541b0f466b5c13f9c73d89e 24 | permission_handler: a1b8c0f8c83b4e7201f9c04b9aef09979cc97f60 25 | 26 | PODFILE CHECKSUM: aff02bfeed411c636180d6812254b2daeea14d09 27 | 28 | COCOAPODS: 1.5.3 29 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Headers/TAIError.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAIError.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/12/4. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, TAIErrCode) 12 | { 13 | /* 14 | 成功 15 | */ 16 | TAIErrCode_Succ = 0, 17 | /* 18 | 参数错误 19 | */ 20 | TAIErrCode_Param, 21 | /* 22 | json解析错误 23 | */ 24 | TAIErrCode_Json, 25 | /* 26 | http请求错误 27 | */ 28 | TAIErrCode_Https, 29 | /* 30 | 服务器错误 31 | */ 32 | TAIErrCode_Server, 33 | }; 34 | 35 | @interface TAIError : NSObject 36 | @property (nonatomic, assign) TAIErrCode code; 37 | @property (nonatomic, strong) NSString *desc; 38 | @property (nonatomic, strong) NSString *requestId; 39 | + (id)errorCode:(NSInteger)code desc:(NSString *)desc requestId:(NSString *)requestId; 40 | @end 41 | -------------------------------------------------------------------------------- /flutter_tai.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ios/flutter_tai.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'flutter_tai' 6 | s.version = '0.0.1' 7 | s.summary = '腾讯云智聆口语评测(Smart Oral Evaluation,SOE)是腾讯云推出的语音评测产品,是基于口语类教育培训场景和腾讯云的语音处理技术,应用特征提取、声学模型和语音识别算法,为儿童和成人提供高准确度的口语发音评测。支持单词、句子和段落模式的评测,多维度反馈口语表现,可广泛应用于中文及英语口语类教学中。' 8 | s.description = <<-DESC 9 | 腾讯云智聆口语评测(Smart Oral Evaluation,SOE)是腾讯云推出的语音评测产品,是基于口语类教育培训场景和腾讯云的语音处理技术,应用特征提取、声学模型和语音识别算法,为儿童和成人提供高准确度的口语发音评测。支持单词、句子和段落模式的评测,多维度反馈口语表现,可广泛应用于中文及英语口语类教学中。 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | 19 | s.ios.deployment_target = '8.0' 20 | s.vendored_frameworks = 'Frameworks/*.framework' 21 | end 22 | 23 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Headers/TAICommonParam.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAICommonParam.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/12/25. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TAICommonParam : NSObject 12 | /** 13 | * 账号应用id 14 | */ 15 | @property (nonatomic, strong) NSString *appId; 16 | /** 17 | * 超时时间(默认30秒) 18 | */ 19 | @property (nonatomic, assign) NSInteger timeout; 20 | /** 21 | * 重试次数(默认0次) 22 | */ 23 | @property (nonatomic, assign) NSInteger retryTimes; 24 | /** 25 | * secretId 26 | */ 27 | @property (nonatomic, strong) NSString *secretId; 28 | /** 29 | * secretKey 30 | * @brief 使用内部签名,此处必填 31 | */ 32 | @property (nonatomic, strong) NSString *secretKey; 33 | /** 34 | * token 35 | * @brief 临时secretKey方案此处必填 36 | */ 37 | @property (nonatomic, strong) NSString *token; 38 | /** 39 | * 时间戳 40 | * @brief 使用外部签名,此处必填 41 | */ 42 | @property (nonatomic, assign) NSInteger timestamp; 43 | /** 44 | * 签名 45 | * @brief 使用外部签名,此处必填(https://cloud.tencent.com/document/product/1004/30611 第三步) 46 | */ 47 | @property (nonatomic, strong) NSString *signature; 48 | @end 49 | -------------------------------------------------------------------------------- /example/lib/PermissionUtil.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:permission_handler/permission_handler.dart'; 5 | 6 | class PermissionUtil { 7 | static Future checkStorage() async { 8 | if (Platform.isAndroid) { 9 | PermissionStatus permission = await PermissionHandler() 10 | .checkPermissionStatus(PermissionGroup.storage); 11 | if (permission != PermissionStatus.granted) { 12 | Map permissions = 13 | await PermissionHandler() 14 | .requestPermissions([PermissionGroup.storage]); 15 | if (permissions[PermissionGroup.storage] == PermissionStatus.granted) { 16 | return true; 17 | } 18 | } else { 19 | return true; 20 | } 21 | } else { 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | static Future checkMicrophone(BuildContext context) async { 28 | PermissionStatus permission = await PermissionHandler() 29 | .checkPermissionStatus(PermissionGroup.microphone); 30 | if (permission != PermissionStatus.granted) { 31 | Map permissions = 32 | await PermissionHandler() 33 | .requestPermissions([PermissionGroup.microphone]); 34 | if (permissions[PermissionGroup.microphone] == PermissionStatus.granted) { 35 | return true; 36 | } 37 | } else { 38 | return true; 39 | } 40 | return false; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Headers/TAIMathCorrection.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAIMathCorrection.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/12/25. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "TAICommonParam.h" 12 | #import "TAIError.h" 13 | 14 | 15 | @interface TAIMathCorrectionItem : NSObject 16 | //计算结果 17 | @property (nonatomic, assign) BOOL result; 18 | //算式位置 19 | @property (nonatomic, assign) CGRect rect; 20 | //算式字符串 21 | @property (nonatomic, strong) NSString *formula; 22 | //推荐答案 23 | @property (nonatomic, strong) NSString *answer; 24 | @end 25 | 26 | 27 | @interface TAIMathCorrectionRet : NSObject 28 | //sessionId 29 | @property (nonatomic, strong) NSString *sessionId; 30 | //items 31 | @property (nonatomic, strong) NSArray *items; 32 | @end 33 | 34 | 35 | 36 | @interface TAIMathCorrectionParam : TAICommonParam 37 | //业务应用id(默认为default) 38 | @property (nonatomic, strong) NSString *hcmAppId; 39 | //sessionId 40 | @property (nonatomic, strong) NSString *sessionId; 41 | //图片数据 42 | @property (nonatomic, strong) NSData *imageData; 43 | @end 44 | 45 | 46 | 47 | 48 | typedef void (^TAIMathCorrectionCallback)(TAIError *error, TAIMathCorrectionRet *result); 49 | 50 | @interface TAIMathCorrection : NSObject 51 | /** 52 | * 速算题目批改 53 | * @param param 参数 54 | * @param callback 回调 55 | */ 56 | - (void)mathCorrection:(TAIMathCorrectionParam *)param callback:(TAIMathCorrectionCallback)callback; 57 | /** 58 | * 获取签名所需字符串 59 | * @param timestamp 时间戳 60 | * @return NSString 签名 61 | */ 62 | - (NSString *)getStringToSign:(NSInteger)timestamp; 63 | @end 64 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_tai_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | NSMicrophoneUsageDescription 45 | App需要您的同意,才能访问麦克风 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 17 | 24 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_tai 2 | description: Smart Oral Evaluation 3 | 4 | version: 0.0.4 5 | author: jlcool 6 | homepage: https://github.com/jlcool/flutter_tai 7 | 8 | environment: 9 | sdk: ">=2.1.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | uuid: ^2.0.0 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | # For information on the generic Dart part of this file, see the 21 | # following page: https://www.dartlang.org/tools/pub/pubspec 22 | 23 | # The following section is specific to Flutter. 24 | flutter: 25 | # This section identifies this Flutter project as a plugin project. 26 | # The androidPackage and pluginClass identifiers should not ordinarily 27 | # be modified. They are used by the tooling to maintain consistency when 28 | # adding or updating assets for this project. 29 | plugin: 30 | androidPackage: com.jlcool.flutter_tai 31 | pluginClass: FlutterTaiPlugin 32 | 33 | # To add assets to your plugin package, add an assets section, like this: 34 | # assets: 35 | # - images/a_dot_burr.jpeg 36 | # - images/a_dot_ham.jpeg 37 | # 38 | # For details regarding assets in packages, see 39 | # https://flutter.dev/assets-and-images/#from-packages 40 | # 41 | # An image asset can refer to one or more resolution-specific "variants", see 42 | # https://flutter.dev/assets-and-images/#resolution-aware. 43 | 44 | # To add custom fonts to your plugin package, add a fonts section here, 45 | # in this "flutter" section. Each entry in this list should have a 46 | # "family" key with the font family name, and a "fonts" key with a 47 | # list giving the asset and other descriptors for the font. For 48 | # example: 49 | # fonts: 50 | # - family: Schyler 51 | # fonts: 52 | # - asset: fonts/Schyler-Regular.ttf 53 | # - asset: fonts/Schyler-Italic.ttf 54 | # style: italic 55 | # - family: Trajan Pro 56 | # fonts: 57 | # - asset: fonts/TrajanPro.ttf 58 | # - asset: fonts/TrajanPro_Bold.ttf 59 | # weight: 700 60 | # 61 | # For details regarding fonts in packages, see 62 | # https://flutter.dev/custom-fonts/#from-packages 63 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_tai_example 2 | description: Demonstrates how to use the flutter_tai plugin. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | permission_handler: ^3.1.0 12 | 13 | # The following adds the Cupertino Icons font to your application. 14 | # Use with the CupertinoIcons class for iOS style icons. 15 | cupertino_icons: ^0.1.2 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | 21 | flutter_tai: 22 | path: ../ 23 | 24 | # For information on the generic Dart part of this file, see the 25 | # following page: https://www.dartlang.org/tools/pub/pubspec 26 | 27 | # The following section is specific to Flutter. 28 | flutter: 29 | 30 | # The following line ensures that the Material Icons font is 31 | # included with your application, so that you can use the icons in 32 | # the material Icons class. 33 | uses-material-design: true 34 | 35 | # To add assets to your application, add an assets section, like this: 36 | # assets: 37 | # - images/a_dot_burr.jpeg 38 | # - images/a_dot_ham.jpeg 39 | 40 | # An image asset can refer to one or more resolution-specific "variants", see 41 | # https://flutter.dev/assets-and-images/#resolution-aware. 42 | 43 | # For details regarding adding assets from package dependencies, see 44 | # https://flutter.dev/assets-and-images/#from-packages 45 | 46 | # To add custom fonts to your application, add a fonts section here, 47 | # in this "flutter" section. Each entry in this list should have a 48 | # "family" key with the font family name, and a "fonts" key with a 49 | # list giving the asset and other descriptors for the font. For 50 | # example: 51 | # fonts: 52 | # - family: Schyler 53 | # fonts: 54 | # - asset: fonts/Schyler-Regular.ttf 55 | # - asset: fonts/Schyler-Italic.ttf 56 | # style: italic 57 | # - family: Trajan Pro 58 | # fonts: 59 | # - asset: fonts/TrajanPro.ttf 60 | # - asset: fonts/TrajanPro_Bold.ttf 61 | # weight: 700 62 | # 63 | # For details regarding fonts from package dependencies, 64 | # see https://flutter.dev/custom-fonts/#from-packages 65 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.jlcool.flutter_tai_example" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | debug { 51 | ///flutter 开发得注释 安卓开发 打开 52 | // ndk { 53 | // abiFilters 'armeabi-v7a' 54 | // } 55 | } 56 | } 57 | } 58 | 59 | flutter { 60 | source '../..' 61 | } 62 | 63 | dependencies { 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'androidx.test:runner:1.1.0' 66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 67 | } 68 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | post_install do |installer| 64 | installer.pods_project.targets.each do |target| 65 | target.build_configurations.each do |config| 66 | config.build_settings['ENABLE_BITCODE'] = 'NO' 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:async'; 3 | 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_tai/flutter_tai.dart'; 6 | 7 | import 'PermissionUtil.dart'; 8 | 9 | void main() => runApp(MyApp()); 10 | 11 | class MyApp extends StatefulWidget { 12 | @override 13 | _MyAppState createState() => _MyAppState(); 14 | } 15 | 16 | class _MyAppState extends State { 17 | FlutterTai _tai = FlutterTai(); 18 | int _volume = 0; 19 | bool _recoding = false; 20 | double _progress = 0; 21 | 22 | @override 23 | void initState() { 24 | super.initState(); 25 | _tai.responseFromProgress.listen((data) { 26 | _volume = data.volume; 27 | _progress = _volume / 120; 28 | setState(() {}); 29 | print("音量:${data.volume} $_progress}"); 30 | }); 31 | _tai.responseFromStop.listen((data) { 32 | setState(() { 33 | _recoding = false; 34 | }); 35 | print("stop:${data.err}"); 36 | }); 37 | _tai.responseFromResult.listen((data) { 38 | print("result:${data.err}"); 39 | }); 40 | _tai.responseFromEvaluationData.listen((data) { 41 | print( 42 | "EvaluationData:err:${data.err} ret:${data.ret} end:${data.end} seqId:${data.seqId} "); 43 | }); 44 | } 45 | 46 | // Platform messages are asynchronous, so we initialize in an async method. 47 | Future record() async { 48 | _recoding = true; 49 | setState(() {}); 50 | if (await PermissionUtil.checkStorage() && 51 | await PermissionUtil.checkMicrophone(context)) { 52 | try { 53 | await _tai.record("", "", 54 | "", "how are you",); 55 | } on PlatformException {} 56 | 57 | // If the widget was removed from the tree while the asynchronous platform 58 | // message was in flight, we want to discard the reply rather than calling 59 | // setState to update our non-existent appearance. 60 | 61 | } 62 | } 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return MaterialApp( 67 | home: Scaffold( 68 | appBar: AppBar( 69 | title: const Text('Plugin example app'), 70 | ), 71 | body: Center( 72 | child: Column( 73 | mainAxisAlignment: MainAxisAlignment.center, 74 | children: [ 75 | LinearProgressIndicator( 76 | value: _progress, 77 | ), 78 | RaisedButton( 79 | child: Text(_recoding ? "停止录音" : "开始录音"), 80 | onPressed: record, 81 | color: Theme.of(context).primaryColor, 82 | ), 83 | ], 84 | )), 85 | ), 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_tai 2 | 3 | 腾讯云智聆口语评测(Smart Oral Evaluation,SOE)是腾讯云推出的语音评测产品,是基于口语类教育培训场景和腾讯云的语音处理技术,应用特征提取、声学模型和语音识别算法,为儿童和成人提供高准确度的口语发音评测。支持单词、句子和段落模式的评测,多维度反馈口语表现,可广泛应用于中文及英语口语类教学中。 4 | 5 | 6 | ## Getting Started 7 | 8 | 9 | ```dart 10 | import 'package:flutter/material.dart'; 11 | import 'dart:async'; 12 | 13 | import 'package:flutter/services.dart'; 14 | import 'package:flutter_tai/flutter_tai.dart'; 15 | 16 | import 'PermissionUtil.dart'; 17 | 18 | void main() => runApp(MyApp()); 19 | 20 | class MyApp extends StatefulWidget { 21 | @override 22 | _MyAppState createState() => _MyAppState(); 23 | } 24 | 25 | class _MyAppState extends State { 26 | FlutterTai _tai = FlutterTai(); 27 | int _volume = 0; 28 | bool _recoding = false; 29 | double _progress = 0; 30 | 31 | @override 32 | void initState() { 33 | super.initState(); 34 | _tai.responseFromProgress.listen((data) { 35 | _volume = data.volume; 36 | _progress = _volume / 120; 37 | setState(() {}); 38 | print("音量:${data.volume} $_progress}"); 39 | }); 40 | _tai.responseFromStop.listen((data) { 41 | setState(() { 42 | _recoding = false; 43 | }); 44 | print("stop:${data.err}"); 45 | }); 46 | _tai.responseFromResult.listen((data) { 47 | print("result:${data.err}"); 48 | }); 49 | _tai.responseFromEvaluationData.listen((data) { 50 | print( 51 | "EvaluationData:err:${data.err} ret:${data.ret} end:${data.end} seqId:${data.seqId} "); 52 | }); 53 | } 54 | 55 | Future record() async { 56 | _recoding = true; 57 | setState(() {}); 58 | // Android SDK 参考https://cloud.tencent.com/document/product/884/31870 59 | try { 60 | await _tai.record("appId", "secretId", 61 | "secretKey", "how are you"); 62 | } on PlatformException {} 63 | } 64 | 65 | @override 66 | Widget build(BuildContext context) { 67 | return MaterialApp( 68 | home: Scaffold( 69 | appBar: AppBar( 70 | title: const Text('Plugin example app'), 71 | ), 72 | body: Center( 73 | child: Column( 74 | mainAxisAlignment: MainAxisAlignment.center, 75 | children: [ 76 | LinearProgressIndicator( 77 | value: _progress, 78 | ), 79 | RaisedButton( 80 | child: Text(_recoding ? "停止录音" : "开始录音"), 81 | onPressed: record, 82 | color: Theme.of(context).primaryColor, 83 | ), 84 | ], 85 | )), 86 | ), 87 | ); 88 | } 89 | } 90 | 91 | ``` 92 | 93 | This project is a starting point for a Flutter 94 | [plug-in package](https://flutter.dev/developing-packages/), 95 | a specialized package that includes platform-specific implementation code for 96 | Android and/or iOS. 97 | 98 | For help getting started with Flutter, view our 99 | [online documentation](https://flutter.dev/docs), which offers tutorials, 100 | samples, guidance on mobile development, and a full API reference. 101 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/flutter_tai.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter_tai/response.dart'; 5 | import 'package:uuid/uuid.dart'; 6 | 7 | class FlutterTai { 8 | final MethodChannel _channel = MethodChannel('flutter_tai') 9 | ..setMethodCallHandler(_handler); 10 | static final _uuid = new Uuid(); 11 | String id; 12 | static final alis = new Map(); 13 | 14 | FlutterTai() { 15 | id = _uuid.v4(); 16 | alis[id] = this; 17 | } 18 | 19 | StreamController _responseProgressController = 20 | new StreamController.broadcast(); 21 | 22 | Stream get responseFromProgress => 23 | _responseProgressController.stream; 24 | 25 | StreamController _responseResultController = 26 | new StreamController.broadcast(); 27 | 28 | Stream get responseFromResult => 29 | _responseResultController.stream; 30 | 31 | StreamController _responseStopController = 32 | new StreamController.broadcast(); 33 | 34 | Stream get responseFromStop => _responseStopController.stream; 35 | 36 | StreamController _responseEvaluationDataController = 37 | new StreamController.broadcast(); 38 | 39 | Stream get responseFromEvaluationData => 40 | _responseEvaluationDataController.stream; 41 | 42 | Future _invokeMethod(String method, 43 | [Map arguments = const {}]) { 44 | Map withId = Map.of(arguments); 45 | withId['id'] = id; 46 | return _channel.invokeMethod(method, withId); 47 | } 48 | 49 | static Future _handler(MethodCall methodCall) { 50 | String id = (methodCall.arguments as Map)['id']; 51 | FlutterTai _tai = alis[id]; 52 | 53 | switch (methodCall.method) { 54 | case "onProgress": 55 | ProgressResponse res = new ProgressResponse( 56 | volume: int.parse(methodCall.arguments["volume"].toString())); 57 | _tai._responseProgressController.add(res); 58 | break; 59 | case "onResult": 60 | ResultResponse res = 61 | new ResultResponse(err: methodCall.arguments["err"].toString()); 62 | _tai._responseResultController.add(res); 63 | break; 64 | case "onEvaluationData": 65 | EvaluationDataResponse res = new EvaluationDataResponse( 66 | seqId: int.parse(methodCall.arguments["seqId"].toString()), 67 | end: int.parse(methodCall.arguments["end"].toString()), 68 | err: methodCall.arguments["err"].toString(), 69 | ret: methodCall.arguments["ret"].toString(), 70 | ); 71 | _tai._responseEvaluationDataController.add(res); 72 | break; 73 | case "onStop": 74 | StopResponse res = 75 | new StopResponse(err: methodCall.arguments["err"].toString()); 76 | _tai._responseStopController.add(res); 77 | break; 78 | } 79 | } 80 | Future stop()async{ 81 | await _invokeMethod('stop'); 82 | } 83 | Future record(String appId, String secretId, String secretKey, String refText, 84 | {String soeAppId = "", 85 | String token = "", 86 | int workMode = TAIOralEvaluationWorkMode.STREAM, 87 | int evalMode = TAIOralEvaluationEvalMode.FREE, 88 | int storageMode = TAIOralEvaluationStorageMode.ENABLE, 89 | int serverType = TAIOralEvaluationServerType.ENGLISH, 90 | int textMode = TAIOralEvaluationTextMode.NORMAL, 91 | double scoreCoeff = 1, 92 | int timeout = -1, 93 | int retryTimes = -1, 94 | double fragSize = 1, 95 | bool fragEnable = true, 96 | bool vadEnable = true, 97 | int vadInterval = 3000}) async { 98 | if (workMode == TAIOralEvaluationWorkMode.STREAM) { 99 | timeout = timeout == -1 ? 5 : timeout; 100 | retryTimes = retryTimes == -1 ? 5 : retryTimes; 101 | } else { 102 | timeout = timeout == -1 ? 5 : timeout; 103 | retryTimes = retryTimes == -1 ? 5 : retryTimes; 104 | } 105 | fragSize = fragSize * 1024; 106 | await _invokeMethod('record', { 107 | "appId": appId, 108 | "secretId": secretId, 109 | "secretKey": secretKey, 110 | "refText": refText, 111 | "soeAppId": soeAppId, 112 | "token": token, 113 | "workMode": workMode, 114 | "evalMode": evalMode, 115 | "storageMode": storageMode, 116 | "serverType": serverType, 117 | "serverType": serverType, 118 | "textMode": textMode, 119 | "scoreCoeff": scoreCoeff, 120 | "timeout": timeout, 121 | "retryTimes": retryTimes, 122 | "fragSize": fragSize.toInt(), 123 | "fragEnable": fragEnable, 124 | "vadEnable": vadEnable, 125 | "vadInterval": vadInterval 126 | }); 127 | } 128 | } 129 | 130 | class TAIOralEvaluationWorkMode { 131 | /** 132 | * 流式传输 133 | */ 134 | static const int STREAM = 0; 135 | 136 | /** 137 | * 一次性传输 138 | */ 139 | static const int ONCE = 1; 140 | } 141 | 142 | class TAIOralEvaluationEvalMode { 143 | /** 144 | * 单词模式 145 | */ 146 | static const int WORD = 0; 147 | 148 | /** 149 | * 句子模式 150 | */ 151 | static const int SENTENCE = 1; 152 | 153 | /** 154 | * 段落模式 155 | */ 156 | static const int PARAGRAPH = 2; 157 | 158 | /** 159 | * 自由说模式 160 | */ 161 | static const int FREE = 3; 162 | } 163 | 164 | class TAIOralEvaluationStorageMode { 165 | static const int DISABLE = 0; 166 | static const int ENABLE = 1; 167 | } 168 | 169 | class TAIOralEvaluationServerType { 170 | static const int ENGLISH = 0; 171 | static const int CHINESE = 1; 172 | } 173 | 174 | class TAIOralEvaluationTextMode { 175 | /** 176 | * 普通文本 177 | */ 178 | static const int NORMAL = 0; 179 | 180 | /** 181 | * 音素结构文本 182 | */ 183 | static const int PHONEME = 1; 184 | } 185 | -------------------------------------------------------------------------------- /ios/Frameworks/TAISDK.framework/Headers/TAIOralEvaluation.h: -------------------------------------------------------------------------------- 1 | // 2 | // TAIOralEvaluation.h 3 | // TAISDK 4 | // 5 | // Created by kennethmiao on 2018/12/25. 6 | // Copyright © 2018年 kennethmiao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TAICommonParam.h" 11 | #import "TAIError.h" 12 | 13 | typedef NS_ENUM(NSInteger, TAIOralEvaluationWorkMode) 14 | { 15 | //流式传输 16 | TAIOralEvaluationWorkMode_Stream = 0, 17 | //一次性传输 18 | TAIOralEvaluationWorkMode_Once, 19 | }; 20 | 21 | typedef NS_ENUM(NSInteger, TAIOralEvaluationTextMode) 22 | { 23 | //普通文本 24 | TAIOralEvaluationTextMode_Noraml = 0, 25 | //音素结构文本 26 | TAIOralEvaluationTextMode_Phoneme, 27 | }; 28 | 29 | 30 | typedef NS_ENUM(NSInteger, TAIOralEvaluationEvalMode) 31 | { 32 | //单词模式 33 | TAIOralEvaluationEvalMode_Word = 0, 34 | //句子模式 35 | TAIOralEvaluationEvalMode_Sentence, 36 | //段落模式 37 | TAIOralEvaluationEvalMode_Paragraph, 38 | //自由模式 39 | TAIOralEvaluationEvalMode_Free, 40 | }; 41 | 42 | typedef NS_ENUM(NSInteger, TAIOralEvaluationFileType) 43 | { 44 | //pcm 45 | TAIOralEvaluationFileType_Raw = 1, 46 | //wav 47 | TAIOralEvaluationFileType_Wav, 48 | //mp3 49 | TAIOralEvaluationFileType_Mp3, 50 | }; 51 | 52 | typedef NS_ENUM(NSInteger, TAIOralEvaluationStorageMode) 53 | { 54 | //关闭存储 55 | TAIOralEvaluationStorageMode_Disable = 0, 56 | //开启存储 57 | TAIOralEvaluationStorageMode_Enable, 58 | }; 59 | 60 | typedef NS_ENUM(NSInteger, TAIOralEvaluationServerType) 61 | { 62 | //英文 63 | TAIOralEvaluationServerType_English = 0, 64 | //中文 65 | TAIOralEvaluationServerType_Chinese, 66 | }; 67 | 68 | @interface TAIOralEvaluationParam : TAICommonParam 69 | //业务应用id(默认为default) 70 | @property (nonatomic, strong) NSString *soeAppId; 71 | //唯一标识一次评测 72 | @property (nonatomic, strong) NSString *sessionId; 73 | //传输模式 74 | @property (nonatomic, assign) TAIOralEvaluationWorkMode workMode; 75 | //评估模式 76 | @property (nonatomic, assign) TAIOralEvaluationEvalMode evalMode; 77 | //数据类型(内部录制仅支持mp3) 78 | @property (nonatomic, assign) TAIOralEvaluationFileType fileType; 79 | //音频存储 80 | @property (nonatomic, assign) TAIOralEvaluationStorageMode storageMode; 81 | //语言类型 82 | @property (nonatomic, assign) TAIOralEvaluationServerType serverType; 83 | //文本模式 84 | @property (nonatomic, assign) TAIOralEvaluationTextMode textMode; 85 | //苛刻指数[1.0-4.0] 86 | @property (nonatomic, assign) float scoreCoeff; 87 | //被评估的文本 88 | @property (nonatomic, strong) NSString *refText; 89 | @end 90 | 91 | 92 | @interface TAIOralEvaluationPhoneInfo : NSObject 93 | //当前音节语音起始时间点,单位为ms 94 | @property (nonatomic, assign) int beginTime; 95 | //当前音节语音终止时间点,单位为ms 96 | @property (nonatomic, assign) int endTime; 97 | //音节发音准确度,取值范围[-1, 100],当取-1时指完全不匹配 98 | @property (nonatomic, assign) float pronAccuracy; 99 | //当前音节是否检测为重音 100 | @property (nonatomic, assign) BOOL detectedStress; 101 | //当前音节 102 | @property (nonatomic, strong) NSString *phone; 103 | //当前音节是否应为重音 104 | @property (nonatomic, assign) BOOL stress; 105 | @end 106 | 107 | @interface TAIOralEvaluationWord : NSObject 108 | //当前单词语音起始时间点,单位为ms 109 | @property (nonatomic, assign) int beginTime; 110 | //当前单词语音终止时间点,单位为ms 111 | @property (nonatomic, assign) int endTime; 112 | //单词发音准确度,取值范围[-1, 100],当取-1时指完全不匹配 113 | @property (nonatomic, assign) float pronAccuracy; 114 | //单词发音流利度,取值范围[0, 1] 115 | @property (nonatomic, assign) float pronFluency; 116 | //当前词 117 | @property (nonatomic, strong) NSString *word; 118 | //当前词与输入语句的匹配情况,0:匹配单词、1:新增单词、2:缺少单词 119 | @property (nonatomic, assign) int matchTag; 120 | //音节评估详情 121 | @property (nonatomic, strong) NSArray *phoneInfos; 122 | @end 123 | 124 | @interface TAIOralEvaluationRet : NSObject 125 | //唯一标识一次评测 126 | @property (nonatomic, strong) NSString *sessionId; 127 | //单词发音准确度,取值范围[-1, 100],当取-1时指完全不匹配 128 | @property (nonatomic, assign) float pronAccuracy; 129 | //单词发音流利度,取值范围[0, 1] 130 | @property (nonatomic, assign) float pronFluency; 131 | //发音完整度,取值范围[0, 1],当为词模式时,取值无意义 132 | @property (nonatomic, assign) float pronCompletion; 133 | //保存语音音频文件的下载地址(TAIOralEvaluationStorageMode_Enable有效) 134 | @property (nonatomic, strong) NSString *audioUrl; 135 | //详细发音评估结果 136 | @property (nonatomic, strong) NSArray *words; 137 | //建议评分,取值范围[0,100] 138 | //评分方式为建议评分 = 准确度(PronAccuracyfloat)× 完整度(PronCompletionfloat)×(2 - 完整度(PronCompletionfloat)) 139 | //如若评分策略不符合请参考Words数组中的详细分数自定义评分逻辑。 140 | @property (nonatomic, assign) float suggestedScore; 141 | @end 142 | 143 | @interface TAIOralEvaluationData : NSObject 144 | //数据seq,从1开始 145 | @property (nonatomic, assign) NSInteger seqId; 146 | //属否是最后分片数据 147 | @property (nonatomic, assign) BOOL bEnd; 148 | //音频数据 149 | @property (nonatomic, strong) NSData *audio; 150 | @end 151 | 152 | @interface TAIRecorderParam : NSObject 153 | //是否开启分片,默认YES 154 | @property (nonatomic, assign) BOOL fragEnable; 155 | //分片大小,默认1024,建议为1024的整数倍,范围【1k-10k】 156 | @property (nonatomic, assign) NSInteger fragSize; 157 | //是否开启静音检测,默认NO 158 | @property (nonatomic, assign) BOOL vadEnable; 159 | //静音检测时间间隔,单位【ms】 160 | @property (nonatomic, assign) NSInteger vadInterval; 161 | @end 162 | 163 | @class TAIOralEvaluation; 164 | @protocol TAIOralEvaluationDelegate 165 | /** 166 | * 评估结果回调 167 | * @param oralEvaluation 评测对象 168 | * @param data 音频数据 169 | * @param result 评估结果(最后一个分片返回,其他分片为nil) 170 | * @param error 错误信息 171 | */ 172 | - (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation 173 | onEvaluateData:(TAIOralEvaluationData *)data 174 | result:(TAIOralEvaluationRet *)result 175 | error:(TAIError *)error; 176 | /** 177 | * 静音检测回调 178 | * @param oralEvaluation 评测对象 179 | * @brief 检测到静音内部不会停止录制,业务层可以根据此回调主动停止录制或提示用户 180 | */ 181 | - (void)onEndOfSpeechInOralEvaluation:(TAIOralEvaluation *)oralEvaluation; 182 | /** 183 | * 音量分贝变化 184 | * @param oralEvaluation 评测对象 185 | * @param volume 分贝大小 186 | * @brief volume范围【0-120】 187 | */ 188 | - (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation onVolumeChanged:(NSInteger)volume; 189 | @end 190 | 191 | typedef void (^TAIOralEvaluationCallback)(TAIError *error); 192 | 193 | @interface TAIOralEvaluation : NSObject 194 | /** 195 | * 录制数据回调 196 | */ 197 | @property (nonatomic, weak) id delegate; 198 | /** 199 | * 开始录制和评测 200 | * @param param 参数(内部录制仅支持mp3) 201 | * @param callback 回调 202 | */ 203 | - (void)startRecordAndEvaluation:(TAIOralEvaluationParam *)param callback:(TAIOralEvaluationCallback)callback; 204 | /** 205 | * 结束录制和评测 206 | * @param callback 回调 207 | */ 208 | - (void)stopRecordAndEvaluation:(TAIOralEvaluationCallback)callback; 209 | /** 210 | * 属否正在录制 211 | * @return BOOL 是否录制 212 | */ 213 | - (BOOL)isRecording; 214 | /** 215 | * 设置分片大小,建议为1024的整数倍,范围【1k-10k】,默认为1024*1 216 | * @param size 分片大小 217 | */ 218 | - (void)setFragSize:(NSInteger)size DEPRECATED_MSG_ATTRIBUTE("Please usee setRecordParam:"); 219 | 220 | /** 221 | * 设置录制参数 222 | * @param param 录制参数 223 | */ 224 | - (void)setRecorderParam:(TAIRecorderParam *)param; 225 | /** 226 | * 口语评测(外部录制) 227 | * @param param 参数 228 | * @param data 音频数据(三种格式目前仅支持16k采样率16bit编码单声道,如有不一致可能导致评估不准确或失败) 229 | * @param callback 回调 230 | */ 231 | - (void)oralEvaluation:(TAIOralEvaluationParam *)param data:(TAIOralEvaluationData *)data callback:(TAIOralEvaluationCallback)callback; 232 | /** 233 | * 获取签名所需字符串 234 | * @param timestamp 时间戳 235 | * @return NSString 签名 236 | */ 237 | - (NSString *)getStringToSign:(NSInteger)timestamp; 238 | @end 239 | -------------------------------------------------------------------------------- /ios/Classes/FlutterTaiPlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterTaiPlugin.h" 2 | #import 3 | #import 4 | 5 | @interface FlutterTaiPlugin () 6 | @property (strong, nonatomic) TAIOralEvaluation *oralEvaluation; 7 | @property (strong, nonatomic) NSString *fileName; 8 | 9 | @end 10 | @implementation FlutterTaiPlugin 11 | FlutterMethodChannel *flutterTaiPluginChannel; 12 | NSString *flutterTaiPluginId; 13 | 14 | + (void)registerWithRegistrar:(NSObject*)registrar { 15 | flutterTaiPluginChannel = [FlutterMethodChannel 16 | methodChannelWithName:@"flutter_tai" 17 | binaryMessenger:[registrar messenger]]; 18 | FlutterTaiPlugin* instance = [[FlutterTaiPlugin alloc] init]; 19 | [registrar addMethodCallDelegate:instance channel:flutterTaiPluginChannel]; 20 | } 21 | - (TAIOralEvaluation *)oralEvaluation 22 | { 23 | if(!_oralEvaluation){ 24 | _oralEvaluation = [[TAIOralEvaluation alloc] init]; 25 | _oralEvaluation.delegate = self; 26 | } 27 | return _oralEvaluation; 28 | } 29 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 30 | if ([@"record" isEqualToString:call.method]) { 31 | [self onRecord:call result:result]; 32 | } else if ([@"stop" isEqualToString:call.method]) { 33 | [self onStop:call result:result]; 34 | } else { 35 | result(FlutterMethodNotImplemented); 36 | } 37 | } 38 | - (IBAction)onStop:(FlutterMethodCall*)call result:(FlutterResult)result{ 39 | flutterTaiPluginId =call.arguments[@"id"]; 40 | if([self.oralEvaluation isRecording]){ 41 | [self.oralEvaluation stopRecordAndEvaluation:^(TAIError *error) { 42 | [flutterTaiPluginChannel invokeMethod:@"onStop" arguments:@{ 43 | @"err": [NSString stringWithFormat:@"%@", error], 44 | @"id":flutterTaiPluginId 45 | }]; 46 | }]; 47 | return; 48 | } 49 | } 50 | - (IBAction)onRecord:(FlutterMethodCall*)call result:(FlutterResult)result{ 51 | flutterTaiPluginId =call.arguments[@"id"]; 52 | if([self.oralEvaluation isRecording]){ 53 | [self.oralEvaluation stopRecordAndEvaluation:^(TAIError *error) { 54 | [flutterTaiPluginChannel invokeMethod:@"onStop" arguments:@{ 55 | @"err": [NSString stringWithFormat:@"%@", error], 56 | @"id":flutterTaiPluginId 57 | }]; 58 | }]; 59 | return; 60 | }else{ 61 | _fileName = [NSString stringWithFormat:@"taisdk_%ld.mp3", (long)[[NSDate date] timeIntervalSince1970]]; 62 | 63 | 64 | TAIOralEvaluationParam *param = [[TAIOralEvaluationParam alloc] init]; 65 | param.sessionId = [[NSUUID UUID] UUIDString]; 66 | param.appId = call.arguments[@"appId"]; 67 | 68 | param.soeAppId = call.arguments[@"soeAppId"]; 69 | param.secretId = call.arguments[@"secretId"]; 70 | param.secretKey = call.arguments[@"secretKey"]; 71 | param.token = call.arguments[@"token"]; 72 | param.workMode = [call.arguments[@"workMode"] intValue]; 73 | param.evalMode = [call.arguments[@"evalMode"] intValue]; 74 | param.serverType = [call.arguments[@"serverType"] intValue]; 75 | 76 | param.fileType = TAIOralEvaluationFileType_Mp3; 77 | param.storageMode = [call.arguments[@"storageMode"] intValue]; 78 | param.textMode = [call.arguments[@"textMode"] intValue]; 79 | param.scoreCoeff = [call.arguments[@"scoreCoeff"] intValue]; 80 | param.refText = call.arguments[@"refText"]; 81 | if(param.workMode == TAIOralEvaluationWorkMode_Stream){ 82 | param.timeout = (NSInteger)call.arguments[@"timeout"]; 83 | param.retryTimes = (NSInteger)call.arguments[@"retryTimes"]; 84 | } 85 | else{ 86 | param.timeout = (NSInteger)call.arguments[@"timeout"]; 87 | param.retryTimes = (NSInteger)call.arguments[@"retryTimes"]; 88 | } 89 | TAIRecorderParam *recordParam = [[TAIRecorderParam alloc] init]; 90 | recordParam.fragEnable = [call.arguments[@"fragEnable"] boolValue]; 91 | recordParam.fragSize = [call.arguments[@"fragSize"] intValue]; 92 | recordParam.vadEnable =[call.arguments[@"vadEnable"] boolValue]; 93 | recordParam.vadInterval = [call.arguments[@"vadInterval"] intValue]; 94 | [self.oralEvaluation setRecorderParam:recordParam]; 95 | [self.oralEvaluation startRecordAndEvaluation:param callback:^(TAIError *error) { 96 | [flutterTaiPluginChannel invokeMethod:@"onResult" arguments:@{@"id":flutterTaiPluginId,@"err":[NSString stringWithFormat:@"%@", error]}]; 97 | }]; 98 | } 99 | } 100 | #pragma mark - oral evaluation delegate 101 | - (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation onEvaluateData:(TAIOralEvaluationData *)data result:(TAIOralEvaluationRet *)result error:(TAIError *)error 102 | { 103 | [self writeMP3Data:data.audio fileName:_fileName]; 104 | if(result!=nil){ 105 | NSDictionary *dic=[self getDictionaryFromObject_Ext:result]; 106 | NSData * jsonData=[NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil]; 107 | NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 108 | [flutterTaiPluginChannel invokeMethod:@"onEvaluationData" arguments:@{@"id":flutterTaiPluginId,@"seqId":[NSString stringWithFormat:@"%ld", (long)data.seqId],@"end":[NSString stringWithFormat:@"%ld", (long)data.bEnd], @"err":[NSString stringWithFormat:@"%@", error],@"ret":jsonString}]; 109 | } 110 | } 111 | - (NSDictionary*)getDictionaryFromObject_Ext:(id)obj 112 | { 113 | NSMutableDictionary *dic = [NSMutableDictionary dictionary]; 114 | unsigned int propsCount; 115 | objc_property_t *props = class_copyPropertyList([obj class], &propsCount); 116 | for(int i = 0;i < propsCount; i++) { 117 | objc_property_t prop = props[i]; 118 | id value = nil; 119 | 120 | @try { 121 | NSString *propName = [NSString stringWithUTF8String:property_getName(prop)]; 122 | value = [self getObjectInternal_Ext:[obj valueForKey:propName]]; 123 | if(value != nil) { 124 | [dic setObject:value forKey:propName]; 125 | } 126 | } 127 | @catch (NSException *exception) { 128 | //[self logError:exception]; 129 | NSLog(@"%@",exception); 130 | } 131 | 132 | } 133 | free(props); 134 | return dic; 135 | } 136 | - (id)getObjectInternal_Ext:(id)obj 137 | { 138 | if(!obj 139 | || [obj isKindOfClass:[NSString class]] 140 | || [obj isKindOfClass:[NSNumber class]] 141 | || [obj isKindOfClass:[NSNull class]]) { 142 | return obj; 143 | } 144 | 145 | if([obj isKindOfClass:[NSArray class]]) { 146 | NSArray *objarr = obj; 147 | NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count]; 148 | for(int i = 0;i < objarr.count; i++) { 149 | [arr setObject:[self getObjectInternal_Ext:[objarr objectAtIndex:i]] atIndexedSubscript:i]; 150 | } 151 | return arr; 152 | } 153 | 154 | if([obj isKindOfClass:[NSDictionary class]]) { 155 | NSDictionary *objdic = obj; 156 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]]; 157 | for(NSString *key in objdic.allKeys) { 158 | [dic setObject:[self getObjectInternal_Ext:[objdic objectForKey:key]] forKey:key]; 159 | } 160 | return dic; 161 | } 162 | return [self getDictionaryFromObject_Ext:obj]; 163 | } 164 | - (void)onEndOfSpeechInOralEvaluation:(TAIOralEvaluation *)oralEvaluation 165 | { 166 | } 167 | 168 | - (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation onVolumeChanged:(NSInteger)volume 169 | { 170 | [flutterTaiPluginChannel invokeMethod:@"onProgress" arguments:@{@"id":flutterTaiPluginId,@"volume": [NSString stringWithFormat:@"%ld",volume]}]; 171 | } 172 | - (void)writeMP3Data:(NSData *)data fileName:(NSString *)fileName 173 | { 174 | NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 175 | NSString *mp3Path = [path stringByAppendingPathComponent:fileName]; 176 | if([[NSFileManager defaultManager] fileExistsAtPath:mp3Path] == false){ 177 | [[NSFileManager defaultManager] createFileAtPath:mp3Path contents:nil attributes:nil]; 178 | } 179 | NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:mp3Path]; 180 | [handle seekToEndOfFile]; 181 | [handle writeData:data]; 182 | } 183 | @end 184 | -------------------------------------------------------------------------------- /android/src/main/java/com/jlcool/flutter_tai/FlutterTaiPlugin.java: -------------------------------------------------------------------------------- 1 | package com.jlcool.flutter_tai; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.pm.PackageManager; 7 | import android.os.Environment; 8 | import android.text.TextUtils; 9 | import android.view.View; 10 | 11 | import androidx.core.app.ActivityCompat; 12 | import androidx.core.content.ContextCompat; 13 | 14 | import io.flutter.plugin.common.MethodCall; 15 | import io.flutter.plugin.common.MethodChannel; 16 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 17 | import io.flutter.plugin.common.MethodChannel.Result; 18 | import io.flutter.plugin.common.PluginRegistry.Registrar; 19 | 20 | import com.google.gson.Gson; 21 | import com.tencent.taisdk.TAIErrCode; 22 | import com.tencent.taisdk.TAIError; 23 | import com.tencent.taisdk.TAIOralEvaluation; 24 | import com.tencent.taisdk.TAIOralEvaluationCallback; 25 | import com.tencent.taisdk.TAIOralEvaluationData; 26 | import com.tencent.taisdk.TAIOralEvaluationEvalMode; 27 | import com.tencent.taisdk.TAIOralEvaluationFileType; 28 | import com.tencent.taisdk.TAIOralEvaluationListener; 29 | import com.tencent.taisdk.TAIOralEvaluationParam; 30 | import com.tencent.taisdk.TAIOralEvaluationRet; 31 | import com.tencent.taisdk.TAIOralEvaluationServerType; 32 | import com.tencent.taisdk.TAIOralEvaluationStorageMode; 33 | import com.tencent.taisdk.TAIOralEvaluationTextMode; 34 | import com.tencent.taisdk.TAIOralEvaluationWorkMode; 35 | import com.tencent.taisdk.TAIRecorderParam; 36 | 37 | import java.io.File; 38 | import java.io.FileOutputStream; 39 | import java.io.IOException; 40 | import java.io.RandomAccessFile; 41 | import java.util.HashMap; 42 | import java.util.Map; 43 | import java.util.UUID; 44 | 45 | /** 46 | * FlutterTaiPlugin 47 | */ 48 | public class FlutterTaiPlugin implements MethodCallHandler { 49 | private static Context _context; 50 | private static MethodChannel _channel; 51 | private final Activity activity; 52 | /** 53 | * Plugin registration. 54 | */ 55 | public static void registerWith(Registrar registrar) { 56 | _context = registrar.context(); 57 | _channel = new MethodChannel(registrar.messenger(), "flutter_tai"); 58 | _channel.setMethodCallHandler(new FlutterTaiPlugin(registrar, registrar.activity())); 59 | } 60 | private FlutterTaiPlugin(Registrar registrar, Activity activity) { 61 | this.activity=activity; 62 | } 63 | private TAIOralEvaluation _oral; 64 | 65 | @Override 66 | public void onMethodCall(MethodCall call, Result result) { 67 | if (call.method.equals("record")) { 68 | onRecord(call, result); 69 | } else if (call.method.equals("stop")) { 70 | onStop(call, result); 71 | } else{ 72 | result.notImplemented(); 73 | } 74 | } 75 | 76 | public void onStop(final MethodCall call, final Result result) { 77 | final String _id= call.argument("id"); 78 | if (_oral!=null && _oral.isRecording()) { 79 | _oral.stopRecordAndEvaluation(new TAIOralEvaluationCallback() { 80 | @Override 81 | public void onResult(final TAIError error) { 82 | Gson gson = new Gson(); 83 | String string = gson.toJson(error); 84 | final Map _data = new HashMap(); 85 | _data.put("id", _id); 86 | _data.put("err", string); 87 | activity.runOnUiThread( 88 | new Runnable() { 89 | @Override 90 | public void run() { 91 | _channel.invokeMethod("onStop", _data); 92 | } 93 | }); 94 | 95 | } 96 | }); 97 | } 98 | } 99 | public void onRecord(final MethodCall call, final Result result) { 100 | 101 | final Result _result = result; 102 | final String _id= call.argument("id"); 103 | if (_oral == null) { 104 | _oral = new TAIOralEvaluation(); 105 | } 106 | if (_oral.isRecording()) { 107 | _oral.stopRecordAndEvaluation(new TAIOralEvaluationCallback() { 108 | @Override 109 | public void onResult(final TAIError error) { 110 | Gson gson = new Gson(); 111 | String string = gson.toJson(error); 112 | final Map _data = new HashMap(); 113 | _data.put("id", _id); 114 | _data.put("err", string); 115 | activity.runOnUiThread( 116 | new Runnable() { 117 | @Override 118 | public void run() { 119 | _channel.invokeMethod("onStop", _data); 120 | } 121 | }); 122 | 123 | } 124 | }); 125 | } else { 126 | final String mp3FileName = String.format("taisdk_%d.mp3", System.currentTimeMillis() / 1000); 127 | _oral.setListener(new TAIOralEvaluationListener() { 128 | @Override 129 | public void onEvaluationData(final TAIOralEvaluationData data, final TAIOralEvaluationRet result, final TAIError error) { 130 | writeFileToSDCard(data.audio, "com.tencent.taidemo", mp3FileName, true, false); 131 | Gson gson = new Gson(); 132 | String errString = gson.toJson(error); 133 | String retString = gson.toJson(result); 134 | final Map _data = new HashMap(); 135 | _data.put("seqId", String.valueOf(data.seqId)); 136 | _data.put("end", String.valueOf(data.bEnd ? 1 : 0)); 137 | _data.put("err", errString); 138 | _data.put("ret", retString); 139 | _data.put("id", _id); 140 | activity.runOnUiThread( 141 | new Runnable() { 142 | @Override 143 | public void run() { 144 | _channel.invokeMethod("onEvaluationData", _data); 145 | } 146 | }); 147 | 148 | } 149 | 150 | @Override 151 | public void onEndOfSpeech() { 152 | onRecord(call, result); 153 | } 154 | 155 | @Override 156 | public void onVolumeChanged(final int volume) { 157 | final Map _data = new HashMap(); 158 | _data.put("volume", String.valueOf(volume)); 159 | _data.put("id", _id); 160 | activity.runOnUiThread( 161 | new Runnable() { 162 | @Override 163 | public void run() { 164 | _channel.invokeMethod("onProgress", _data); 165 | } 166 | }); 167 | 168 | } 169 | }); 170 | 171 | TAIOralEvaluationParam param = new TAIOralEvaluationParam(); 172 | param.context = _context; 173 | param.sessionId = UUID.randomUUID().toString(); 174 | param.appId = call.argument("appId"); 175 | param.soeAppId = call.argument("soeAppId"); 176 | param.secretId = call.argument("secretId"); 177 | param.secretKey = call.argument("secretKey"); 178 | param.token = call.argument("token"); 179 | 180 | param.workMode = call.argument("workMode"); 181 | param.evalMode = call.argument("evalMode"); 182 | param.storageMode = call.argument("storageMode"); 183 | param.fileType = TAIOralEvaluationFileType.MP3; 184 | param.serverType = call.argument("serverType"); 185 | param.textMode = call.argument("textMode"); 186 | param.scoreCoeff = call.argument("scoreCoeff"); 187 | param.refText = call.argument("refText"); 188 | if (param.workMode == TAIOralEvaluationWorkMode.STREAM) { 189 | param.timeout = call.argument("timeout"); 190 | param.retryTimes = call.argument("retryTimes"); 191 | } else { 192 | param.timeout = call.argument("timeout"); 193 | param.retryTimes = call.argument("retryTimes"); 194 | } 195 | TAIRecorderParam recordParam = new TAIRecorderParam(); 196 | recordParam.fragSize = call.argument("fragSize"); 197 | recordParam.fragEnable = call.argument("fragEnable"); 198 | recordParam.vadEnable = call.argument("vadEnable"); 199 | recordParam.vadInterval = call.argument("vadInterval"); 200 | _oral.setRecorderParam(recordParam); 201 | _oral.startRecordAndEvaluation(param, new TAIOralEvaluationCallback() { 202 | @Override 203 | public void onResult(final TAIError error) { 204 | Gson gson = new Gson(); 205 | String string = gson.toJson(error); 206 | final Map _data = new HashMap(); 207 | _data.put("err", string); 208 | _data.put("id", _id); 209 | activity.runOnUiThread( 210 | new Runnable() { 211 | @Override 212 | public void run() { 213 | _channel.invokeMethod("onResult", _data); 214 | } 215 | }); 216 | 217 | } 218 | }); 219 | } 220 | } 221 | 222 | public synchronized static void writeFileToSDCard(final byte[] buffer, final String folder, 223 | final String fileName, final boolean append, final boolean autoLine) { 224 | new Thread(new Runnable() { 225 | @Override 226 | public void run() { 227 | boolean sdCardExist = Environment.getExternalStorageState().equals( 228 | android.os.Environment.MEDIA_MOUNTED); 229 | String folderPath = ""; 230 | if (sdCardExist) { 231 | //TextUtils为android自带的帮助类 232 | if (TextUtils.isEmpty(folder)) { 233 | //如果folder为空,则直接保存在sd卡的根目录 234 | folderPath = Environment.getExternalStorageDirectory() 235 | + File.separator; 236 | } else { 237 | folderPath = Environment.getExternalStorageDirectory() 238 | + File.separator + folder + File.separator; 239 | } 240 | } else { 241 | return; 242 | } 243 | 244 | 245 | File fileDir = new File(folderPath); 246 | if (!fileDir.exists()) { 247 | if (!fileDir.mkdirs()) { 248 | return; 249 | } 250 | } 251 | File file; 252 | //判断文件名是否为空 253 | if (TextUtils.isEmpty(fileName)) { 254 | file = new File(folderPath + "app_log.txt"); 255 | } else { 256 | file = new File(folderPath + fileName); 257 | } 258 | RandomAccessFile raf = null; 259 | FileOutputStream out = null; 260 | try { 261 | if (append) { 262 | //如果为追加则在原来的基础上继续写文件 263 | raf = new RandomAccessFile(file, "rw"); 264 | raf.seek(file.length()); 265 | raf.write(buffer); 266 | if (autoLine) { 267 | raf.write("\n".getBytes()); 268 | } 269 | } else { 270 | //重写文件,覆盖掉原来的数据 271 | out = new FileOutputStream(file); 272 | out.write(buffer); 273 | out.flush(); 274 | } 275 | } catch (IOException e) { 276 | e.printStackTrace(); 277 | } finally { 278 | try { 279 | if (raf != null) { 280 | raf.close(); 281 | } 282 | if (out != null) { 283 | out.close(); 284 | } 285 | } catch (IOException e) { 286 | e.printStackTrace(); 287 | } 288 | } 289 | } 290 | }).start(); 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 8C71B7AED1BABDD0811A6BCC /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FFF1B1AECC9ABDA0442FCBE /* libPods-Runner.a */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXCopyFilesBuildPhase section */ 26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 27 | isa = PBXCopyFilesBuildPhase; 28 | buildActionMask = 2147483647; 29 | dstPath = ""; 30 | dstSubfolderSpec = 10; 31 | files = ( 32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 34 | ); 35 | name = "Embed Frameworks"; 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXCopyFilesBuildPhase section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 43 | 2FFF1B1AECC9ABDA0442FCBE /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 67 | 8C71B7AED1BABDD0811A6BCC /* libPods-Runner.a in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | 8C150234F932C354FDE62792 /* Frameworks */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 2FFF1B1AECC9ABDA0442FCBE /* libPods-Runner.a */, 78 | ); 79 | name = Frameworks; 80 | sourceTree = ""; 81 | }; 82 | 9740EEB11CF90186004384FC /* Flutter */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 3B80C3931E831B6300D905FE /* App.framework */, 86 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 87 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 91 | ); 92 | name = Flutter; 93 | sourceTree = ""; 94 | }; 95 | 97C146E51CF9000F007C117D = { 96 | isa = PBXGroup; 97 | children = ( 98 | 9740EEB11CF90186004384FC /* Flutter */, 99 | 97C146F01CF9000F007C117D /* Runner */, 100 | 97C146EF1CF9000F007C117D /* Products */, 101 | D344ED0445818F538631D9CE /* Pods */, 102 | 8C150234F932C354FDE62792 /* Frameworks */, 103 | ); 104 | sourceTree = ""; 105 | }; 106 | 97C146EF1CF9000F007C117D /* Products */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 97C146EE1CF9000F007C117D /* Runner.app */, 110 | ); 111 | name = Products; 112 | sourceTree = ""; 113 | }; 114 | 97C146F01CF9000F007C117D /* Runner */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 118 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 119 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 120 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 121 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 122 | 97C147021CF9000F007C117D /* Info.plist */, 123 | 97C146F11CF9000F007C117D /* Supporting Files */, 124 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 125 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 126 | ); 127 | path = Runner; 128 | sourceTree = ""; 129 | }; 130 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 97C146F21CF9000F007C117D /* main.m */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | D344ED0445818F538631D9CE /* Pods */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | ); 142 | name = Pods; 143 | sourceTree = ""; 144 | }; 145 | /* End PBXGroup section */ 146 | 147 | /* Begin PBXNativeTarget section */ 148 | 97C146ED1CF9000F007C117D /* Runner */ = { 149 | isa = PBXNativeTarget; 150 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 151 | buildPhases = ( 152 | F3A9DC6A17248D79D94DAD23 /* [CP] Check Pods Manifest.lock */, 153 | 9740EEB61CF901F6004384FC /* Run Script */, 154 | 97C146EA1CF9000F007C117D /* Sources */, 155 | 97C146EB1CF9000F007C117D /* Frameworks */, 156 | 97C146EC1CF9000F007C117D /* Resources */, 157 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 158 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 159 | 712CE4C61B039F5E86D8CF98 /* [CP] Embed Pods Frameworks */, 160 | ); 161 | buildRules = ( 162 | ); 163 | dependencies = ( 164 | ); 165 | name = Runner; 166 | productName = Runner; 167 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 168 | productType = "com.apple.product-type.application"; 169 | }; 170 | /* End PBXNativeTarget section */ 171 | 172 | /* Begin PBXProject section */ 173 | 97C146E61CF9000F007C117D /* Project object */ = { 174 | isa = PBXProject; 175 | attributes = { 176 | LastUpgradeCheck = 0910; 177 | ORGANIZATIONNAME = "The Chromium Authors"; 178 | TargetAttributes = { 179 | 97C146ED1CF9000F007C117D = { 180 | CreatedOnToolsVersion = 7.3.1; 181 | DevelopmentTeam = YJV4N2CBA3; 182 | }; 183 | }; 184 | }; 185 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 186 | compatibilityVersion = "Xcode 3.2"; 187 | developmentRegion = English; 188 | hasScannedForEncodings = 0; 189 | knownRegions = ( 190 | en, 191 | Base, 192 | ); 193 | mainGroup = 97C146E51CF9000F007C117D; 194 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 195 | projectDirPath = ""; 196 | projectRoot = ""; 197 | targets = ( 198 | 97C146ED1CF9000F007C117D /* Runner */, 199 | ); 200 | }; 201 | /* End PBXProject section */ 202 | 203 | /* Begin PBXResourcesBuildPhase section */ 204 | 97C146EC1CF9000F007C117D /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 209 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 210 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 211 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 212 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | }; 216 | /* End PBXResourcesBuildPhase section */ 217 | 218 | /* Begin PBXShellScriptBuildPhase section */ 219 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 220 | isa = PBXShellScriptBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | ); 224 | inputPaths = ( 225 | ); 226 | name = "Thin Binary"; 227 | outputPaths = ( 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | shellPath = /bin/sh; 231 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 232 | }; 233 | 712CE4C61B039F5E86D8CF98 /* [CP] Embed Pods Frameworks */ = { 234 | isa = PBXShellScriptBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | ); 238 | inputFileListPaths = ( 239 | ); 240 | inputPaths = ( 241 | "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 242 | "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", 243 | ); 244 | name = "[CP] Embed Pods Frameworks"; 245 | outputFileListPaths = ( 246 | ); 247 | outputPaths = ( 248 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | shellPath = /bin/sh; 252 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 253 | showEnvVarsInLog = 0; 254 | }; 255 | 9740EEB61CF901F6004384FC /* Run Script */ = { 256 | isa = PBXShellScriptBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | ); 260 | inputPaths = ( 261 | ); 262 | name = "Run Script"; 263 | outputPaths = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | shellPath = /bin/sh; 267 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 268 | }; 269 | F3A9DC6A17248D79D94DAD23 /* [CP] Check Pods Manifest.lock */ = { 270 | isa = PBXShellScriptBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | ); 274 | inputFileListPaths = ( 275 | ); 276 | inputPaths = ( 277 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 278 | "${PODS_ROOT}/Manifest.lock", 279 | ); 280 | name = "[CP] Check Pods Manifest.lock"; 281 | outputFileListPaths = ( 282 | ); 283 | outputPaths = ( 284 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | shellPath = /bin/sh; 288 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 289 | showEnvVarsInLog = 0; 290 | }; 291 | /* End PBXShellScriptBuildPhase section */ 292 | 293 | /* Begin PBXSourcesBuildPhase section */ 294 | 97C146EA1CF9000F007C117D /* Sources */ = { 295 | isa = PBXSourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 299 | 97C146F31CF9000F007C117D /* main.m in Sources */, 300 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | /* End PBXSourcesBuildPhase section */ 305 | 306 | /* Begin PBXVariantGroup section */ 307 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 308 | isa = PBXVariantGroup; 309 | children = ( 310 | 97C146FB1CF9000F007C117D /* Base */, 311 | ); 312 | name = Main.storyboard; 313 | sourceTree = ""; 314 | }; 315 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 316 | isa = PBXVariantGroup; 317 | children = ( 318 | 97C147001CF9000F007C117D /* Base */, 319 | ); 320 | name = LaunchScreen.storyboard; 321 | sourceTree = ""; 322 | }; 323 | /* End PBXVariantGroup section */ 324 | 325 | /* Begin XCBuildConfiguration section */ 326 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 327 | isa = XCBuildConfiguration; 328 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 329 | buildSettings = { 330 | ALWAYS_SEARCH_USER_PATHS = NO; 331 | CLANG_ANALYZER_NONNULL = YES; 332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 333 | CLANG_CXX_LIBRARY = "libc++"; 334 | CLANG_ENABLE_MODULES = YES; 335 | CLANG_ENABLE_OBJC_ARC = YES; 336 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 337 | CLANG_WARN_BOOL_CONVERSION = YES; 338 | CLANG_WARN_COMMA = YES; 339 | CLANG_WARN_CONSTANT_CONVERSION = YES; 340 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 341 | CLANG_WARN_EMPTY_BODY = YES; 342 | CLANG_WARN_ENUM_CONVERSION = YES; 343 | CLANG_WARN_INFINITE_RECURSION = YES; 344 | CLANG_WARN_INT_CONVERSION = YES; 345 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 346 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 347 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 348 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 349 | CLANG_WARN_STRICT_PROTOTYPES = YES; 350 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 351 | CLANG_WARN_UNREACHABLE_CODE = YES; 352 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 354 | COPY_PHASE_STRIP = NO; 355 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 356 | ENABLE_NS_ASSERTIONS = NO; 357 | ENABLE_STRICT_OBJC_MSGSEND = YES; 358 | GCC_C_LANGUAGE_STANDARD = gnu99; 359 | GCC_NO_COMMON_BLOCKS = YES; 360 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 361 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 362 | GCC_WARN_UNDECLARED_SELECTOR = YES; 363 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 364 | GCC_WARN_UNUSED_FUNCTION = YES; 365 | GCC_WARN_UNUSED_VARIABLE = YES; 366 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 367 | MTL_ENABLE_DEBUG_INFO = NO; 368 | SDKROOT = iphoneos; 369 | TARGETED_DEVICE_FAMILY = "1,2"; 370 | VALIDATE_PRODUCT = YES; 371 | }; 372 | name = Profile; 373 | }; 374 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 375 | isa = XCBuildConfiguration; 376 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 380 | DEVELOPMENT_TEAM = YJV4N2CBA3; 381 | ENABLE_BITCODE = NO; 382 | FRAMEWORK_SEARCH_PATHS = ( 383 | "$(inherited)", 384 | "$(PROJECT_DIR)/Flutter", 385 | ); 386 | INFOPLIST_FILE = Runner/Info.plist; 387 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 388 | LIBRARY_SEARCH_PATHS = ( 389 | "$(inherited)", 390 | "$(PROJECT_DIR)/Flutter", 391 | ); 392 | PRODUCT_BUNDLE_IDENTIFIER = com.jlcool.flutterTaiExample; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | VERSIONING_SYSTEM = "apple-generic"; 395 | }; 396 | name = Profile; 397 | }; 398 | 97C147031CF9000F007C117D /* Debug */ = { 399 | isa = XCBuildConfiguration; 400 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 401 | buildSettings = { 402 | ALWAYS_SEARCH_USER_PATHS = NO; 403 | CLANG_ANALYZER_NONNULL = YES; 404 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 405 | CLANG_CXX_LIBRARY = "libc++"; 406 | CLANG_ENABLE_MODULES = YES; 407 | CLANG_ENABLE_OBJC_ARC = YES; 408 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 409 | CLANG_WARN_BOOL_CONVERSION = YES; 410 | CLANG_WARN_COMMA = YES; 411 | CLANG_WARN_CONSTANT_CONVERSION = YES; 412 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 413 | CLANG_WARN_EMPTY_BODY = YES; 414 | CLANG_WARN_ENUM_CONVERSION = YES; 415 | CLANG_WARN_INFINITE_RECURSION = YES; 416 | CLANG_WARN_INT_CONVERSION = YES; 417 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 419 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 420 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 421 | CLANG_WARN_STRICT_PROTOTYPES = YES; 422 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 423 | CLANG_WARN_UNREACHABLE_CODE = YES; 424 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 425 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 426 | COPY_PHASE_STRIP = NO; 427 | DEBUG_INFORMATION_FORMAT = dwarf; 428 | ENABLE_STRICT_OBJC_MSGSEND = YES; 429 | ENABLE_TESTABILITY = YES; 430 | GCC_C_LANGUAGE_STANDARD = gnu99; 431 | GCC_DYNAMIC_NO_PIC = NO; 432 | GCC_NO_COMMON_BLOCKS = YES; 433 | GCC_OPTIMIZATION_LEVEL = 0; 434 | GCC_PREPROCESSOR_DEFINITIONS = ( 435 | "DEBUG=1", 436 | "$(inherited)", 437 | ); 438 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 439 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 440 | GCC_WARN_UNDECLARED_SELECTOR = YES; 441 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 442 | GCC_WARN_UNUSED_FUNCTION = YES; 443 | GCC_WARN_UNUSED_VARIABLE = YES; 444 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 445 | MTL_ENABLE_DEBUG_INFO = YES; 446 | ONLY_ACTIVE_ARCH = YES; 447 | SDKROOT = iphoneos; 448 | TARGETED_DEVICE_FAMILY = "1,2"; 449 | }; 450 | name = Debug; 451 | }; 452 | 97C147041CF9000F007C117D /* Release */ = { 453 | isa = XCBuildConfiguration; 454 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 455 | buildSettings = { 456 | ALWAYS_SEARCH_USER_PATHS = NO; 457 | CLANG_ANALYZER_NONNULL = YES; 458 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 459 | CLANG_CXX_LIBRARY = "libc++"; 460 | CLANG_ENABLE_MODULES = YES; 461 | CLANG_ENABLE_OBJC_ARC = YES; 462 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 463 | CLANG_WARN_BOOL_CONVERSION = YES; 464 | CLANG_WARN_COMMA = YES; 465 | CLANG_WARN_CONSTANT_CONVERSION = YES; 466 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 467 | CLANG_WARN_EMPTY_BODY = YES; 468 | CLANG_WARN_ENUM_CONVERSION = YES; 469 | CLANG_WARN_INFINITE_RECURSION = YES; 470 | CLANG_WARN_INT_CONVERSION = YES; 471 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 472 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 473 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 474 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 475 | CLANG_WARN_STRICT_PROTOTYPES = YES; 476 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 477 | CLANG_WARN_UNREACHABLE_CODE = YES; 478 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 479 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 480 | COPY_PHASE_STRIP = NO; 481 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 482 | ENABLE_NS_ASSERTIONS = NO; 483 | ENABLE_STRICT_OBJC_MSGSEND = YES; 484 | GCC_C_LANGUAGE_STANDARD = gnu99; 485 | GCC_NO_COMMON_BLOCKS = YES; 486 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 487 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 488 | GCC_WARN_UNDECLARED_SELECTOR = YES; 489 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 490 | GCC_WARN_UNUSED_FUNCTION = YES; 491 | GCC_WARN_UNUSED_VARIABLE = YES; 492 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 493 | MTL_ENABLE_DEBUG_INFO = NO; 494 | SDKROOT = iphoneos; 495 | TARGETED_DEVICE_FAMILY = "1,2"; 496 | VALIDATE_PRODUCT = YES; 497 | }; 498 | name = Release; 499 | }; 500 | 97C147061CF9000F007C117D /* Debug */ = { 501 | isa = XCBuildConfiguration; 502 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 503 | buildSettings = { 504 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 505 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 506 | DEVELOPMENT_TEAM = YJV4N2CBA3; 507 | ENABLE_BITCODE = NO; 508 | FRAMEWORK_SEARCH_PATHS = ( 509 | "$(inherited)", 510 | "$(PROJECT_DIR)/Flutter", 511 | ); 512 | INFOPLIST_FILE = Runner/Info.plist; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 514 | LIBRARY_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "$(PROJECT_DIR)/Flutter", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = com.jlcool.flutterTaiExample; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | VERSIONING_SYSTEM = "apple-generic"; 521 | }; 522 | name = Debug; 523 | }; 524 | 97C147071CF9000F007C117D /* Release */ = { 525 | isa = XCBuildConfiguration; 526 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 530 | DEVELOPMENT_TEAM = YJV4N2CBA3; 531 | ENABLE_BITCODE = NO; 532 | FRAMEWORK_SEARCH_PATHS = ( 533 | "$(inherited)", 534 | "$(PROJECT_DIR)/Flutter", 535 | ); 536 | INFOPLIST_FILE = Runner/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 538 | LIBRARY_SEARCH_PATHS = ( 539 | "$(inherited)", 540 | "$(PROJECT_DIR)/Flutter", 541 | ); 542 | PRODUCT_BUNDLE_IDENTIFIER = com.jlcool.flutterTaiExample; 543 | PRODUCT_NAME = "$(TARGET_NAME)"; 544 | VERSIONING_SYSTEM = "apple-generic"; 545 | }; 546 | name = Release; 547 | }; 548 | /* End XCBuildConfiguration section */ 549 | 550 | /* Begin XCConfigurationList section */ 551 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 97C147031CF9000F007C117D /* Debug */, 555 | 97C147041CF9000F007C117D /* Release */, 556 | 249021D3217E4FDB00AE95B9 /* Profile */, 557 | ); 558 | defaultConfigurationIsVisible = 0; 559 | defaultConfigurationName = Release; 560 | }; 561 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 97C147061CF9000F007C117D /* Debug */, 565 | 97C147071CF9000F007C117D /* Release */, 566 | 249021D4217E4FDB00AE95B9 /* Profile */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | /* End XCConfigurationList section */ 572 | }; 573 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 574 | } 575 | -------------------------------------------------------------------------------- /ios/Frameworks/lame.framework/Headers/lame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to MP3 LAME encoding engine 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | /* $Id: lame.h,v 1.189.2.1 2012/01/08 23:49:58 robert Exp $ */ 23 | 24 | #ifndef LAME_LAME_H 25 | #define LAME_LAME_H 26 | 27 | /* for size_t typedef */ 28 | #include 29 | /* for va_list typedef */ 30 | #include 31 | /* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */ 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" { 36 | #endif 37 | 38 | typedef void (*lame_report_function)(const char *format, va_list ap); 39 | 40 | #if defined(WIN32) || defined(_WIN32) 41 | #undef CDECL 42 | #define CDECL __cdecl 43 | #else 44 | #define CDECL 45 | #endif 46 | 47 | #define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1 48 | 49 | typedef enum vbr_mode_e { 50 | vbr_off=0, 51 | vbr_mt, /* obsolete, same as vbr_mtrh */ 52 | vbr_rh, 53 | vbr_abr, 54 | vbr_mtrh, 55 | vbr_max_indicator, /* Don't use this! It's used for sanity checks. */ 56 | vbr_default=vbr_mtrh /* change this to change the default VBR mode of LAME */ 57 | } vbr_mode; 58 | 59 | 60 | /* MPEG modes */ 61 | typedef enum MPEG_mode_e { 62 | STEREO = 0, 63 | JOINT_STEREO, 64 | DUAL_CHANNEL, /* LAME doesn't supports this! */ 65 | MONO, 66 | NOT_SET, 67 | MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ 68 | } MPEG_mode; 69 | 70 | /* Padding types */ 71 | typedef enum Padding_type_e { 72 | PAD_NO = 0, 73 | PAD_ALL, 74 | PAD_ADJUST, 75 | PAD_MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ 76 | } Padding_type; 77 | 78 | 79 | 80 | /*presets*/ 81 | typedef enum preset_mode_e { 82 | /*values from 8 to 320 should be reserved for abr bitrates*/ 83 | /*for abr I'd suggest to directly use the targeted bitrate as a value*/ 84 | ABR_8 = 8, 85 | ABR_320 = 320, 86 | 87 | V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/ 88 | VBR_10 = 410, 89 | V8 = 420, 90 | VBR_20 = 420, 91 | V7 = 430, 92 | VBR_30 = 430, 93 | V6 = 440, 94 | VBR_40 = 440, 95 | V5 = 450, 96 | VBR_50 = 450, 97 | V4 = 460, 98 | VBR_60 = 460, 99 | V3 = 470, 100 | VBR_70 = 470, 101 | V2 = 480, 102 | VBR_80 = 480, 103 | V1 = 490, 104 | VBR_90 = 490, 105 | V0 = 500, 106 | VBR_100 = 500, 107 | 108 | 109 | 110 | /*still there for compatibility*/ 111 | R3MIX = 1000, 112 | STANDARD = 1001, 113 | EXTREME = 1002, 114 | INSANE = 1003, 115 | STANDARD_FAST = 1004, 116 | EXTREME_FAST = 1005, 117 | MEDIUM = 1006, 118 | MEDIUM_FAST = 1007 119 | } preset_mode; 120 | 121 | 122 | /*asm optimizations*/ 123 | typedef enum asm_optimizations_e { 124 | MMX = 1, 125 | AMD_3DNOW = 2, 126 | SSE = 3 127 | } asm_optimizations; 128 | 129 | 130 | /* psychoacoustic model */ 131 | typedef enum Psy_model_e { 132 | PSY_GPSYCHO = 1, 133 | PSY_NSPSYTUNE = 2 134 | } Psy_model; 135 | 136 | 137 | /* buffer considerations */ 138 | typedef enum buffer_constraint_e { 139 | MDB_DEFAULT=0, 140 | MDB_STRICT_ISO=1, 141 | MDB_MAXIMUM=2 142 | } buffer_constraint; 143 | 144 | 145 | struct lame_global_struct; 146 | typedef struct lame_global_struct lame_global_flags; 147 | typedef lame_global_flags *lame_t; 148 | 149 | 150 | 151 | 152 | /*********************************************************************** 153 | * 154 | * The LAME API 155 | * These functions should be called, in this order, for each 156 | * MP3 file to be encoded. See the file "API" for more documentation 157 | * 158 | ***********************************************************************/ 159 | 160 | 161 | /* 162 | * REQUIRED: 163 | * initialize the encoder. sets default for all encoder parameters, 164 | * returns NULL if some malloc()'s failed 165 | * otherwise returns pointer to structure needed for all future 166 | * API calls. 167 | */ 168 | lame_global_flags * CDECL lame_init(void); 169 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 170 | #else 171 | /* obsolete version */ 172 | int CDECL lame_init_old(lame_global_flags *); 173 | #endif 174 | 175 | /* 176 | * OPTIONAL: 177 | * set as needed to override defaults 178 | */ 179 | 180 | /******************************************************************** 181 | * input stream description 182 | ***********************************************************************/ 183 | /* number of samples. default = 2^32-1 */ 184 | int CDECL lame_set_num_samples(lame_global_flags *, unsigned long); 185 | unsigned long CDECL lame_get_num_samples(const lame_global_flags *); 186 | 187 | /* input sample rate in Hz. default = 44100hz */ 188 | int CDECL lame_set_in_samplerate(lame_global_flags *, int); 189 | int CDECL lame_get_in_samplerate(const lame_global_flags *); 190 | 191 | /* number of channels in input stream. default=2 */ 192 | int CDECL lame_set_num_channels(lame_global_flags *, int); 193 | int CDECL lame_get_num_channels(const lame_global_flags *); 194 | 195 | /* 196 | scale the input by this amount before encoding. default=1 197 | (not used by decoding routines) 198 | */ 199 | int CDECL lame_set_scale(lame_global_flags *, float); 200 | float CDECL lame_get_scale(const lame_global_flags *); 201 | 202 | /* 203 | scale the channel 0 (left) input by this amount before encoding. default=1 204 | (not used by decoding routines) 205 | */ 206 | int CDECL lame_set_scale_left(lame_global_flags *, float); 207 | float CDECL lame_get_scale_left(const lame_global_flags *); 208 | 209 | /* 210 | scale the channel 1 (right) input by this amount before encoding. default=1 211 | (not used by decoding routines) 212 | */ 213 | int CDECL lame_set_scale_right(lame_global_flags *, float); 214 | float CDECL lame_get_scale_right(const lame_global_flags *); 215 | 216 | /* 217 | output sample rate in Hz. default = 0, which means LAME picks best value 218 | based on the amount of compression. MPEG only allows: 219 | MPEG1 32, 44.1, 48khz 220 | MPEG2 16, 22.05, 24 221 | MPEG2.5 8, 11.025, 12 222 | (not used by decoding routines) 223 | */ 224 | int CDECL lame_set_out_samplerate(lame_global_flags *, int); 225 | int CDECL lame_get_out_samplerate(const lame_global_flags *); 226 | 227 | 228 | /******************************************************************** 229 | * general control parameters 230 | ***********************************************************************/ 231 | /* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */ 232 | int CDECL lame_set_analysis(lame_global_flags *, int); 233 | int CDECL lame_get_analysis(const lame_global_flags *); 234 | 235 | /* 236 | 1 = write a Xing VBR header frame. 237 | default = 1 238 | this variable must have been added by a Hungarian notation Windows programmer :-) 239 | */ 240 | int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int); 241 | int CDECL lame_get_bWriteVbrTag(const lame_global_flags *); 242 | 243 | /* 1=decode only. use lame/mpglib to convert mp3/ogg to wav. default=0 */ 244 | int CDECL lame_set_decode_only(lame_global_flags *, int); 245 | int CDECL lame_get_decode_only(const lame_global_flags *); 246 | 247 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 248 | #else 249 | /* 1=encode a Vorbis .ogg file. default=0 */ 250 | /* DEPRECATED */ 251 | int CDECL lame_set_ogg(lame_global_flags *, int); 252 | int CDECL lame_get_ogg(const lame_global_flags *); 253 | #endif 254 | 255 | /* 256 | internal algorithm selection. True quality is determined by the bitrate 257 | but this variable will effect quality by selecting expensive or cheap algorithms. 258 | quality=0..9. 0=best (very slow). 9=worst. 259 | recommended: 2 near-best quality, not too slow 260 | 5 good quality, fast 261 | 7 ok quality, really fast 262 | */ 263 | int CDECL lame_set_quality(lame_global_flags *, int); 264 | int CDECL lame_get_quality(const lame_global_flags *); 265 | 266 | /* 267 | mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono 268 | default: lame picks based on compression ration and input channels 269 | */ 270 | int CDECL lame_set_mode(lame_global_flags *, MPEG_mode); 271 | MPEG_mode CDECL lame_get_mode(const lame_global_flags *); 272 | 273 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 274 | #else 275 | /* 276 | mode_automs. Use a M/S mode with a switching threshold based on 277 | compression ratio 278 | DEPRECATED 279 | */ 280 | int CDECL lame_set_mode_automs(lame_global_flags *, int); 281 | int CDECL lame_get_mode_automs(const lame_global_flags *); 282 | #endif 283 | 284 | /* 285 | force_ms. Force M/S for all frames. For testing only. 286 | default = 0 (disabled) 287 | */ 288 | int CDECL lame_set_force_ms(lame_global_flags *, int); 289 | int CDECL lame_get_force_ms(const lame_global_flags *); 290 | 291 | /* use free_format? default = 0 (disabled) */ 292 | int CDECL lame_set_free_format(lame_global_flags *, int); 293 | int CDECL lame_get_free_format(const lame_global_flags *); 294 | 295 | /* perform ReplayGain analysis? default = 0 (disabled) */ 296 | int CDECL lame_set_findReplayGain(lame_global_flags *, int); 297 | int CDECL lame_get_findReplayGain(const lame_global_flags *); 298 | 299 | /* decode on the fly. Search for the peak sample. If the ReplayGain 300 | * analysis is enabled then perform the analysis on the decoded data 301 | * stream. default = 0 (disabled) 302 | * NOTE: if this option is set the build-in decoder should not be used */ 303 | int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int); 304 | int CDECL lame_get_decode_on_the_fly(const lame_global_flags *); 305 | 306 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 307 | #else 308 | /* DEPRECATED: now does the same as lame_set_findReplayGain() 309 | default = 0 (disabled) */ 310 | int CDECL lame_set_ReplayGain_input(lame_global_flags *, int); 311 | int CDECL lame_get_ReplayGain_input(const lame_global_flags *); 312 | 313 | /* DEPRECATED: now does the same as 314 | lame_set_decode_on_the_fly() && lame_set_findReplayGain() 315 | default = 0 (disabled) */ 316 | int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int); 317 | int CDECL lame_get_ReplayGain_decode(const lame_global_flags *); 318 | 319 | /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() 320 | default = 0 (disabled) */ 321 | int CDECL lame_set_findPeakSample(lame_global_flags *, int); 322 | int CDECL lame_get_findPeakSample(const lame_global_flags *); 323 | #endif 324 | 325 | /* counters for gapless encoding */ 326 | int CDECL lame_set_nogap_total(lame_global_flags*, int); 327 | int CDECL lame_get_nogap_total(const lame_global_flags*); 328 | 329 | int CDECL lame_set_nogap_currentindex(lame_global_flags* , int); 330 | int CDECL lame_get_nogap_currentindex(const lame_global_flags*); 331 | 332 | 333 | /* 334 | * OPTIONAL: 335 | * Set printf like error/debug/message reporting functions. 336 | * The second argument has to be a pointer to a function which looks like 337 | * void my_debugf(const char *format, va_list ap) 338 | * { 339 | * (void) vfprintf(stdout, format, ap); 340 | * } 341 | * If you use NULL as the value of the pointer in the set function, the 342 | * lame buildin function will be used (prints to stderr). 343 | * To quiet any output you have to replace the body of the example function 344 | * with just "return;" and use it in the set function. 345 | */ 346 | int CDECL lame_set_errorf(lame_global_flags *, lame_report_function); 347 | int CDECL lame_set_debugf(lame_global_flags *, lame_report_function); 348 | int CDECL lame_set_msgf (lame_global_flags *, lame_report_function); 349 | 350 | 351 | 352 | /* set one of brate compression ratio. default is compression ratio of 11. */ 353 | int CDECL lame_set_brate(lame_global_flags *, int); 354 | int CDECL lame_get_brate(const lame_global_flags *); 355 | int CDECL lame_set_compression_ratio(lame_global_flags *, float); 356 | float CDECL lame_get_compression_ratio(const lame_global_flags *); 357 | 358 | 359 | int CDECL lame_set_preset( lame_global_flags* gfp, int ); 360 | int CDECL lame_set_asm_optimizations( lame_global_flags* gfp, int, int ); 361 | 362 | 363 | 364 | /******************************************************************** 365 | * frame params 366 | ***********************************************************************/ 367 | /* mark as copyright. default=0 */ 368 | int CDECL lame_set_copyright(lame_global_flags *, int); 369 | int CDECL lame_get_copyright(const lame_global_flags *); 370 | 371 | /* mark as original. default=1 */ 372 | int CDECL lame_set_original(lame_global_flags *, int); 373 | int CDECL lame_get_original(const lame_global_flags *); 374 | 375 | /* error_protection. Use 2 bytes from each frame for CRC checksum. default=0 */ 376 | int CDECL lame_set_error_protection(lame_global_flags *, int); 377 | int CDECL lame_get_error_protection(const lame_global_flags *); 378 | 379 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 380 | #else 381 | /* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */ 382 | int CDECL lame_set_padding_type(lame_global_flags *, Padding_type); 383 | Padding_type CDECL lame_get_padding_type(const lame_global_flags *); 384 | #endif 385 | 386 | /* MP3 'private extension' bit Meaningless. default=0 */ 387 | int CDECL lame_set_extension(lame_global_flags *, int); 388 | int CDECL lame_get_extension(const lame_global_flags *); 389 | 390 | /* enforce strict ISO compliance. default=0 */ 391 | int CDECL lame_set_strict_ISO(lame_global_flags *, int); 392 | int CDECL lame_get_strict_ISO(const lame_global_flags *); 393 | 394 | 395 | /******************************************************************** 396 | * quantization/noise shaping 397 | ***********************************************************************/ 398 | 399 | /* disable the bit reservoir. For testing only. default=0 */ 400 | int CDECL lame_set_disable_reservoir(lame_global_flags *, int); 401 | int CDECL lame_get_disable_reservoir(const lame_global_flags *); 402 | 403 | /* select a different "best quantization" function. default=0 */ 404 | int CDECL lame_set_quant_comp(lame_global_flags *, int); 405 | int CDECL lame_get_quant_comp(const lame_global_flags *); 406 | int CDECL lame_set_quant_comp_short(lame_global_flags *, int); 407 | int CDECL lame_get_quant_comp_short(const lame_global_flags *); 408 | 409 | int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/ 410 | int CDECL lame_get_experimentalX(const lame_global_flags *); 411 | 412 | /* another experimental option. for testing only */ 413 | int CDECL lame_set_experimentalY(lame_global_flags *, int); 414 | int CDECL lame_get_experimentalY(const lame_global_flags *); 415 | 416 | /* another experimental option. for testing only */ 417 | int CDECL lame_set_experimentalZ(lame_global_flags *, int); 418 | int CDECL lame_get_experimentalZ(const lame_global_flags *); 419 | 420 | /* Naoki's psycho acoustic model. default=0 */ 421 | int CDECL lame_set_exp_nspsytune(lame_global_flags *, int); 422 | int CDECL lame_get_exp_nspsytune(const lame_global_flags *); 423 | 424 | void CDECL lame_set_msfix(lame_global_flags *, double); 425 | float CDECL lame_get_msfix(const lame_global_flags *); 426 | 427 | 428 | /******************************************************************** 429 | * VBR control 430 | ***********************************************************************/ 431 | /* Types of VBR. default = vbr_off = CBR */ 432 | int CDECL lame_set_VBR(lame_global_flags *, vbr_mode); 433 | vbr_mode CDECL lame_get_VBR(const lame_global_flags *); 434 | 435 | /* VBR quality level. 0=highest 9=lowest */ 436 | int CDECL lame_set_VBR_q(lame_global_flags *, int); 437 | int CDECL lame_get_VBR_q(const lame_global_flags *); 438 | 439 | /* VBR quality level. 0=highest 9=lowest, Range [0,...,10[ */ 440 | int CDECL lame_set_VBR_quality(lame_global_flags *, float); 441 | float CDECL lame_get_VBR_quality(const lame_global_flags *); 442 | 443 | /* Ignored except for VBR=vbr_abr (ABR mode) */ 444 | int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int); 445 | int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *); 446 | 447 | int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int); 448 | int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *); 449 | 450 | int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int); 451 | int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *); 452 | 453 | /* 454 | 1=strictly enforce VBR_min_bitrate. Normally it will be violated for 455 | analog silence 456 | */ 457 | int CDECL lame_set_VBR_hard_min(lame_global_flags *, int); 458 | int CDECL lame_get_VBR_hard_min(const lame_global_flags *); 459 | 460 | /* for preset */ 461 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 462 | #else 463 | int CDECL lame_set_preset_expopts(lame_global_flags *, int); 464 | #endif 465 | 466 | /******************************************************************** 467 | * Filtering control 468 | ***********************************************************************/ 469 | /* freq in Hz to apply lowpass. Default = 0 = lame chooses. -1 = disabled */ 470 | int CDECL lame_set_lowpassfreq(lame_global_flags *, int); 471 | int CDECL lame_get_lowpassfreq(const lame_global_flags *); 472 | /* width of transition band, in Hz. Default = one polyphase filter band */ 473 | int CDECL lame_set_lowpasswidth(lame_global_flags *, int); 474 | int CDECL lame_get_lowpasswidth(const lame_global_flags *); 475 | 476 | /* freq in Hz to apply highpass. Default = 0 = lame chooses. -1 = disabled */ 477 | int CDECL lame_set_highpassfreq(lame_global_flags *, int); 478 | int CDECL lame_get_highpassfreq(const lame_global_flags *); 479 | /* width of transition band, in Hz. Default = one polyphase filter band */ 480 | int CDECL lame_set_highpasswidth(lame_global_flags *, int); 481 | int CDECL lame_get_highpasswidth(const lame_global_flags *); 482 | 483 | 484 | /******************************************************************** 485 | * psycho acoustics and other arguments which you should not change 486 | * unless you know what you are doing 487 | ***********************************************************************/ 488 | 489 | /* only use ATH for masking */ 490 | int CDECL lame_set_ATHonly(lame_global_flags *, int); 491 | int CDECL lame_get_ATHonly(const lame_global_flags *); 492 | 493 | /* only use ATH for short blocks */ 494 | int CDECL lame_set_ATHshort(lame_global_flags *, int); 495 | int CDECL lame_get_ATHshort(const lame_global_flags *); 496 | 497 | /* disable ATH */ 498 | int CDECL lame_set_noATH(lame_global_flags *, int); 499 | int CDECL lame_get_noATH(const lame_global_flags *); 500 | 501 | /* select ATH formula */ 502 | int CDECL lame_set_ATHtype(lame_global_flags *, int); 503 | int CDECL lame_get_ATHtype(const lame_global_flags *); 504 | 505 | /* lower ATH by this many db */ 506 | int CDECL lame_set_ATHlower(lame_global_flags *, float); 507 | float CDECL lame_get_ATHlower(const lame_global_flags *); 508 | 509 | /* select ATH adaptive adjustment type */ 510 | int CDECL lame_set_athaa_type( lame_global_flags *, int); 511 | int CDECL lame_get_athaa_type( const lame_global_flags *); 512 | 513 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 514 | #else 515 | /* select the loudness approximation used by the ATH adaptive auto-leveling */ 516 | int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int); 517 | int CDECL lame_get_athaa_loudapprox( const lame_global_flags *); 518 | #endif 519 | 520 | /* adjust (in dB) the point below which adaptive ATH level adjustment occurs */ 521 | int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float); 522 | float CDECL lame_get_athaa_sensitivity( const lame_global_flags* ); 523 | 524 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 525 | #else 526 | /* OBSOLETE: predictability limit (ISO tonality formula) */ 527 | int CDECL lame_set_cwlimit(lame_global_flags *, int); 528 | int CDECL lame_get_cwlimit(const lame_global_flags *); 529 | #endif 530 | 531 | /* 532 | allow blocktypes to differ between channels? 533 | default: 0 for jstereo, 1 for stereo 534 | */ 535 | int CDECL lame_set_allow_diff_short(lame_global_flags *, int); 536 | int CDECL lame_get_allow_diff_short(const lame_global_flags *); 537 | 538 | /* use temporal masking effect (default = 1) */ 539 | int CDECL lame_set_useTemporal(lame_global_flags *, int); 540 | int CDECL lame_get_useTemporal(const lame_global_flags *); 541 | 542 | /* use temporal masking effect (default = 1) */ 543 | int CDECL lame_set_interChRatio(lame_global_flags *, float); 544 | float CDECL lame_get_interChRatio(const lame_global_flags *); 545 | 546 | /* disable short blocks */ 547 | int CDECL lame_set_no_short_blocks(lame_global_flags *, int); 548 | int CDECL lame_get_no_short_blocks(const lame_global_flags *); 549 | 550 | /* force short blocks */ 551 | int CDECL lame_set_force_short_blocks(lame_global_flags *, int); 552 | int CDECL lame_get_force_short_blocks(const lame_global_flags *); 553 | 554 | /* Input PCM is emphased PCM (for instance from one of the rarely 555 | emphased CDs), it is STRONGLY not recommended to use this, because 556 | psycho does not take it into account, and last but not least many decoders 557 | ignore these bits */ 558 | int CDECL lame_set_emphasis(lame_global_flags *, int); 559 | int CDECL lame_get_emphasis(const lame_global_flags *); 560 | 561 | 562 | 563 | /************************************************************************/ 564 | /* internal variables, cannot be set... */ 565 | /* provided because they may be of use to calling application */ 566 | /************************************************************************/ 567 | /* version 0=MPEG-2 1=MPEG-1 (2=MPEG-2.5) */ 568 | int CDECL lame_get_version(const lame_global_flags *); 569 | 570 | /* encoder delay */ 571 | int CDECL lame_get_encoder_delay(const lame_global_flags *); 572 | 573 | /* 574 | padding appended to the input to make sure decoder can fully decode 575 | all input. Note that this value can only be calculated during the 576 | call to lame_encoder_flush(). Before lame_encoder_flush() has 577 | been called, the value of encoder_padding = 0. 578 | */ 579 | int CDECL lame_get_encoder_padding(const lame_global_flags *); 580 | 581 | /* size of MPEG frame */ 582 | int CDECL lame_get_framesize(const lame_global_flags *); 583 | 584 | /* number of PCM samples buffered, but not yet encoded to mp3 data. */ 585 | int CDECL lame_get_mf_samples_to_encode( const lame_global_flags* gfp ); 586 | 587 | /* 588 | size (bytes) of mp3 data buffered, but not yet encoded. 589 | this is the number of bytes which would be output by a call to 590 | lame_encode_flush_nogap. NOTE: lame_encode_flush() will return 591 | more bytes than this because it will encode the reamining buffered 592 | PCM samples before flushing the mp3 buffers. 593 | */ 594 | int CDECL lame_get_size_mp3buffer( const lame_global_flags* gfp ); 595 | 596 | /* number of frames encoded so far */ 597 | int CDECL lame_get_frameNum(const lame_global_flags *); 598 | 599 | /* 600 | lame's estimate of the total number of frames to be encoded 601 | only valid if calling program set num_samples 602 | */ 603 | int CDECL lame_get_totalframes(const lame_global_flags *); 604 | 605 | /* RadioGain value. Multiplied by 10 and rounded to the nearest. */ 606 | int CDECL lame_get_RadioGain(const lame_global_flags *); 607 | 608 | /* AudiophileGain value. Multipled by 10 and rounded to the nearest. */ 609 | int CDECL lame_get_AudiophileGain(const lame_global_flags *); 610 | 611 | /* the peak sample */ 612 | float CDECL lame_get_PeakSample(const lame_global_flags *); 613 | 614 | /* Gain change required for preventing clipping. The value is correct only if 615 | peak sample searching was enabled. If negative then the waveform 616 | already does not clip. The value is multiplied by 10 and rounded up. */ 617 | int CDECL lame_get_noclipGainChange(const lame_global_flags *); 618 | 619 | /* user-specified scale factor required for preventing clipping. Value is 620 | correct only if peak sample searching was enabled and no user-specified 621 | scaling was performed. If negative then either the waveform already does 622 | not clip or the value cannot be determined */ 623 | float CDECL lame_get_noclipScale(const lame_global_flags *); 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | /* 632 | * REQUIRED: 633 | * sets more internal configuration based on data provided above. 634 | * returns -1 if something failed. 635 | */ 636 | int CDECL lame_init_params(lame_global_flags *); 637 | 638 | 639 | /* 640 | * OPTIONAL: 641 | * get the version number, in a string. of the form: 642 | * "3.63 (beta)" or just "3.63". 643 | */ 644 | const char* CDECL get_lame_version ( void ); 645 | const char* CDECL get_lame_short_version ( void ); 646 | const char* CDECL get_lame_very_short_version ( void ); 647 | const char* CDECL get_psy_version ( void ); 648 | const char* CDECL get_lame_url ( void ); 649 | const char* CDECL get_lame_os_bitness ( void ); 650 | 651 | /* 652 | * OPTIONAL: 653 | * get the version numbers in numerical form. 654 | */ 655 | typedef struct { 656 | /* generic LAME version */ 657 | int major; 658 | int minor; 659 | int alpha; /* 0 if not an alpha version */ 660 | int beta; /* 0 if not a beta version */ 661 | 662 | /* version of the psy model */ 663 | int psy_major; 664 | int psy_minor; 665 | int psy_alpha; /* 0 if not an alpha version */ 666 | int psy_beta; /* 0 if not a beta version */ 667 | 668 | /* compile time features */ 669 | const char *features; /* Don't make assumptions about the contents! */ 670 | } lame_version_t; 671 | void CDECL get_lame_version_numerical(lame_version_t *); 672 | 673 | 674 | /* 675 | * OPTIONAL: 676 | * print internal lame configuration to message handler 677 | */ 678 | void CDECL lame_print_config(const lame_global_flags* gfp); 679 | 680 | void CDECL lame_print_internals( const lame_global_flags *gfp); 681 | 682 | 683 | /* 684 | * input pcm data, output (maybe) mp3 frames. 685 | * This routine handles all buffering, resampling and filtering for you. 686 | * 687 | * return code number of bytes output in mp3buf. Can be 0 688 | * -1: mp3buf was too small 689 | * -2: malloc() problem 690 | * -3: lame_init_params() not called 691 | * -4: psycho acoustic problems 692 | * 693 | * The required mp3buf_size can be computed from num_samples, 694 | * samplerate and encoding rate, but here is a worst case estimate: 695 | * 696 | * mp3buf_size in bytes = 1.25*num_samples + 7200 697 | * 698 | * I think a tighter bound could be: (mt, March 2000) 699 | * MPEG1: 700 | * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512 701 | * MPEG2: 702 | * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256 703 | * 704 | * but test first if you use that! 705 | * 706 | * set mp3buf_size = 0 and LAME will not check if mp3buf_size is 707 | * large enough. 708 | * 709 | * NOTE: 710 | * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels 711 | * will be averaged into the L channel before encoding only the L channel 712 | * This will overwrite the data in buffer_l[] and buffer_r[]. 713 | * 714 | */ 715 | int CDECL lame_encode_buffer ( 716 | lame_global_flags* gfp, /* global context handle */ 717 | const short int buffer_l [], /* PCM data for left channel */ 718 | const short int buffer_r [], /* PCM data for right channel */ 719 | const int nsamples, /* number of samples per channel */ 720 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 721 | const int mp3buf_size ); /* number of valid octets in this 722 | stream */ 723 | 724 | /* 725 | * as above, but input has L & R channel data interleaved. 726 | * NOTE: 727 | * num_samples = number of samples in the L (or R) 728 | * channel, not the total number of samples in pcm[] 729 | */ 730 | int CDECL lame_encode_buffer_interleaved( 731 | lame_global_flags* gfp, /* global context handlei */ 732 | short int pcm[], /* PCM data for left and right 733 | channel, interleaved */ 734 | int num_samples, /* number of samples per channel, 735 | _not_ number of samples in 736 | pcm[] */ 737 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 738 | int mp3buf_size ); /* number of valid octets in this 739 | stream */ 740 | 741 | 742 | /* as lame_encode_buffer, but for 'float's. 743 | * !! NOTE: !! data must still be scaled to be in the same range as 744 | * short int, +/- 32768 745 | */ 746 | int CDECL lame_encode_buffer_float( 747 | lame_global_flags* gfp, /* global context handle */ 748 | const float pcm_l [], /* PCM data for left channel */ 749 | const float pcm_r [], /* PCM data for right channel */ 750 | const int nsamples, /* number of samples per channel */ 751 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 752 | const int mp3buf_size ); /* number of valid octets in this 753 | stream */ 754 | 755 | /* as lame_encode_buffer, but for 'float's. 756 | * !! NOTE: !! data must be scaled to +/- 1 full scale 757 | */ 758 | int CDECL lame_encode_buffer_ieee_float( 759 | lame_t gfp, 760 | const float pcm_l [], /* PCM data for left channel */ 761 | const float pcm_r [], /* PCM data for right channel */ 762 | const int nsamples, 763 | unsigned char * mp3buf, 764 | const int mp3buf_size); 765 | int CDECL lame_encode_buffer_interleaved_ieee_float( 766 | lame_t gfp, 767 | const float pcm[], /* PCM data for left and right 768 | channel, interleaved */ 769 | const int nsamples, 770 | unsigned char * mp3buf, 771 | const int mp3buf_size); 772 | 773 | /* as lame_encode_buffer, but for 'double's. 774 | * !! NOTE: !! data must be scaled to +/- 1 full scale 775 | */ 776 | int CDECL lame_encode_buffer_ieee_double( 777 | lame_t gfp, 778 | const double pcm_l [], /* PCM data for left channel */ 779 | const double pcm_r [], /* PCM data for right channel */ 780 | const int nsamples, 781 | unsigned char * mp3buf, 782 | const int mp3buf_size); 783 | int CDECL lame_encode_buffer_interleaved_ieee_double( 784 | lame_t gfp, 785 | const double pcm[], /* PCM data for left and right 786 | channel, interleaved */ 787 | const int nsamples, 788 | unsigned char * mp3buf, 789 | const int mp3buf_size); 790 | 791 | /* as lame_encode_buffer, but for long's 792 | * !! NOTE: !! data must still be scaled to be in the same range as 793 | * short int, +/- 32768 794 | * 795 | * This scaling was a mistake (doesn't allow one to exploit full 796 | * precision of type 'long'. Use lame_encode_buffer_long2() instead. 797 | * 798 | */ 799 | int CDECL lame_encode_buffer_long( 800 | lame_global_flags* gfp, /* global context handle */ 801 | const long buffer_l [], /* PCM data for left channel */ 802 | const long buffer_r [], /* PCM data for right channel */ 803 | const int nsamples, /* number of samples per channel */ 804 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 805 | const int mp3buf_size ); /* number of valid octets in this 806 | stream */ 807 | 808 | /* Same as lame_encode_buffer_long(), but with correct scaling. 809 | * !! NOTE: !! data must still be scaled to be in the same range as 810 | * type 'long'. Data should be in the range: +/- 2^(8*size(long)-1) 811 | * 812 | */ 813 | int CDECL lame_encode_buffer_long2( 814 | lame_global_flags* gfp, /* global context handle */ 815 | const long buffer_l [], /* PCM data for left channel */ 816 | const long buffer_r [], /* PCM data for right channel */ 817 | const int nsamples, /* number of samples per channel */ 818 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 819 | const int mp3buf_size ); /* number of valid octets in this 820 | stream */ 821 | 822 | /* as lame_encode_buffer, but for int's 823 | * !! NOTE: !! input should be scaled to the maximum range of 'int' 824 | * If int is 4 bytes, then the values should range from 825 | * +/- 2147483648. 826 | * 827 | * This routine does not (and cannot, without loosing precision) use 828 | * the same scaling as the rest of the lame_encode_buffer() routines. 829 | * 830 | */ 831 | int CDECL lame_encode_buffer_int( 832 | lame_global_flags* gfp, /* global context handle */ 833 | const int buffer_l [], /* PCM data for left channel */ 834 | const int buffer_r [], /* PCM data for right channel */ 835 | const int nsamples, /* number of samples per channel */ 836 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 837 | const int mp3buf_size ); /* number of valid octets in this 838 | stream */ 839 | 840 | 841 | 842 | 843 | 844 | /* 845 | * REQUIRED: 846 | * lame_encode_flush will flush the intenal PCM buffers, padding with 847 | * 0's to make sure the final frame is complete, and then flush 848 | * the internal MP3 buffers, and thus may return a 849 | * final few mp3 frames. 'mp3buf' should be at least 7200 bytes long 850 | * to hold all possible emitted data. 851 | * 852 | * will also write id3v1 tags (if any) into the bitstream 853 | * 854 | * return code = number of bytes output to mp3buf. Can be 0 855 | */ 856 | int CDECL lame_encode_flush( 857 | lame_global_flags * gfp, /* global context handle */ 858 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 859 | int size); /* number of valid octets in this stream */ 860 | 861 | /* 862 | * OPTIONAL: 863 | * lame_encode_flush_nogap will flush the internal mp3 buffers and pad 864 | * the last frame with ancillary data so it is a complete mp3 frame. 865 | * 866 | * 'mp3buf' should be at least 7200 bytes long 867 | * to hold all possible emitted data. 868 | * 869 | * After a call to this routine, the outputed mp3 data is complete, but 870 | * you may continue to encode new PCM samples and write future mp3 data 871 | * to a different file. The two mp3 files will play back with no gaps 872 | * if they are concatenated together. 873 | * 874 | * This routine will NOT write id3v1 tags into the bitstream. 875 | * 876 | * return code = number of bytes output to mp3buf. Can be 0 877 | */ 878 | int CDECL lame_encode_flush_nogap( 879 | lame_global_flags * gfp, /* global context handle */ 880 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 881 | int size); /* number of valid octets in this stream */ 882 | 883 | /* 884 | * OPTIONAL: 885 | * Normally, this is called by lame_init_params(). It writes id3v2 and 886 | * Xing headers into the front of the bitstream, and sets frame counters 887 | * and bitrate histogram data to 0. You can also call this after 888 | * lame_encode_flush_nogap(). 889 | */ 890 | int CDECL lame_init_bitstream( 891 | lame_global_flags * gfp); /* global context handle */ 892 | 893 | 894 | 895 | /* 896 | * OPTIONAL: some simple statistics 897 | * a bitrate histogram to visualize the distribution of used frame sizes 898 | * a stereo mode histogram to visualize the distribution of used stereo 899 | * modes, useful in joint-stereo mode only 900 | * 0: LR left-right encoded 901 | * 1: LR-I left-right and intensity encoded (currently not supported) 902 | * 2: MS mid-side encoded 903 | * 3: MS-I mid-side and intensity encoded (currently not supported) 904 | * 905 | * attention: don't call them after lame_encode_finish 906 | * suggested: lame_encode_flush -> lame_*_hist -> lame_close 907 | */ 908 | 909 | void CDECL lame_bitrate_hist( 910 | const lame_global_flags * gfp, 911 | int bitrate_count[14] ); 912 | void CDECL lame_bitrate_kbps( 913 | const lame_global_flags * gfp, 914 | int bitrate_kbps [14] ); 915 | void CDECL lame_stereo_mode_hist( 916 | const lame_global_flags * gfp, 917 | int stereo_mode_count[4] ); 918 | 919 | void CDECL lame_bitrate_stereo_mode_hist ( 920 | const lame_global_flags * gfp, 921 | int bitrate_stmode_count[14][4] ); 922 | 923 | void CDECL lame_block_type_hist ( 924 | const lame_global_flags * gfp, 925 | int btype_count[6] ); 926 | 927 | void CDECL lame_bitrate_block_type_hist ( 928 | const lame_global_flags * gfp, 929 | int bitrate_btype_count[14][6] ); 930 | 931 | #if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0) 932 | #else 933 | /* 934 | * OPTIONAL: 935 | * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file 936 | * pointer fid. These calls perform forward and backwards seeks, so make 937 | * sure fid is a real file. Make sure lame_encode_flush has been called, 938 | * and all mp3 data has been written to the file before calling this 939 | * function. 940 | * NOTE: 941 | * if VBR tags are turned off by the user, or turned off by LAME because 942 | * the output is not a regular file, this call does nothing 943 | * NOTE: 944 | * LAME wants to read from the file to skip an optional ID3v2 tag, so 945 | * make sure you opened the file for writing and reading. 946 | * NOTE: 947 | * You can call lame_get_lametag_frame instead, if you want to insert 948 | * the lametag yourself. 949 | */ 950 | void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid); 951 | #endif 952 | 953 | /* 954 | * OPTIONAL: 955 | * lame_get_lametag_frame copies the final LAME-tag into 'buffer'. 956 | * The function returns the number of bytes copied into buffer, or 957 | * the required buffer size, if the provided buffer is too small. 958 | * Function failed, if the return value is larger than 'size'! 959 | * Make sure lame_encode flush has been called before calling this function. 960 | * NOTE: 961 | * if VBR tags are turned off by the user, or turned off by LAME, 962 | * this call does nothing and returns 0. 963 | * NOTE: 964 | * LAME inserted an empty frame in the beginning of mp3 audio data, 965 | * which you have to replace by the final LAME-tag frame after encoding. 966 | * In case there is no ID3v2 tag, usually this frame will be the very first 967 | * data in your mp3 file. If you put some other leading data into your 968 | * file, you'll have to do some bookkeeping about where to write this buffer. 969 | */ 970 | size_t CDECL lame_get_lametag_frame( 971 | const lame_global_flags *, unsigned char* buffer, size_t size); 972 | 973 | /* 974 | * REQUIRED: 975 | * final call to free all remaining buffers 976 | */ 977 | int CDECL lame_close (lame_global_flags *); 978 | 979 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 980 | #else 981 | /* 982 | * OBSOLETE: 983 | * lame_encode_finish combines lame_encode_flush() and lame_close() in 984 | * one call. However, once this call is made, the statistics routines 985 | * will no longer work because the data will have been cleared, and 986 | * lame_mp3_tags_fid() cannot be called to add data to the VBR header 987 | */ 988 | int CDECL lame_encode_finish( 989 | lame_global_flags* gfp, 990 | unsigned char* mp3buf, 991 | int size ); 992 | #endif 993 | 994 | 995 | 996 | 997 | 998 | 999 | /********************************************************************* 1000 | * 1001 | * decoding 1002 | * 1003 | * a simple interface to mpglib, part of mpg123, is also included if 1004 | * libmp3lame is compiled with HAVE_MPGLIB 1005 | * 1006 | *********************************************************************/ 1007 | 1008 | struct hip_global_struct; 1009 | typedef struct hip_global_struct hip_global_flags; 1010 | typedef hip_global_flags *hip_t; 1011 | 1012 | 1013 | typedef struct { 1014 | int header_parsed; /* 1 if header was parsed and following data was 1015 | computed */ 1016 | int stereo; /* number of channels */ 1017 | int samplerate; /* sample rate */ 1018 | int bitrate; /* bitrate */ 1019 | int mode; /* mp3 frame type */ 1020 | int mode_ext; /* mp3 frame type */ 1021 | int framesize; /* number of samples per mp3 frame */ 1022 | 1023 | /* this data is only computed if mpglib detects a Xing VBR header */ 1024 | unsigned long nsamp; /* number of samples in mp3 file. */ 1025 | int totalframes; /* total number of frames in mp3 file */ 1026 | 1027 | /* this data is not currently computed by the mpglib routines */ 1028 | int framenum; /* frames decoded counter */ 1029 | } mp3data_struct; 1030 | 1031 | /* required call to initialize decoder */ 1032 | hip_t CDECL hip_decode_init(void); 1033 | 1034 | /* cleanup call to exit decoder */ 1035 | int CDECL hip_decode_exit(hip_t gfp); 1036 | 1037 | /* HIP reporting functions */ 1038 | void CDECL hip_set_errorf(hip_t gfp, lame_report_function f); 1039 | void CDECL hip_set_debugf(hip_t gfp, lame_report_function f); 1040 | void CDECL hip_set_msgf (hip_t gfp, lame_report_function f); 1041 | 1042 | /********************************************************************* 1043 | * input 1 mp3 frame, output (maybe) pcm data. 1044 | * 1045 | * nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r); 1046 | * 1047 | * input: 1048 | * len : number of bytes of mp3 data in mp3buf 1049 | * mp3buf[len] : mp3 data to be decoded 1050 | * 1051 | * output: 1052 | * nout: -1 : decoding error 1053 | * 0 : need more data before we can complete the decode 1054 | * >0 : returned 'nout' samples worth of data in pcm_l,pcm_r 1055 | * pcm_l[nout] : left channel data 1056 | * pcm_r[nout] : right channel data 1057 | * 1058 | *********************************************************************/ 1059 | int CDECL hip_decode( hip_t gfp 1060 | , unsigned char * mp3buf 1061 | , size_t len 1062 | , short pcm_l[] 1063 | , short pcm_r[] 1064 | ); 1065 | 1066 | /* same as hip_decode, and also returns mp3 header data */ 1067 | int CDECL hip_decode_headers( hip_t gfp 1068 | , unsigned char* mp3buf 1069 | , size_t len 1070 | , short pcm_l[] 1071 | , short pcm_r[] 1072 | , mp3data_struct* mp3data 1073 | ); 1074 | 1075 | /* same as hip_decode, but returns at most one frame */ 1076 | int CDECL hip_decode1( hip_t gfp 1077 | , unsigned char* mp3buf 1078 | , size_t len 1079 | , short pcm_l[] 1080 | , short pcm_r[] 1081 | ); 1082 | 1083 | /* same as hip_decode1, but returns at most one frame and mp3 header data */ 1084 | int CDECL hip_decode1_headers( hip_t gfp 1085 | , unsigned char* mp3buf 1086 | , size_t len 1087 | , short pcm_l[] 1088 | , short pcm_r[] 1089 | , mp3data_struct* mp3data 1090 | ); 1091 | 1092 | /* same as hip_decode1_headers, but also returns enc_delay and enc_padding 1093 | from VBR Info tag, (-1 if no info tag was found) */ 1094 | int CDECL hip_decode1_headersB( hip_t gfp 1095 | , unsigned char* mp3buf 1096 | , size_t len 1097 | , short pcm_l[] 1098 | , short pcm_r[] 1099 | , mp3data_struct* mp3data 1100 | , int *enc_delay 1101 | , int *enc_padding 1102 | ); 1103 | 1104 | 1105 | 1106 | /* OBSOLETE: 1107 | * lame_decode... functions are there to keep old code working 1108 | * but it is strongly recommended to replace calls by hip_decode... 1109 | * function calls, see above. 1110 | */ 1111 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1112 | #else 1113 | int CDECL lame_decode_init(void); 1114 | int CDECL lame_decode( 1115 | unsigned char * mp3buf, 1116 | int len, 1117 | short pcm_l[], 1118 | short pcm_r[] ); 1119 | int CDECL lame_decode_headers( 1120 | unsigned char* mp3buf, 1121 | int len, 1122 | short pcm_l[], 1123 | short pcm_r[], 1124 | mp3data_struct* mp3data ); 1125 | int CDECL lame_decode1( 1126 | unsigned char* mp3buf, 1127 | int len, 1128 | short pcm_l[], 1129 | short pcm_r[] ); 1130 | int CDECL lame_decode1_headers( 1131 | unsigned char* mp3buf, 1132 | int len, 1133 | short pcm_l[], 1134 | short pcm_r[], 1135 | mp3data_struct* mp3data ); 1136 | int CDECL lame_decode1_headersB( 1137 | unsigned char* mp3buf, 1138 | int len, 1139 | short pcm_l[], 1140 | short pcm_r[], 1141 | mp3data_struct* mp3data, 1142 | int *enc_delay, 1143 | int *enc_padding ); 1144 | int CDECL lame_decode_exit(void); 1145 | 1146 | #endif /* obsolete lame_decode API calls */ 1147 | 1148 | 1149 | /********************************************************************* 1150 | * 1151 | * id3tag stuff 1152 | * 1153 | *********************************************************************/ 1154 | 1155 | /* 1156 | * id3tag.h -- Interface to write ID3 version 1 and 2 tags. 1157 | * 1158 | * Copyright (C) 2000 Don Melton. 1159 | * 1160 | * This library is free software; you can redistribute it and/or 1161 | * modify it under the terms of the GNU Library General Public 1162 | * License as published by the Free Software Foundation; either 1163 | * version 2 of the License, or (at your option) any later version. 1164 | * 1165 | * This library is distributed in the hope that it will be useful, 1166 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 1167 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1168 | * Library General Public License for more details. 1169 | * 1170 | * You should have received a copy of the GNU Library General Public 1171 | * License along with this library; if not, write to the Free Software 1172 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 1173 | */ 1174 | 1175 | /* utility to obtain alphabetically sorted list of genre names with numbers */ 1176 | void CDECL id3tag_genre_list( 1177 | void (*handler)(int, const char *, void *), 1178 | void* cookie); 1179 | 1180 | void CDECL id3tag_init (lame_t gfp); 1181 | 1182 | /* force addition of version 2 tag */ 1183 | void CDECL id3tag_add_v2 (lame_t gfp); 1184 | 1185 | /* add only a version 1 tag */ 1186 | void CDECL id3tag_v1_only (lame_t gfp); 1187 | 1188 | /* add only a version 2 tag */ 1189 | void CDECL id3tag_v2_only (lame_t gfp); 1190 | 1191 | /* pad version 1 tag with spaces instead of nulls */ 1192 | void CDECL id3tag_space_v1 (lame_t gfp); 1193 | 1194 | /* pad version 2 tag with extra 128 bytes */ 1195 | void CDECL id3tag_pad_v2 (lame_t gfp); 1196 | 1197 | /* pad version 2 tag with extra n bytes */ 1198 | void CDECL id3tag_set_pad (lame_t gfp, size_t n); 1199 | 1200 | void CDECL id3tag_set_title(lame_t gfp, const char* title); 1201 | void CDECL id3tag_set_artist(lame_t gfp, const char* artist); 1202 | void CDECL id3tag_set_album(lame_t gfp, const char* album); 1203 | void CDECL id3tag_set_year(lame_t gfp, const char* year); 1204 | void CDECL id3tag_set_comment(lame_t gfp, const char* comment); 1205 | 1206 | /* return -1 result if track number is out of ID3v1 range 1207 | and ignored for ID3v1 */ 1208 | int CDECL id3tag_set_track(lame_t gfp, const char* track); 1209 | 1210 | /* return non-zero result if genre name or number is invalid 1211 | result 0: OK 1212 | result -1: genre number out of range 1213 | result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other' 1214 | but taken as-is for ID3v2 genre tag */ 1215 | int CDECL id3tag_set_genre(lame_t gfp, const char* genre); 1216 | 1217 | /* return non-zero result if field name is invalid */ 1218 | int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue); 1219 | 1220 | /* return non-zero result if image type is invalid */ 1221 | int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size); 1222 | 1223 | /* lame_get_id3v1_tag copies ID3v1 tag into buffer. 1224 | * Function returns number of bytes copied into buffer, or number 1225 | * of bytes rquired if buffer 'size' is too small. 1226 | * Function fails, if returned value is larger than 'size'. 1227 | * NOTE: 1228 | * This functions does nothing, if user/LAME disabled ID3v1 tag. 1229 | */ 1230 | size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size); 1231 | 1232 | /* lame_get_id3v2_tag copies ID3v2 tag into buffer. 1233 | * Function returns number of bytes copied into buffer, or number 1234 | * of bytes rquired if buffer 'size' is too small. 1235 | * Function fails, if returned value is larger than 'size'. 1236 | * NOTE: 1237 | * This functions does nothing, if user/LAME disabled ID3v2 tag. 1238 | */ 1239 | size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size); 1240 | 1241 | /* normaly lame_init_param writes ID3v2 tags into the audio stream 1242 | * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param 1243 | * to turn off this behaviour and get ID3v2 tag with above function 1244 | * write it yourself into your file. 1245 | */ 1246 | void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int); 1247 | int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp); 1248 | 1249 | /* experimental */ 1250 | int CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text); 1251 | 1252 | /* experimental */ 1253 | int CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text); 1254 | 1255 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1256 | #else 1257 | /* experimental */ 1258 | int CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text); 1259 | 1260 | /* experimental */ 1261 | int CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang, 1262 | unsigned short const *desc, unsigned short const *text); 1263 | 1264 | /* experimental */ 1265 | int CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue); 1266 | #endif 1267 | 1268 | /* experimental */ 1269 | int CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue); 1270 | 1271 | /* experimental */ 1272 | int CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text); 1273 | 1274 | /* experimental */ 1275 | int CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text); 1276 | 1277 | 1278 | /*********************************************************************** 1279 | * 1280 | * list of valid bitrates [kbps] & sample frequencies [Hz]. 1281 | * first index: 0: MPEG-2 values (sample frequencies 16...24 kHz) 1282 | * 1: MPEG-1 values (sample frequencies 32...48 kHz) 1283 | * 2: MPEG-2.5 values (sample frequencies 8...12 kHz) 1284 | ***********************************************************************/ 1285 | 1286 | extern const int bitrate_table [3][16]; 1287 | extern const int samplerate_table [3][ 4]; 1288 | 1289 | /* access functions for use in DLL, global vars are not exported */ 1290 | int CDECL lame_get_bitrate(int mpeg_version, int table_index); 1291 | int CDECL lame_get_samplerate(int mpeg_version, int table_index); 1292 | 1293 | 1294 | /* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER 1295 | as well since lame_encode_buffer() also returns ID3v2 tag data */ 1296 | #define LAME_MAXALBUMART (128 * 1024) 1297 | 1298 | /* maximum size of mp3buffer needed if you encode at most 1152 samples for 1299 | each call to lame_encode_buffer. see lame_encode_buffer() below 1300 | (LAME_MAXMP3BUFFER is now obsolete) */ 1301 | #define LAME_MAXMP3BUFFER (16384 + LAME_MAXALBUMART) 1302 | 1303 | 1304 | typedef enum { 1305 | LAME_OKAY = 0, 1306 | LAME_NOERROR = 0, 1307 | LAME_GENERICERROR = -1, 1308 | LAME_NOMEM = -10, 1309 | LAME_BADBITRATE = -11, 1310 | LAME_BADSAMPFREQ = -12, 1311 | LAME_INTERNALERROR = -13, 1312 | 1313 | FRONTEND_READERROR = -80, 1314 | FRONTEND_WRITEERROR = -81, 1315 | FRONTEND_FILETOOLARGE = -82 1316 | 1317 | } lame_errorcodes_t; 1318 | 1319 | #if defined(__cplusplus) 1320 | } 1321 | #endif 1322 | #endif /* LAME_LAME_H */ 1323 | 1324 | --------------------------------------------------------------------------------