Browse Source

添加驰声、腾讯语音评测

rhyme 5 years ago
parent
commit
52b569c585

+ 21 - 21
.idea/libraries/Dart_SDK.xml

@@ -1,27 +1,27 @@
 <component name="libraryTable">
 <component name="libraryTable">
   <library name="Dart SDK">
   <library name="Dart SDK">
     <CLASSES>
     <CLASSES>
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/async" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/cli" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/collection" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/convert" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/core" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/developer" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/ffi" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/html" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/indexed_db" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/io" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/isolate" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/js" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/js_util" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/math" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/mirrors" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/svg" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/typed_data" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/wasm" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/web_audio" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/web_gl" />
-      <root url="file://C:/flutter/flutter/bin/cache/dart-sdk/lib/web_sql" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/async" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/cli" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/collection" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/convert" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/core" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/developer" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/ffi" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/html" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/indexed_db" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/io" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/isolate" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/js" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/js_util" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/math" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/mirrors" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/svg" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/typed_data" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/wasm" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/web_audio" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/web_gl" />
+      <root url="file://$PROJECT_DIR$/../../../../flutter/bin/cache/dart-sdk/lib/web_sql" />
     </CLASSES>
     </CLASSES>
     <JAVADOC />
     <JAVADOC />
     <SOURCES />
     <SOURCES />

+ 1 - 0
.idea/vcs.xml

@@ -2,5 +2,6 @@
 <project version="4">
 <project version="4">
   <component name="VcsDirectoryMappings">
   <component name="VcsDirectoryMappings">
     <mapping directory="$PROJECT_DIR$" vcs="Git" />
     <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin" vcs="Git" />
   </component>
   </component>
 </project>
 </project>

+ 263 - 38
.idea/workspace.xml

@@ -6,12 +6,33 @@
   </component>
   </component>
   <component name="ChangeListManager">
   <component name="ChangeListManager">
     <list default="true" id="91fb8cbe-3946-4eca-a4cf-05dab52b73c6" name="Default Changelist" comment="">
     <list default="true" id="91fb8cbe-3946-4eca-a4cf-05dab52b73c6" name="Default Changelist" comment="">
-      <change afterPath="$PROJECT_DIR$/android/src/main/assets/hello_guagua.mp3" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/Classes/Libraries/libai/aiengine.h" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/Classes/Libraries/libai/aiengine.provision" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/Classes/Libraries/libai/libaiengine.a" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/ios/Classes/Libraries/libai/aiengine.h" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/ios/Classes/Libraries/libai/aiengine.provision" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/ios/Classes/Libraries/libai/libaiengine.a" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/libraries/Dart_SDK.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/libraries/Dart_SDK.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/.idea/caches/build_file_checksums.ser" beforeDir="false" afterPath="$PROJECT_DIR$/android/.idea/caches/build_file_checksums.ser" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/android/build.gradle" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/SpeechPlugin.kt" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/SpeechPlugin.kt" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/util/SmartOralAudioEvaluatorUtil.kt" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/util/SmartOralAudioEvaluatorUtil.kt" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/libraries/Dart_SDK.xml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/libraries/Dart_SDK.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/vcs.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/.idea/workspace.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/example/ios/Podfile.lock" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/example/ios/Podfile.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/example/pubspec.lock" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/example/pubspec.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/Classes/SpeechPlugin.m" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/Classes/SpeechPlugin.m" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/speech_plugin.podspec" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/ios/speech_plugin.podspec" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/lib/speech_plugin.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/lib/speech_plugin.dart" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/pubspec.lock" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/pubspec.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/speech_plugin.iml" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/.symlinks/plugins/speech_plugin/speech_plugin.iml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/Podfile.lock" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Podfile.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/example/pubspec.lock" beforeDir="false" afterPath="$PROJECT_DIR$/example/pubspec.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/ios/Classes/SpeechPlugin.m" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SpeechPlugin.m" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/ios/speech_plugin.podspec" beforeDir="false" afterPath="$PROJECT_DIR$/ios/speech_plugin.podspec" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/lib/speech_plugin.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/speech_plugin.dart" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/pubspec.lock" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.lock" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/speech_plugin.iml" beforeDir="false" afterPath="$PROJECT_DIR$/speech_plugin.iml" afterDir="false" />
     </list>
     </list>
     <ignored path="$PROJECT_DIR$/.dart_tool/" />
     <ignored path="$PROJECT_DIR$/.dart_tool/" />
     <ignored path="$PROJECT_DIR$/.idea/" />
     <ignored path="$PROJECT_DIR$/.idea/" />
@@ -26,17 +47,66 @@
     <option name="LAST_RESOLUTION" value="IGNORE" />
     <option name="LAST_RESOLUTION" value="IGNORE" />
   </component>
   </component>
   <component name="DefaultGradleProjectSettings">
   <component name="DefaultGradleProjectSettings">
-    <option name="testRunner" value="GRADLE" />
-    <option name="delegatedBuild" value="true" />
+    <option name="isMigrated" value="true" />
   </component>
   </component>
-  <component name="ExecutionTargetManager" SELECTED_TARGET="792QAESFTC6MD" />
+  <component name="ExecutionTargetManager" SELECTED_TARGET="Pixel_2_API_29" />
   <component name="FileEditorManager">
   <component name="FileEditorManager">
     <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
     <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
-      <file pinned="false" current-in-tab="true">
+      <file pinned="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/lib/speech_plugin.dart">
         <entry file="file://$PROJECT_DIR$/lib/speech_plugin.dart">
           <provider selected="true" editor-type-id="text-editor">
           <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="285">
-              <caret line="78" column="31" lean-forward="true" selection-start-line="78" selection-start-column="31" selection-end-line="78" selection-end-column="31" />
+            <state relative-caret-position="98">
+              <caret line="58" column="13" selection-start-line="58" selection-start-column="13" selection-end-line="58" selection-end-column="13" />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/android/.gitignore">
+          <provider selected="true" editor-type-id="text-editor" />
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/SpeechPlugin.kt">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="228">
+              <caret line="152" column="24" selection-start-line="152" selection-start-column="24" selection-end-line="152" selection-end-column="24" />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/audioUtils/bean/SimpleWord.kt">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="30">
+              <caret line="2" column="40" lean-forward="true" selection-start-line="2" selection-start-column="40" selection-end-line="2" selection-end-column="40" />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/util/SmartOralAudioEvaluatorUtil.kt">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="217">
+              <caret line="95" column="38" lean-forward="true" selection-start-line="95" selection-start-column="38" selection-end-line="95" selection-end-column="38" />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/ios/speech_plugin.podspec">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="330">
+              <caret line="22" column="56" selection-start-line="22" selection-start-column="56" selection-end-line="22" selection-end-column="56" />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/ios/Classes/SpeechPlugin.m">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="1905">
+              <caret line="128" column="26" selection-start-line="128" selection-start-column="26" selection-end-line="128" selection-end-column="26" />
             </state>
             </state>
           </provider>
           </provider>
         </entry>
         </entry>
@@ -44,7 +114,7 @@
       <file pinned="false" current-in-tab="false">
       <file pinned="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/.gitignore">
         <entry file="file://$PROJECT_DIR$/.gitignore">
           <provider selected="true" editor-type-id="text-editor">
           <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="154">
+            <state relative-caret-position="105">
               <caret line="7" selection-start-line="7" selection-end-line="7" />
               <caret line="7" selection-start-line="7" selection-end-line="7" />
             </state>
             </state>
           </provider>
           </provider>
@@ -56,6 +126,7 @@
     <findStrings>
     <findStrings>
       <find>invokeMethod</find>
       <find>invokeMethod</find>
       <find>soeAppId</find>
       <find>soeAppId</find>
+      <find>totalScore</find>
     </findStrings>
     </findStrings>
   </component>
   </component>
   <component name="Git.Settings">
   <component name="Git.Settings">
@@ -65,14 +136,14 @@
     <option name="CHANGED_PATHS">
     <option name="CHANGED_PATHS">
       <list>
       <list>
         <option value="$PROJECT_DIR$/lib/speech_plugin.dart" />
         <option value="$PROJECT_DIR$/lib/speech_plugin.dart" />
+        <option value="$PROJECT_DIR$/ios/speech_plugin.podspec" />
       </list>
       </list>
     </option>
     </option>
   </component>
   </component>
-  <component name="ProjectFrameBounds" extendedState="6">
-    <option name="x" value="395" />
-    <option name="y" value="42" />
-    <option name="width" value="1346" />
-    <option name="height" value="955" />
+  <component name="ProjectFrameBounds">
+    <option name="y" value="23" />
+    <option name="width" value="1440" />
+    <option name="height" value="877" />
   </component>
   </component>
   <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
   <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
   <component name="ProjectView">
   <component name="ProjectView">
@@ -84,24 +155,141 @@
         <subPane>
         <subPane>
           <expand>
           <expand>
             <path>
             <path>
-              <item name="speech_plugin" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
               <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
               <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
             </path>
             </path>
             <path>
             <path>
-              <item name="speech_plugin" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
               <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
               <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
-              <item name="lib" type="462c0819:PsiDirectoryNode" />
+              <item name="audioUtils" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
+              <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
+              <item name="audioUtils" type="462c0819:PsiDirectoryNode" />
+              <item name="bean" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
+              <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
+              <item name="model" type="462c0819:PsiDirectoryNode" />
             </path>
             </path>
             <path>
             <path>
-              <item name="speech_plugin" type="b2602c69:ProjectViewProjectNode" />
-              <item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="android" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="main" type="462c0819:PsiDirectoryNode" />
+              <item name="kotlin" type="462c0819:PsiDirectoryNode" />
+              <item name="cn" type="462c0819:PsiDirectoryNode" />
+              <item name="i2edu" type="462c0819:PsiDirectoryNode" />
+              <item name="speech_plugin" type="462c0819:PsiDirectoryNode" />
+              <item name="util" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="ios" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="ios" type="462c0819:PsiDirectoryNode" />
+              <item name="Classes" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="ios" type="462c0819:PsiDirectoryNode" />
+              <item name="Frameworks" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="speech_lib" type="b2602c69:ProjectViewProjectNode" />
+              <item name="speech_lib" type="462c0819:PsiDirectoryNode" />
+              <item name="lib" type="462c0819:PsiDirectoryNode" />
             </path>
             </path>
           </expand>
           </expand>
           <select />
           <select />
         </subPane>
         </subPane>
       </pane>
       </pane>
       <pane id="PackagesPane" />
       <pane id="PackagesPane" />
-      <pane id="AndroidView" />
       <pane id="Scope" />
       <pane id="Scope" />
     </panes>
     </panes>
   </component>
   </component>
@@ -112,6 +300,11 @@
     <property name="settings.editor.selected.configurable" value="flutter.settings" />
     <property name="settings.editor.selected.configurable" value="flutter.settings" />
     <property name="show.migrate.to.gradle.popup" value="false" />
     <property name="show.migrate.to.gradle.popup" value="false" />
   </component>
   </component>
+  <component name="RecentsManager">
+    <key name="MoveFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$/ios/Frameworks" />
+    </key>
+  </component>
   <component name="RunDashboard">
   <component name="RunDashboard">
     <option name="ruleStates">
     <option name="ruleStates">
       <list>
       <list>
@@ -138,10 +331,10 @@
     <servers />
     <servers />
   </component>
   </component>
   <component name="ToolWindowManager">
   <component name="ToolWindowManager">
-    <frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
+    <frame x="0" y="23" width="1440" height="877" extended-state="0" />
     <editor active="true" />
     <editor active="true" />
     <layout>
     <layout>
-      <window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.14658849" />
+      <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.22246066" />
       <window_info id="Captures" order="1" side_tool="true" />
       <window_info id="Captures" order="1" side_tool="true" />
       <window_info id="Structure" order="2" side_tool="true" />
       <window_info id="Structure" order="2" side_tool="true" />
       <window_info id="Image Layers" order="3" />
       <window_info id="Image Layers" order="3" />
@@ -156,11 +349,11 @@
       <window_info anchor="bottom" id="Android Profiler" order="3" show_stripe_button="false" />
       <window_info anchor="bottom" id="Android Profiler" order="3" show_stripe_button="false" />
       <window_info active="true" anchor="bottom" id="Logcat" order="4" visible="true" weight="0.3286334" />
       <window_info active="true" anchor="bottom" id="Logcat" order="4" visible="true" weight="0.3286334" />
       <window_info anchor="bottom" id="Debug" order="5" />
       <window_info anchor="bottom" id="Debug" order="5" />
-      <window_info anchor="bottom" id="Terminal" order="6" weight="0.329718" />
+      <window_info anchor="bottom" id="Terminal" order="6" visible="true" weight="0.3713911" />
       <window_info anchor="bottom" id="Event Log" order="7" side_tool="true" />
       <window_info anchor="bottom" id="Event Log" order="7" side_tool="true" />
       <window_info anchor="bottom" id="Flutter Performance" order="8" side_tool="true" />
       <window_info anchor="bottom" id="Flutter Performance" order="8" side_tool="true" />
       <window_info anchor="bottom" id="Version Control" order="9" />
       <window_info anchor="bottom" id="Version Control" order="9" />
-      <window_info anchor="bottom" id="Messages" order="10" weight="0.3299435" />
+      <window_info anchor="bottom" id="Messages" order="10" weight="0.17847769" />
       <window_info anchor="right" id="Device File Explorer" order="0" side_tool="true" />
       <window_info anchor="right" id="Device File Explorer" order="0" side_tool="true" />
       <window_info anchor="right" id="Capture Analysis" order="1" />
       <window_info anchor="right" id="Capture Analysis" order="1" />
       <window_info anchor="right" id="Theme Preview" order="2" />
       <window_info anchor="right" id="Theme Preview" order="2" />
@@ -184,31 +377,63 @@
         </state>
         </state>
       </provider>
       </provider>
     </entry>
     </entry>
-    <entry file="file://C:/flutter/flutter/packages/flutter/lib/src/services/platform_channel.dart">
+    <entry file="file://C:/flutter/flutter/packages/flutter/lib/src/services/platform_channel.dart" />
+    <entry file="file://$PROJECT_DIR$/ios/speech_plugin.podspec">
       <provider selected="true" editor-type-id="text-editor">
       <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="298">
-          <caret line="311" column="12" selection-start-line="311" selection-start-column="12" selection-end-line="311" selection-end-column="12" />
+        <state relative-caret-position="330">
+          <caret line="22" column="56" selection-start-line="22" selection-start-column="56" selection-end-line="22" selection-end-column="56" />
         </state>
         </state>
       </provider>
       </provider>
     </entry>
     </entry>
-    <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/SpeechPlugin.kt">
+    <entry file="file://$PROJECT_DIR$/ios/Classes/SpeechPlugin.m">
       <provider selected="true" editor-type-id="text-editor">
       <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="154">
-          <caret line="136" selection-start-line="136" selection-end-line="136" />
+        <state relative-caret-position="1905">
+          <caret line="128" column="26" selection-start-line="128" selection-start-column="26" selection-end-line="128" selection-end-column="26" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/.gitignore">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="105">
+          <caret line="7" selection-start-line="7" selection-end-line="7" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/android/src/main/java/com/chivox/AIEngine.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-1332">
+          <caret line="2" column="19" selection-start-line="2" selection-start-column="19" selection-end-line="2" selection-end-column="19" />
         </state>
         </state>
       </provider>
       </provider>
     </entry>
     </entry>
     <entry file="file://$PROJECT_DIR$/lib/speech_plugin.dart">
     <entry file="file://$PROJECT_DIR$/lib/speech_plugin.dart">
       <provider selected="true" editor-type-id="text-editor">
       <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="285">
-          <caret line="78" column="31" lean-forward="true" selection-start-line="78" selection-start-column="31" selection-end-line="78" selection-end-column="31" />
+        <state relative-caret-position="98">
+          <caret line="58" column="13" selection-start-line="58" selection-start-column="13" selection-end-line="58" selection-end-column="13" />
         </state>
         </state>
       </provider>
       </provider>
     </entry>
     </entry>
-    <entry file="file://$PROJECT_DIR$/.gitignore">
+    <entry file="file://$PROJECT_DIR$/android/.gitignore">
+      <provider selected="true" editor-type-id="text-editor" />
+    </entry>
+    <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/util/SmartOralAudioEvaluatorUtil.kt">
       <provider selected="true" editor-type-id="text-editor">
       <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="154">
-          <caret line="7" selection-start-line="7" selection-end-line="7" />
+        <state relative-caret-position="217">
+          <caret line="95" column="38" lean-forward="true" selection-start-line="95" selection-start-column="38" selection-end-line="95" selection-end-column="38" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/SpeechPlugin.kt">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="228">
+          <caret line="152" column="24" selection-start-line="152" selection-start-column="24" selection-end-line="152" selection-end-column="24" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/android/src/main/kotlin/cn/i2edu/speech_plugin/audioUtils/bean/SimpleWord.kt">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="30">
+          <caret line="2" column="40" lean-forward="true" selection-start-line="2" selection-start-column="40" selection-end-line="2" selection-end-column="40" />
         </state>
         </state>
       </provider>
       </provider>
     </entry>
     </entry>

+ 1 - 0
example/android/res/values/strings_en.arb

@@ -0,0 +1 @@
+{}

+ 1 - 1
example/ios/Podfile.lock

@@ -15,7 +15,7 @@ EXTERNAL SOURCES:
 
 
 SPEC CHECKSUMS:
 SPEC CHECKSUMS:
   Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
   Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
-  speech_plugin: 4d6162d5c4b864182810b9300668986467ee0a94
+  speech_plugin: f602a06719916976112860387281f36605d99a56
 
 
 PODFILE CHECKSUM: 3dbe063e9c90a5d7c9e4e76e70a821b9e2c1d271
 PODFILE CHECKSUM: 3dbe063e9c90a5d7c9e4e76e70a821b9e2c1d271
 
 

+ 16 - 0
example/ios/Runner.xcodeproj/project.pbxproj

@@ -162,6 +162,7 @@
 				9705A1C41CF9048500538489 /* Embed Frameworks */,
 				9705A1C41CF9048500538489 /* Embed Frameworks */,
 				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
 				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
 				C9816D6ACD4932443EF75500 /* [CP] Embed Pods Frameworks */,
 				C9816D6ACD4932443EF75500 /* [CP] Embed Pods Frameworks */,
+				669486AE96A3269861E0886A /* [CP] Copy Pods Resources */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -234,6 +235,21 @@
 			shellPath = /bin/sh;
 			shellPath = /bin/sh;
 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
 		};
 		};
+		669486AE96A3269861E0886A /* [CP] Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "[CP] Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 		8AABC13A4AE969899678E386 /* [CP] Check Pods Manifest.lock */ = {
 		8AABC13A4AE969899678E386 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;

+ 126 - 0
example/lib/generated/i18n.dart

@@ -0,0 +1,126 @@
+import 'dart:async';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: camel_case_types
+// ignore_for_file: prefer_single_quotes
+
+// This file is automatically generated. DO NOT EDIT, all your changes would be lost.
+class S implements WidgetsLocalizations {
+  const S();
+
+  static S current;
+
+  static const GeneratedLocalizationsDelegate delegate =
+    GeneratedLocalizationsDelegate();
+
+  static S of(BuildContext context) => Localizations.of<S>(context, S);
+
+  @override
+  TextDirection get textDirection => TextDirection.ltr;
+
+}
+
+class $en extends S {
+  const $en();
+}
+
+class GeneratedLocalizationsDelegate extends LocalizationsDelegate<S> {
+  const GeneratedLocalizationsDelegate();
+
+  List<Locale> get supportedLocales {
+    return const <Locale>[
+      Locale("en", ""),
+    ];
+  }
+
+  LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) {
+    return (List<Locale> locales, Iterable<Locale> supported) {
+      if (locales == null || locales.isEmpty) {
+        return fallback ?? supported.first;
+      } else {
+        return _resolve(locales.first, fallback, supported, withCountry);
+      }
+    };
+  }
+
+  LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) {
+    return (Locale locale, Iterable<Locale> supported) {
+      return _resolve(locale, fallback, supported, withCountry);
+    };
+  }
+
+  @override
+  Future<S> load(Locale locale) {
+    final String lang = getLang(locale);
+    if (lang != null) {
+      switch (lang) {
+        case "en":
+          S.current = const $en();
+          return SynchronousFuture<S>(S.current);
+        default:
+          // NO-OP.
+      }
+    }
+    S.current = const S();
+    return SynchronousFuture<S>(S.current);
+  }
+
+  @override
+  bool isSupported(Locale locale) => _isSupported(locale, true);
+
+  @override
+  bool shouldReload(GeneratedLocalizationsDelegate old) => false;
+
+  ///
+  /// Internal method to resolve a locale from a list of locales.
+  ///
+  Locale _resolve(Locale locale, Locale fallback, Iterable<Locale> supported, bool withCountry) {
+    if (locale == null || !_isSupported(locale, withCountry)) {
+      return fallback ?? supported.first;
+    }
+
+    final Locale languageLocale = Locale(locale.languageCode, "");
+    if (supported.contains(locale)) {
+      return locale;
+    } else if (supported.contains(languageLocale)) {
+      return languageLocale;
+    } else {
+      final Locale fallbackLocale = fallback ?? supported.first;
+      return fallbackLocale;
+    }
+  }
+
+  ///
+  /// Returns true if the specified locale is supported, false otherwise.
+  ///
+  bool _isSupported(Locale locale, bool withCountry) {
+    if (locale != null) {
+      for (Locale supportedLocale in supportedLocales) {
+        // Language must always match both locales.
+        if (supportedLocale.languageCode != locale.languageCode) {
+          continue;
+        }
+
+        // If country code matches, return this locale.
+        if (supportedLocale.countryCode == locale.countryCode) {
+          return true;
+        }
+
+        // If no country requirement is requested, check if this locale has no country.
+        if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+String getLang(Locale l) => l == null
+  ? null
+  : l.countryCode != null && l.countryCode.isEmpty
+    ? l.languageCode
+    : l.toString();

+ 25 - 25
example/pubspec.lock

@@ -5,63 +5,63 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: archive
       name: archive
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.11"
     version: "2.0.11"
   args:
   args:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: args
       name: args
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.5.2"
     version: "1.5.2"
   async:
   async:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: async
       name: async
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.4.0"
     version: "2.4.0"
   boolean_selector:
   boolean_selector:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: boolean_selector
       name: boolean_selector
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.0.5"
     version: "1.0.5"
   charcode:
   charcode:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: charcode
       name: charcode
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.2"
     version: "1.1.2"
   collection:
   collection:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: collection
       name: collection
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.14.11"
     version: "1.14.11"
   convert:
   convert:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: convert
       name: convert
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.1"
     version: "2.1.1"
   crypto:
   crypto:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: crypto
       name: crypto
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.3"
     version: "2.1.3"
   cupertino_icons:
   cupertino_icons:
     dependency: "direct main"
     dependency: "direct main"
     description:
     description:
       name: cupertino_icons
       name: cupertino_icons
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "0.1.3"
     version: "0.1.3"
   flutter:
   flutter:
@@ -78,49 +78,49 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: image
       name: image
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.4"
     version: "2.1.4"
   matcher:
   matcher:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: matcher
       name: matcher
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "0.12.6"
     version: "0.12.6"
   meta:
   meta:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: meta
       name: meta
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.8"
     version: "1.1.8"
   path:
   path:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path
       name: path
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.6.4"
     version: "1.6.4"
   pedantic:
   pedantic:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: pedantic
       name: pedantic
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.8.0+1"
     version: "1.8.0+1"
   petitparser:
   petitparser:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: petitparser
       name: petitparser
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.4.0"
     version: "2.4.0"
   quiver:
   quiver:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: quiver
       name: quiver
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.5"
     version: "2.0.5"
   sky_engine:
   sky_engine:
@@ -132,7 +132,7 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: source_span
       name: source_span
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.5.5"
     version: "1.5.5"
   speech_plugin:
   speech_plugin:
@@ -146,56 +146,56 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: stack_trace
       name: stack_trace
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.9.3"
     version: "1.9.3"
   stream_channel:
   stream_channel:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: stream_channel
       name: stream_channel
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.0"
     version: "2.0.0"
   string_scanner:
   string_scanner:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: string_scanner
       name: string_scanner
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.0.5"
     version: "1.0.5"
   term_glyph:
   term_glyph:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: term_glyph
       name: term_glyph
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.0"
     version: "1.1.0"
   test_api:
   test_api:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: test_api
       name: test_api
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "0.2.11"
     version: "0.2.11"
   typed_data:
   typed_data:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: typed_data
       name: typed_data
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.6"
     version: "1.1.6"
   vector_math:
   vector_math:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: vector_math
       name: vector_math
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.8"
     version: "2.0.8"
   xml:
   xml:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: xml
       name: xml
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "3.5.0"
     version: "3.5.0"
 sdks:
 sdks:

+ 69 - 0
ios/Classes/Libraries/libai/aiengine.h

@@ -0,0 +1,69 @@
+#ifndef AIENGINE_H_
+#define AIENGINE_H_
+
+#define AIENGINE_VERSION "2.2.8"
+
+#if (!(defined AIENGINE_CALL) || !(defined AIENGINE_IMPORT_OR_EXPORT))
+#    if defined __WIN32__ || defined _WIN32 || defined _WIN64
+#       define AIENGINE_CALL __stdcall
+#       ifdef  AIENGINE_IMPLEMENTION
+#           define AIENGINE_IMPORT_OR_EXPORT __declspec(dllexport)
+#       else
+#           define AIENGINE_IMPORT_OR_EXPORT __declspec(dllimport)
+#       endif
+#    else
+#       define AIENGINE_CALL
+#       define AIENGINE_IMPORT_OR_EXPORT __attribute ((visibility("default")))
+#    endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    AIENGINE_MESSAGE_TYPE_JSON = 1,
+    AIENGINE_MESSAGE_TYPE_BIN
+};
+
+#define AIENGINE_GET_VERSION       AIENGINE_OPT_GET_VERSION
+#define AIENGINE_GET_MODULES       AIENGINE_OPT_GET_MODULES
+#define AIENGINE_GET_TRAFFIC       AIENGINE_OPT_GET_TRAFFIC
+#define AIENGINE_SET_WIFI_STATUS   AIENGINE_OPT_SET_WIFI_STATUS
+#define AIENGINE_GET_PROVISION     AIENGINE_OPT_GET_PROVISION
+#define AIENGINE_GET_SERIAL_NUMBER AIENGINE_OPT_GET_SERIAL_NUMBER
+#define AIENGINE_SET_AILAS_ADDRESS AIENGINE_OPT_SET_AILAS_ADDRESS
+
+enum {
+    AIENGINE_OPT_INVALID  = 0,
+    AIENGINE_OPT_GET_VERSION,
+    AIENGINE_OPT_GET_MODULES,
+    AIENGINE_OPT_GET_TRAFFIC,
+    AIENGINE_OPT_SET_WIFI_STATUS,
+    AIENGINE_OPT_GET_PROVISION,
+    AIENGINE_OPT_GET_SERIAL_NUMBER,
+    AIENGINE_OPT_SET_AILAS_ADDRESS,
+    AIENGINE_OPT_MAX
+};
+
+struct aiengine;
+
+typedef int (AIENGINE_CALL *aiengine_callback)(const void *usrdata, const char *id, int type, const void *message, int size);
+AIENGINE_IMPORT_OR_EXPORT struct aiengine *AIENGINE_CALL aiengine_new(const char *cfg);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_delete(struct aiengine *engine);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_start(struct aiengine *engine, const char *param, char id[64], aiengine_callback callback, const void *usrdata);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_feed(struct aiengine *engine, const void *data, int size);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_stop(struct aiengine *engine);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_redo(struct aiengine *engine, char id[64], aiengine_callback callback, const void *usrdata);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_log(struct aiengine *engine, const char *log);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_device_id(char device_id[64]);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_cancel(struct aiengine *engine);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_opt(struct aiengine *engine, int opt, char *data, int size);
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_last_error_code();
+AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_last_sub_error_code();
+AIENGINE_IMPORT_OR_EXPORT const char *AIENGINE_CALL aiengine_get_last_error_text();
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 1 - 0
ios/Classes/Libraries/libai/aiengine.provision

@@ -0,0 +1 @@
+侍饰颂掏滔滔滔涛伤墒茩松推怂蕷浵櫶锨似铺殯虤洐仁澤藴毴菣屯烫虦炂澤菧浲湠灆灉蓻殮洑贤伤櫄灋螢蔀仙撬翁莆迫澢蠙溙洖

BIN
ios/Classes/Libraries/libai/libaiengine.a


+ 293 - 21
ios/Classes/SpeechPlugin.m

@@ -5,17 +5,22 @@
 #import "Results/ISEResult.h"
 #import "Results/ISEResult.h"
 #import "Results/ISEResultXmlParser.h"
 #import "Results/ISEResultXmlParser.h"
 #import "Results/ISEResultTools.h"
 #import "Results/ISEResultTools.h"
+#import "aiengine.h"
+#import <TAISDK/TAISDK.h>
+#import <TAISDK/TAIOralEvaluation.h>
 
 
-@interface SpeechPlugin () <IFlySpeechEvaluatorDelegate, ISEResultXmlParserDelegate>
+@interface SpeechPlugin () <IFlySpeechEvaluatorDelegate, ISEResultXmlParserDelegate,TAIOralEvaluationDelegate>
 @property (nonatomic, strong) IFlySpeechEvaluator *iFlySpeechEvaluator;
 @property (nonatomic, strong) IFlySpeechEvaluator *iFlySpeechEvaluator;
 @property (nonatomic, strong) NSNumber *index;
 @property (nonatomic, strong) NSNumber *index;
+@property struct aiengine * engine;
+@property (strong, nonatomic) TAIOralEvaluation *oralEvaluation;
 @end
 @end
 
 
 @implementation SpeechPlugin
 @implementation SpeechPlugin
 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
     _channel = [FlutterMethodChannel
     _channel = [FlutterMethodChannel
-                                     methodChannelWithName:@"speech_plugin"
-                                     binaryMessenger:[registrar messenger]];
+                methodChannelWithName:@"speech_plugin"
+                binaryMessenger:[registrar messenger]];
     SpeechPlugin* instance = [[SpeechPlugin alloc] init];
     SpeechPlugin* instance = [[SpeechPlugin alloc] init];
     [registrar addMethodCallDelegate:instance channel: _channel];
     [registrar addMethodCallDelegate:instance channel: _channel];
 }
 }
@@ -25,16 +30,30 @@
         result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
         result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
     } else if ([@"initSpeechSdk" isEqualToString:call.method]) {
     } else if ([@"initSpeechSdk" isEqualToString:call.method]) {
         [self iflyInit];
         [self iflyInit];
+        self.oralEvaluation=[[TAIOralEvaluation alloc]init];
+        self.oralEvaluation.delegate=self;
+        
     }  else if ([@"evaluatorByAudio" isEqualToString:call.method]) {
     }  else if ([@"evaluatorByAudio" isEqualToString:call.method]) {
         NSNumber* index = call.arguments[@"index"];
         NSNumber* index = call.arguments[@"index"];
         NSString* recordPath = call.arguments[@"recordPath"];
         NSString* recordPath = call.arguments[@"recordPath"];
         NSString* text = call.arguments[@"en"];
         NSString* text = call.arguments[@"en"];
-        [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:false];
+        NSString* pathEvaluatorDecode = call.arguments[@"pathEvaluatorDecode"];
+        NSString* videoId = call.arguments[@"videoId"];
+        NSNumber* evaluatorType = call.arguments[@"evaluatorType"];
+        NSNumber* sdkType = call.arguments[@"sdkType"];
+        
+        [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:false pathEvaluatorDecode:pathEvaluatorDecode videoId:videoId evaluatorType:evaluatorType sdkType:sdkType];
     }  else if ([@"evaluatorByMp4" isEqualToString:call.method]) {
     }  else if ([@"evaluatorByMp4" isEqualToString:call.method]) {
         NSNumber* index = call.arguments[@"index"];
         NSNumber* index = call.arguments[@"index"];
         NSString* recordPath = call.arguments[@"recordPath"];
         NSString* recordPath = call.arguments[@"recordPath"];
         NSString* text = call.arguments[@"en"];
         NSString* text = call.arguments[@"en"];
-        [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:true];
+        NSString* pathEvaluatorDecode = call.arguments[@"pathEvaluatorDecode"];
+        NSString* videoId = call.arguments[@"videoId"];
+        NSNumber* evaluatorType = call.arguments[@"evaluatorType"];
+        NSNumber* sdkType = call.arguments[@"sdkType"];
+        
+        [self evaluateVoice:index andPath:recordPath andText:text andIsVideo:true
+        pathEvaluatorDecode:pathEvaluatorDecode videoId:videoId evaluatorType:evaluatorType sdkType:sdkType];
     } else {
     } else {
         result(FlutterMethodNotImplemented);
         result(FlutterMethodNotImplemented);
     }
     }
@@ -49,6 +68,103 @@
     [self configEvaluator];
     [self configEvaluator];
 }
 }
 
 
+- (void)chivosInit:(NSString *)en
+{
+    char cfg[4096];
+    char version[512] = {0};
+    char record_id[64] = {0};
+    char param[4096];
+    NSString* user_id = @"ios_user";
+    
+    /*获取当前SDK版本号*/
+    aiengine_opt(NULL, AIENGINE_OPT_GET_VERSION, version, sizeof(version));
+    NSLog(@"version: %s\n",version);
+    
+    /*获取证书路径*/
+    NSString * provision = [[NSBundle mainBundle] pathForResource:@"aiengine" ofType:@"provision"];
+    /*引擎初始化传参设置*/
+    NSMutableDictionary *jsonDic = [[NSMutableDictionary alloc] initWithCapacity:10];
+    /*授权参数*/
+    [jsonDic setValue:@"157775873600002d" forKey:@"appKey"];
+    [jsonDic setValue:@"a6c766845f9a83974aed16f103e60621" forKey:@"secretKey"];
+    [jsonDic setValue:provision forKey:@"provision"];
+    /*日志传参*/
+    NSMutableDictionary *logDic = [[NSMutableDictionary alloc] init];
+    NSString *logFileName = @"log.txt";
+    [logDic setValue:[NSNumber numberWithInt:0] forKey:@"enable"];
+    [logDic setValue:logFileName forKey:@"output"];
+    /*服务链接参数*/
+    NSMutableDictionary *cloudDic = [[NSMutableDictionary alloc] init];
+    NSString *serverPath = @"wss://cloud.chivox.com:443";
+    [cloudDic setValue:[NSNumber numberWithInt:1] forKey:@"enable"];
+    [cloudDic setValue:serverPath forKey:@"server"];
+    [cloudDic setValue:[NSNumber numberWithInt:60] forKey:@"serverTimeout"];
+    /*初始化传参设置*/
+    [jsonDic setValue:logDic forKey:@"prof"];
+    [jsonDic setValue:cloudDic forKey:@"cloud"];
+    NSString *jsonString;
+    jsonString = [self dicToString:jsonDic];
+    /*cfg赋值:string转char*/
+    strcpy(cfg, [jsonString UTF8String]);
+    NSLog(@"cfg: %s\n",cfg);
+    /*评分引擎初始化*/
+    _engine = aiengine_new(cfg);
+    NSLog(@"engine: %p\n", _engine);
+    /*引擎启用param传参设置*/
+    NSMutableDictionary *paramDic = [[NSMutableDictionary alloc] initWithCapacity:10];
+    /*在线离线参数配置(cloud/native)*/
+    [paramDic setValue:@"cloud" forKey:@"coreProvideType"];
+    /*音量实时返回参数设置(0关/1开)*/
+    [paramDic setValue:[NSNumber numberWithInt:0] forKey:@"soundIntensityEnable"];
+    /*appUser传参*/
+    NSMutableDictionary *appDic = [[NSMutableDictionary alloc] init];
+    [appDic setValue:user_id forKey:@"userId"];
+    /*audio音频数据传参*/
+    NSMutableDictionary *audioDic = [[NSMutableDictionary alloc] init];
+    [audioDic setValue:@"wav" forKey:@"audioType"];//音频编码格式
+    [audioDic setValue:[NSNumber numberWithInt:16000] forKey:@"sampleRate"];//音频采样率
+    [audioDic setValue:[NSNumber numberWithInt:1] forKey:@"channel"];//单声道设置
+    [audioDic setValue:[NSNumber numberWithInt:2] forKey:@"sampleBytes"];//采样字节数(1-单字节-8位,2-双字节-16位)
+    /*内核request传参*/
+    NSMutableDictionary *requestDic = [[NSMutableDictionary alloc] init];
+    //内核类型设置cn.word.raw/cn.sent.raw/cn.pred.raw
+    [requestDic setValue:@"en.sent.score" forKey:@"coreType"];
+    [requestDic setValue:en forKey:@"refText"];//评测文本
+    [requestDic setValue:[NSNumber numberWithInt:100] forKey:@"rank"];//总分分制
+    [requestDic setValue:[NSNumber numberWithInt:1] forKey:@"attachAudioUrl"];
+    [requestDic setValue:[NSNumber numberWithInt:1] forKey:@"precision"];//段落评分精度设置(0.5/1)
+    
+    [paramDic setValue:appDic forKey:@"app"];
+    [paramDic setValue:audioDic forKey:@"audio"];
+    [paramDic setValue:requestDic forKey:@"request"];
+    
+    NSString *paramString;
+    paramString = [self dicToString:paramDic];
+    /*cfg赋值:string转char*/
+    strcpy(param, [paramString UTF8String]);
+    int rv = 0;
+    rv = aiengine_start(_engine,param,record_id,(aiengine_callback)_aiengine_callback, (__bridge const void *)(self));
+    if (rv) {
+        NSLog(@"aiengine_start() failed: %d\n", rv);
+        return;
+    }
+}
+
+/*字典转为String*/
+- (NSString *)dicToString: (NSMutableDictionary *) jsonDictionary{
+    NSError *error;
+    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:&error];
+    NSString *jsString;
+    if (!jsonData) {
+        NSLog(@"sorry you get an error:%@",error);
+    } else {
+        jsString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
+    }
+    NSLog(@"引擎初始化传参#####:%@",jsString);
+    return jsString;
+}
+
+
 - (void) configEvaluator {
 - (void) configEvaluator {
     [self.iFlySpeechEvaluator setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
     [self.iFlySpeechEvaluator setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
     [self.iFlySpeechEvaluator setParameter:@"read_sentence" forKey:[IFlySpeechConstant ISE_CATEGORY]];
     [self.iFlySpeechEvaluator setParameter:@"read_sentence" forKey:[IFlySpeechConstant ISE_CATEGORY]];
@@ -63,35 +179,99 @@
     [self.iFlySpeechEvaluator setParameter:@"-1" forKey:@"audio_source"];
     [self.iFlySpeechEvaluator setParameter:@"-1" forKey:@"audio_source"];
 }
 }
 
 
-- (void) evaluateVoice: (NSNumber*)index andPath:(NSString*)path andText:(NSString*)text andIsVideo:(BOOL) isVideo
+- (void) evaluateVoice: (NSNumber*)index andPath:(NSString*)path andText:(NSString*)text andIsVideo:(BOOL) isVideo pathEvaluatorDecode:(NSString*)pathEvaluatorDecode videoId:(NSString*)videoId evaluatorType:(NSNumber*)evaluatorType sdkType:(NSNumber*)sdkType
 {
 {
     self.index = index;
     self.index = index;
-    if(isVideo) {
-        [Mp4ToPcmHelper Mp4ToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path] completion:^(NSData *data) {
-            if(data == nil) {
+    if (sdkType.intValue == 0) {
+        //调用讯飞解析
+        if(isVideo) {
+            [Mp4ToPcmHelper Mp4ToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path] completion:^(NSData *data) {
+                if(data == nil) {
+                    [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
+                    return;
+                }
+                NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
+                NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
+                [self.iFlySpeechEvaluator startListening:buffer params:nil];
+                [self.iFlySpeechEvaluator writeAudio:data];
+                [self.iFlySpeechEvaluator stopListening];
+            }];
+        } else {
+            NSData *voiceData = [M4aToPcmHelper M4aToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path]];
+            if(voiceData == nil) {
                 [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
                 [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
                 return;
                 return;
             }
             }
             NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
             NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
             NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
             NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
             [self.iFlySpeechEvaluator startListening:buffer params:nil];
             [self.iFlySpeechEvaluator startListening:buffer params:nil];
-            [self.iFlySpeechEvaluator writeAudio:data];
+            [self.iFlySpeechEvaluator writeAudio:voiceData];
             [self.iFlySpeechEvaluator stopListening];
             [self.iFlySpeechEvaluator stopListening];
-        }];
-    } else {
-        NSData *voiceData = [M4aToPcmHelper M4aToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path]];
-        if(voiceData == nil) {
-            [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
-            return;
         }
         }
-        NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
-        NSMutableData *buffer= [NSMutableData dataWithData:[text dataUsingEncoding:encoding]];
-        [self.iFlySpeechEvaluator startListening:buffer params:nil];
-        [self.iFlySpeechEvaluator writeAudio:voiceData];
-        [self.iFlySpeechEvaluator stopListening];
+    }else if(sdkType.intValue == 1){
+        //调用池声解析
+        [self chivosInit:text];
+        
+        if(isVideo){
+            
+        }else {
+            int   bytes = 0;
+            char  buf[1024]={0};
+            FILE *file = NULL;
+            const char * audiopath = [path UTF8String];
+            file = fopen(audiopath, "rb");//待评分音频地址
+            if(!file)
+            {
+                printf("read file error!\n");
+                return;
+            }
+            //            NSData *voiceData = [M4aToPcmHelper M4aToPcmWithUrl:[[NSURL alloc] initFileURLWithPath:path]];
+            //            NSUInteger len = [voiceData length];
+            //            Byte *bytedata = (Byte*)malloc(len);
+            //            memcpy(bytedata, [voiceData bytes], len);
+            //
+            //            aiengine_feed(_engine, bytedata, len);
+            
+            //            fseek(file, 44, SEEK_SET); //wav音频文件需要跳过头文件信息,其它音频格式不需要
+            printf("startFeed\n");
+            while ((bytes = (int)fread(buf, 1, 1024, file)))
+            {
+                aiengine_feed(_engine, buf, bytes);
+            }
+            aiengine_stop(_engine);
+            
+        }
+    }else {
+        //调用腾讯解析
+        TAIOralEvaluationParam *param =[[TAIOralEvaluationParam alloc]init];
+        param.sessionId = [[NSUUID UUID]UUIDString];
+        param.appId =@"1301049120";
+        param.workMode = TAIOralEvaluationWorkMode_Once;
+        param.evalMode = TAIOralEvaluationEvalMode_Sentence;
+        param.storageMode = TAIOralEvaluationStorageMode_Disable;
+        param.serverType = TAIOralEvaluationServerType_English;
+        param.scoreCoeff = 1.0;
+        param.fileType = TAIOralEvaluationFileType_Wav;
+        param.refText = text;
+        param.secretId = @"AKIDUf0EEzc8NMpPmu4Po1zhXBZicKp5G7xZ";
+        param.secretKey = @"WnsjKaqtgDVbV9cMtABwVptarwpWyBAt";
+        TAIOralEvaluationData *data = [[TAIOralEvaluationData alloc] init];
+        data.seqId = 1;
+        data.bEnd = YES;
+        data.audio = [NSData dataWithContentsOfFile:path];
+        [self.oralEvaluation oralEvaluation:param data:data callback:^(TAIError *error) {
+            //接口调用结果返回
+            if(error){
+                NSLog(@"调用腾讯失败:code:%ld , msg:%@",(long)error.code ,error.desc);
+            }else{
+                NSLog(@"调用腾讯成功");
+            }
+        }];
+        
     }
     }
 }
 }
 
 
+
 #pragma mark - iFly delegate
 #pragma mark - iFly delegate
 
 
 // 评测结果回调
 // 评测结果回调
@@ -154,4 +334,96 @@
     }
     }
 }
 }
 
 
+#pragma mark - chisheng回掉
+
+/*评分引擎回调方法*/
+int _aiengine_callback(const void *usrdata, const char *id, int type, const void *message, int size)
+{
+    if (type == AIENGINE_MESSAGE_TYPE_JSON) {
+        [(__bridge SpeechPlugin *)usrdata performSelectorOnMainThread:@selector(onChiResult:) withObject:[[NSString alloc] initWithUTF8String:(char *)message] waitUntilDone:NO];
+    }
+    
+    return 0;
+}
+//返回的内容
+-(void) onChiResult:(NSString *) result{
+    if(result == nil){
+        [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
+        return;
+    }
+    NSLog(@"返回的结果:%@",result);
+    NSData *jsonData = [result dataUsingEncoding:NSUTF8StringEncoding];
+    NSError *err = nil;
+    NSMutableDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
+    if(err) {
+        NSLog(@"json解析失败:%@",err);
+        [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
+        return ;
+    }
+    NSNumber *score = dic[@"result"][@"overall"];
+    NSNumber *integrity = dic[@"result"][@"integrity"];
+    NSNumber *accuracy = dic[@"result"][@"accuracy"];
+    NSNumber *fluency = dic[@"result"][@"fluency"][@"overall"];
+    NSArray<NSDictionary *>* worksList = dic[@"result"][@"details"];
+    
+    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+    [dict setValue:self.index forKey:@"index"];
+    [dict setValue:@(score.doubleValue/20) forKey:@"score"];
+    [dict setValue:@(accuracy.doubleValue/20) forKey:@"accuracy_score"];
+    [dict setValue:@(fluency.doubleValue/20) forKey:@"fluency_score"];
+    [dict setValue:@(integrity.doubleValue/20) forKey:@"integrity_score"];
+    [dict setValue:worksList forKey:@"words"];
+    [_channel invokeMethod:@"evaluatorResult" arguments: dict];
+    if (_engine) {
+        aiengine_delete(_engine);
+        _engine = NULL;
+    }
+}
+
+#pragma mark - 腾讯会掉
+
+- (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation onEvaluateData:(TAIOralEvaluationData *)data result:(TAIOralEvaluationRet *)result error:(TAIError *)error {
+    //数据和结果回调(只有data.bEnd为YES,result有效)
+    if (data.bEnd) {
+        float pronFluency = result.pronFluency *5;
+        float pronAccuracy = result.pronAccuracy;
+        if(pronAccuracy == -1){
+            pronAccuracy = 0;
+        }else {
+            pronAccuracy = pronAccuracy/20;
+        }
+        float pronCompletion = result.pronCompletion * 5;
+        
+        float totalScore = (pronFluency + pronAccuracy + pronCompletion)/ 3;
+        
+        NSMutableArray* workList =[NSMutableArray array];
+        
+        for (TAIOralEvaluationWord* work in result.words) {
+            NSMutableDictionary *dic =[NSMutableDictionary dictionary];
+            float score = work.pronAccuracy;
+            if(score == -1.0){
+                score = 0;
+                
+            }else{
+                score = score/20;
+                
+            }
+            dic[@"score"]= [NSNumber numberWithFloat:score];
+            dic[@"content"] = work.word;
+            [workList addObject:dic];
+        }
+        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+        [dict setValue:self.index forKey:@"index"];
+        [dict setValue:@(totalScore) forKey:@"score"];
+        [dict setValue:@(pronAccuracy) forKey:@"accuracy_score"];
+        [dict setValue:@(pronFluency) forKey:@"fluency_score"];
+        [dict setValue:@(pronCompletion) forKey:@"integrity_score"];
+        [dict setValue:workList forKey:@"words"];
+        [_channel invokeMethod:@"evaluatorResult" arguments: dict];
+    }else{
+        [_channel invokeMethod:@"evaluatorResult" arguments: [NSDictionary dictionaryWithObjectsAndKeys: self.index, @"index", [NSNull null], @"score", nil]];
+    }
+}
+
+
 @end
 @end

+ 48 - 0
ios/Frameworks/TAISDK.framework/Headers/TAICommonParam.h

@@ -0,0 +1,48 @@
+//
+//  TAICommonParam.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/12/25.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface TAICommonParam : NSObject
+/**
+ * 账号应用id
+ */
+@property (nonatomic, strong) NSString *appId;
+/**
+ * 超时时间(默认30秒)
+ */
+@property (nonatomic, assign) NSInteger timeout;
+/**
+ * 重试次数(默认0次)
+ */
+@property (nonatomic, assign) NSInteger retryTimes;
+/**
+ * secretId
+ */
+@property (nonatomic, strong) NSString *secretId;
+/**
+ * secretKey
+ * @brief 使用内部签名,此处必填
+ */
+@property (nonatomic, strong) NSString *secretKey;
+/**
+ * token
+ * @brief 临时secretKey方案此处必填
+ */
+@property (nonatomic, strong) NSString *token;
+/**
+ * 时间戳
+ * @brief 使用外部签名,此处必填
+ */
+@property (nonatomic, assign) NSInteger timestamp;
+/**
+ * 签名
+ * @brief 使用外部签名,此处必填(https://cloud.tencent.com/document/product/1004/30611 第三步)
+ */
+@property (nonatomic, strong) NSString *signature;
+@end

+ 40 - 0
ios/Frameworks/TAISDK.framework/Headers/TAIError.h

@@ -0,0 +1,40 @@
+//
+//  TAIError.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/12/4.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSInteger, TAIErrCode)
+{
+    /*
+     成功
+     */
+    TAIErrCode_Succ   =   0,
+    /*
+     参数错误
+     */
+    TAIErrCode_Param,
+    /*
+     json解析错误
+     */
+    TAIErrCode_Json,
+    /*
+     http请求错误
+     */
+    TAIErrCode_Https,
+    /*
+     服务器错误
+     */
+    TAIErrCode_Server,
+};
+
+@interface TAIError : NSObject
+@property (nonatomic, assign) TAIErrCode code;
+@property (nonatomic, strong) NSString *desc;
+@property (nonatomic, strong) NSString *requestId;
++ (id)errorCode:(NSInteger)code desc:(NSString *)desc requestId:(NSString *)requestId;
+@end

+ 16 - 0
ios/Frameworks/TAISDK.framework/Headers/TAIManager.h

@@ -0,0 +1,16 @@
+//
+//  TAIManager.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/11/27.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface TAIManager : NSObject
+/*
+ 获取版本号
+ */
++ (NSString *)getVersion;
+@end

+ 63 - 0
ios/Frameworks/TAISDK.framework/Headers/TAIMathCorrection.h

@@ -0,0 +1,63 @@
+//
+//  TAIMathCorrection.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/12/25.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import "TAICommonParam.h"
+#import "TAIError.h"
+
+
+@interface TAIMathCorrectionItem : NSObject
+//计算结果
+@property (nonatomic, assign) BOOL result;
+//算式位置
+@property (nonatomic, assign) CGRect rect;
+//算式字符串
+@property (nonatomic, strong) NSString *formula;
+//推荐答案
+@property (nonatomic, strong) NSString *answer;
+@end
+
+
+@interface TAIMathCorrectionRet : NSObject
+//sessionId
+@property (nonatomic, strong) NSString *sessionId;
+//items
+@property (nonatomic, strong) NSArray<TAIMathCorrectionItem *> *items;
+@end
+
+
+
+@interface TAIMathCorrectionParam : TAICommonParam
+//业务应用id(默认为default)
+@property (nonatomic, strong) NSString *hcmAppId;
+//sessionId
+@property (nonatomic, strong) NSString *sessionId;
+//图片数据
+@property (nonatomic, strong) NSData *imageData;
+@end
+
+
+
+
+typedef void (^TAIMathCorrectionCallback)(TAIError *error, TAIMathCorrectionRet *result);
+
+@interface TAIMathCorrection : NSObject
+/**
+ * 速算题目批改
+ * @param param 参数
+ * @param callback 回调
+ */
+- (void)mathCorrection:(TAIMathCorrectionParam *)param callback:(TAIMathCorrectionCallback)callback;
+/**
+ * 获取签名所需字符串
+ * @param timestamp 时间戳
+ * @return NSString 签名
+ */
+- (NSString *)getStringToSign:(NSInteger)timestamp;
+@end

+ 273 - 0
ios/Frameworks/TAISDK.framework/Headers/TAIOralEvaluation.h

@@ -0,0 +1,273 @@
+//
+//  TAIOralEvaluation.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/12/25.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "TAICommonParam.h"
+#import "TAIError.h"
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationWorkMode)
+{
+    //流式传输
+    TAIOralEvaluationWorkMode_Stream = 0,
+    //一次性传输
+    TAIOralEvaluationWorkMode_Once = 1,
+};
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationTextMode)
+{
+    //普通文本
+    TAIOralEvaluationTextMode_Noraml = 0,
+    //音素结构文本
+    TAIOralEvaluationTextMode_Phoneme = 1,
+    //音素注册模式
+    TAIOralEvaluationTextMode_Phoneme_Register = 2,
+};
+
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationEvalMode)
+{
+    //单词模式
+    TAIOralEvaluationEvalMode_Word = 0,
+    //句子模式
+    TAIOralEvaluationEvalMode_Sentence = 1,
+    //段落模式
+    TAIOralEvaluationEvalMode_Paragraph = 2,
+    //自由模式
+    TAIOralEvaluationEvalMode_Free = 3,
+    //单词纠错模式
+    TAIOralEvaluationEvalMode_Word_Fix = 4,
+};
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationFileType)
+{
+    //pcm
+    TAIOralEvaluationFileType_Raw = 1,
+    //wav
+    TAIOralEvaluationFileType_Wav = 2,
+    //mp3
+    TAIOralEvaluationFileType_Mp3 = 3,
+};
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationStorageMode)
+{
+    //关闭存储
+    TAIOralEvaluationStorageMode_Disable = 0,
+    //开启存储
+    TAIOralEvaluationStorageMode_Enable = 1,
+    //永久存储(请提工单备案)
+    TAIOralEvaluationStorageMode_Permanent = 2,
+    //自定义存储(请提工单备案)
+    TAIOralEvaluationStorageMode_Custom = 3,
+};
+
+typedef NS_ENUM(NSInteger, TAIOralEvaluationServerType)
+{
+    //英文
+    TAIOralEvaluationServerType_English = 0,
+    //中文
+    TAIOralEvaluationServerType_Chinese = 1,
+};
+
+@interface TAIOralEvaluationParam : TAICommonParam
+//业务应用id(默认为default)
+@property (nonatomic, strong) NSString *soeAppId;
+//唯一标识一次评测
+@property (nonatomic, strong) NSString *sessionId;
+//传输模式
+@property (nonatomic, assign) TAIOralEvaluationWorkMode workMode;
+//评估模式
+@property (nonatomic, assign) TAIOralEvaluationEvalMode evalMode;
+//数据类型(内部录制仅支持mp3)
+@property (nonatomic, assign) TAIOralEvaluationFileType fileType;
+//音频存储
+@property (nonatomic, assign) TAIOralEvaluationStorageMode storageMode;
+//语言类型
+@property (nonatomic, assign) TAIOralEvaluationServerType serverType;
+//文本模式
+@property (nonatomic, assign) TAIOralEvaluationTextMode textMode;
+//苛刻指数[1.0-4.0]
+@property (nonatomic, assign) float scoreCoeff;
+//被评估的文本
+@property (nonatomic, strong) NSString *refText;
+//输出断句中间结果
+@property (nonatomic, assign) BOOL sentenceInfoEnabled;
+@end
+
+
+@interface TAIOralEvaluationPhoneInfo : NSObject
+//当前音节语音起始时间点,单位为ms
+@property (nonatomic, assign) int beginTime;
+//当前音节语音终止时间点,单位为ms
+@property (nonatomic, assign) int endTime;
+//音节发音准确度,取值范围[-1, 100],当取-1时指完全不匹配
+@property (nonatomic, assign) float pronAccuracy;
+//当前音节是否检测为重音
+@property (nonatomic, assign) BOOL detectedStress;
+//当前音节
+@property (nonatomic, strong) NSString *phone;
+//当前音节是否应为重音
+@property (nonatomic, assign) BOOL stress;
+//参考音素,在单词诊断模式下,代表标准音素
+@property (nonatomic, strong) NSString *referencePhone;
+@end
+
+
+
+@interface TAIOralEvaluationWord : NSObject
+//当前单词语音起始时间点,单位为ms
+@property (nonatomic, assign) int beginTime;
+//当前单词语音终止时间点,单位为ms
+@property (nonatomic, assign) int endTime;
+//单词发音准确度,取值范围[-1, 100],当取-1时指完全不匹配
+@property (nonatomic, assign) float pronAccuracy;
+//单词发音流利度,取值范围[0, 1]
+@property (nonatomic, assign) float pronFluency;
+//当前词
+@property (nonatomic, strong) NSString *word;
+//当前词与输入语句的匹配情况,0:匹配单词、1:新增单词、2:缺少单词
+@property (nonatomic, assign) int matchTag;
+//音节评估详情
+@property (nonatomic, strong) NSArray<TAIOralEvaluationPhoneInfo *> *phoneInfos;
+//参考词
+@property (nonatomic, strong) NSString *referenceWord;
+@end
+
+
+@interface TAIOralEvaluationSentenceInfo : NSObject
+//句子序号,在段落、自由说模式下有效,表示断句序号,最后的综合结果的为-1.
+@property (nonatomic, assign) int sentenceId;
+//详细发音评估结果
+@property (nonatomic, strong) NSArray<TAIOralEvaluationWord *> *words;
+//发音精准度,取值范围[-1, 100],当取-1时指完全不匹配,当为句子模式时,是所有已识别单词准确度的加权平均值,在reftext中但未识别出来的词不计入分数中
+@property (nonatomic, assign) float pronAccuracy;
+//发音流利度,取值范围[0, 1],当为词模式时,取值无意义;当为流式模式且请求中IsEnd未置1时,取值无意义
+@property (nonatomic, assign) float pronFluency;
+//发音完整度,取值范围[0, 1],当为词模式时,取值无意义;当为流式模式且请求中IsEnd未置1时,取值无意义
+@property (nonatomic, assign) float pronCompletion;
+//建议评分,取值范围[0,100],评分方式为建议评分 = 准确度(pronAccuracyfloat) 完整度(pronCompletionfloat)(2 - 完整度(pronCompletionfloat)),如若评分策略不符合请参考Words数组中的详细分数自定义评分逻辑
+@property (nonatomic, assign) float suggestedScore;
+@end
+
+
+@interface TAIOralEvaluationRet : NSObject
+//唯一标识一次评测
+@property (nonatomic, strong) NSString *sessionId;
+//单词发音准确度,取值范围[-1, 100],当取-1时指完全不匹配
+@property (nonatomic, assign) float pronAccuracy;
+//单词发音流利度,取值范围[0, 1]
+@property (nonatomic, assign) float pronFluency;
+//发音完整度,取值范围[0, 1],当为词模式时,取值无意义
+@property (nonatomic, assign) float pronCompletion;
+//保存语音音频文件的下载地址(TAIOralEvaluationStorageMode_Enable有效)
+@property (nonatomic, strong) NSString *audioUrl;
+//详细发音评估结果
+@property (nonatomic, strong) NSArray<TAIOralEvaluationWord *> *words;
+//建议评分,取值范围[0,100]
+//评分方式为建议评分 = 准确度(PronAccuracyfloat)× 完整度(PronCompletionfloat)×(2 - 完整度(PronCompletionfloat))
+//如若评分策略不符合请参考Words数组中的详细分数自定义评分逻辑。
+@property (nonatomic, assign) float suggestedScore;
+//断句中间结果
+@property (nonatomic, strong) NSArray<TAIOralEvaluationSentenceInfo*> *sentenceInfoSet;
+@end
+
+@interface TAIOralEvaluationData : NSObject
+//数据seq,从1开始
+@property (nonatomic, assign) NSInteger seqId;
+//属否是最后分片数据
+@property (nonatomic, assign) BOOL bEnd;
+//音频数据
+@property (nonatomic, strong) NSData *audio;
+@end
+
+@interface TAIRecorderParam : NSObject
+//是否开启分片,默认YES
+@property (nonatomic, assign) BOOL fragEnable;
+//分片大小,默认1024,建议为1024的整数倍,范围【1k-10k】
+@property (nonatomic, assign) NSInteger fragSize;
+//是否开启静音检测,默认NO
+@property (nonatomic, assign) BOOL vadEnable;
+//静音检测时间间隔,单位【ms】
+@property (nonatomic, assign) NSInteger vadInterval;
+@end
+
+@class TAIOralEvaluation;
+@protocol TAIOralEvaluationDelegate <NSObject>
+/**
+ * 评估结果回调
+ * @param oralEvaluation 评测对象
+ * @param data 音频数据
+ * @param result 评估结果(最后一个分片返回,其他分片为nil)
+ * @param error 错误信息
+ */
+- (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation
+        onEvaluateData:(TAIOralEvaluationData *)data
+                result:(TAIOralEvaluationRet *)result
+                 error:(TAIError *)error;
+/**
+ * 静音检测回调
+ * @param oralEvaluation 评测对象
+ * @brief 检测到静音内部不会停止录制,业务层可以根据此回调主动停止录制或提示用户
+ */
+- (void)onEndOfSpeechInOralEvaluation:(TAIOralEvaluation *)oralEvaluation;
+/**
+ * 音量分贝变化
+ * @param oralEvaluation 评测对象
+ * @param volume 分贝大小
+ * @brief volume范围【0-120】
+ */
+- (void)oralEvaluation:(TAIOralEvaluation *)oralEvaluation onVolumeChanged:(NSInteger)volume;
+@end
+
+typedef void (^TAIOralEvaluationCallback)(TAIError *error);
+
+@interface TAIOralEvaluation : NSObject
+/**
+ * 录制数据回调
+ */
+@property (nonatomic, weak) id<TAIOralEvaluationDelegate> delegate;
+/**
+ * 开始录制和评测
+ * @param param 参数(内部录制仅支持mp3)
+ * @param callback 回调
+ */
+- (void)startRecordAndEvaluation:(TAIOralEvaluationParam *)param callback:(TAIOralEvaluationCallback)callback;
+/**
+ * 结束录制和评测
+ * @param callback 回调
+ */
+- (void)stopRecordAndEvaluation:(TAIOralEvaluationCallback)callback;
+/**
+ * 属否正在录制
+ * @return BOOL 是否录制
+ */
+- (BOOL)isRecording;
+/**
+ * 设置分片大小,建议为1024的整数倍,范围【1k-10k】,默认为1024*1
+ * @param size 分片大小
+ */
+- (void)setFragSize:(NSInteger)size DEPRECATED_MSG_ATTRIBUTE("Please usee setRecordParam:");
+
+/**
+ * 设置录制参数
+ * @param param 录制参数
+ */
+- (void)setRecorderParam:(TAIRecorderParam *)param;
+/**
+ * 口语评测(外部录制)
+ * @param param 参数
+ * @param data 音频数据(三种格式目前仅支持16k采样率16bit编码单声道,如有不一致可能导致评估不准确或失败)
+ * @param callback 回调
+ */
+- (void)oralEvaluation:(TAIOralEvaluationParam *)param data:(TAIOralEvaluationData *)data callback:(TAIOralEvaluationCallback)callback;
+/**
+ * 获取签名所需字符串
+ * @param timestamp 时间戳
+ * @return NSString 签名
+ */
+- (NSString *)getStringToSign:(NSInteger)timestamp;
+@end

BIN
ios/Frameworks/TAISDK.framework/Info.plist


+ 6 - 0
ios/Frameworks/TAISDK.framework/Modules/module.modulemap

@@ -0,0 +1,6 @@
+framework module TAISDK {
+  umbrella header "TAISDK.h"
+
+  export *
+  module * { export * }
+}

+ 10 - 0
ios/Frameworks/TAISDK.framework/PrivateHeaders/TAISDK.h

@@ -0,0 +1,10 @@
+//
+//  TAISDK.h
+//  TAISDK
+//
+//  Created by kennethmiao on 2018/11/27.
+//  Copyright © 2018年 kennethmiao. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+

BIN
ios/Frameworks/TAISDK.framework/TAISDK


+ 1323 - 0
ios/Frameworks/lame.framework/Headers/lame.h

@@ -0,0 +1,1323 @@
+/*
+ *	Interface to MP3 LAME encoding engine
+ *
+ *	Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: lame.h,v 1.189.2.1 2012/01/08 23:49:58 robert Exp $ */
+
+#ifndef LAME_LAME_H
+#define LAME_LAME_H
+
+/* for size_t typedef */
+#include <stddef.h>
+/* for va_list typedef */
+#include <stdarg.h>
+/* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */
+#include <stdio.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef void (*lame_report_function)(const char *format, va_list ap);
+
+#if defined(WIN32) || defined(_WIN32)
+#undef CDECL
+#define CDECL __cdecl
+#else
+#define CDECL
+#endif
+
+#define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1
+
+typedef enum vbr_mode_e {
+  vbr_off=0,
+  vbr_mt,               /* obsolete, same as vbr_mtrh */
+  vbr_rh,
+  vbr_abr,
+  vbr_mtrh,
+  vbr_max_indicator,    /* Don't use this! It's used for sanity checks.       */
+  vbr_default=vbr_mtrh    /* change this to change the default VBR mode of LAME */
+} vbr_mode;
+
+
+/* MPEG modes */
+typedef enum MPEG_mode_e {
+  STEREO = 0,
+  JOINT_STEREO,
+  DUAL_CHANNEL,   /* LAME doesn't supports this! */
+  MONO,
+  NOT_SET,
+  MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */
+} MPEG_mode;
+
+/* Padding types */
+typedef enum Padding_type_e {
+  PAD_NO = 0,
+  PAD_ALL,
+  PAD_ADJUST,
+  PAD_MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */
+} Padding_type;
+
+
+
+/*presets*/
+typedef enum preset_mode_e {
+    /*values from 8 to 320 should be reserved for abr bitrates*/
+    /*for abr I'd suggest to directly use the targeted bitrate as a value*/
+    ABR_8 = 8,
+    ABR_320 = 320,
+
+    V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/
+    VBR_10 = 410,
+    V8 = 420,
+    VBR_20 = 420,
+    V7 = 430,
+    VBR_30 = 430,
+    V6 = 440,
+    VBR_40 = 440,
+    V5 = 450,
+    VBR_50 = 450,
+    V4 = 460,
+    VBR_60 = 460,
+    V3 = 470,
+    VBR_70 = 470,
+    V2 = 480,
+    VBR_80 = 480,
+    V1 = 490,
+    VBR_90 = 490,
+    V0 = 500,
+    VBR_100 = 500,
+
+
+
+    /*still there for compatibility*/
+    R3MIX = 1000,
+    STANDARD = 1001,
+    EXTREME = 1002,
+    INSANE = 1003,
+    STANDARD_FAST = 1004,
+    EXTREME_FAST = 1005,
+    MEDIUM = 1006,
+    MEDIUM_FAST = 1007
+} preset_mode;
+
+
+/*asm optimizations*/
+typedef enum asm_optimizations_e {
+    MMX = 1,
+    AMD_3DNOW = 2,
+    SSE = 3
+} asm_optimizations;
+
+
+/* psychoacoustic model */
+typedef enum Psy_model_e {
+    PSY_GPSYCHO = 1,
+    PSY_NSPSYTUNE = 2
+} Psy_model;
+
+
+/* buffer considerations */
+typedef enum buffer_constraint_e {
+    MDB_DEFAULT=0,
+    MDB_STRICT_ISO=1,
+    MDB_MAXIMUM=2
+} buffer_constraint;
+
+
+struct lame_global_struct;
+typedef struct lame_global_struct lame_global_flags;
+typedef lame_global_flags *lame_t;
+
+
+
+
+/***********************************************************************
+ *
+ *  The LAME API
+ *  These functions should be called, in this order, for each
+ *  MP3 file to be encoded.  See the file "API" for more documentation
+ *
+ ***********************************************************************/
+
+
+/*
+ * REQUIRED:
+ * initialize the encoder.  sets default for all encoder parameters,
+ * returns NULL if some malloc()'s failed
+ * otherwise returns pointer to structure needed for all future
+ * API calls.
+ */
+lame_global_flags * CDECL lame_init(void);
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* obsolete version */
+int CDECL lame_init_old(lame_global_flags *);
+#endif
+
+/*
+ * OPTIONAL:
+ * set as needed to override defaults
+ */
+
+/********************************************************************
+ *  input stream description
+ ***********************************************************************/
+/* number of samples.  default = 2^32-1   */
+int CDECL lame_set_num_samples(lame_global_flags *, unsigned long);
+unsigned long CDECL lame_get_num_samples(const lame_global_flags *);
+
+/* input sample rate in Hz.  default = 44100hz */
+int CDECL lame_set_in_samplerate(lame_global_flags *, int);
+int CDECL lame_get_in_samplerate(const lame_global_flags *);
+
+/* number of channels in input stream. default=2  */
+int CDECL lame_set_num_channels(lame_global_flags *, int);
+int CDECL lame_get_num_channels(const lame_global_flags *);
+
+/*
+  scale the input by this amount before encoding.  default=1
+  (not used by decoding routines)
+*/
+int CDECL lame_set_scale(lame_global_flags *, float);
+float CDECL lame_get_scale(const lame_global_flags *);
+
+/*
+  scale the channel 0 (left) input by this amount before encoding.  default=1
+  (not used by decoding routines)
+*/
+int CDECL lame_set_scale_left(lame_global_flags *, float);
+float CDECL lame_get_scale_left(const lame_global_flags *);
+
+/*
+  scale the channel 1 (right) input by this amount before encoding.  default=1
+  (not used by decoding routines)
+*/
+int CDECL lame_set_scale_right(lame_global_flags *, float);
+float CDECL lame_get_scale_right(const lame_global_flags *);
+
+/*
+  output sample rate in Hz.  default = 0, which means LAME picks best value
+  based on the amount of compression.  MPEG only allows:
+  MPEG1    32, 44.1,   48khz
+  MPEG2    16, 22.05,  24
+  MPEG2.5   8, 11.025, 12
+  (not used by decoding routines)
+*/
+int CDECL lame_set_out_samplerate(lame_global_flags *, int);
+int CDECL lame_get_out_samplerate(const lame_global_flags *);
+
+
+/********************************************************************
+ *  general control parameters
+ ***********************************************************************/
+/* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */
+int CDECL lame_set_analysis(lame_global_flags *, int);
+int CDECL lame_get_analysis(const lame_global_flags *);
+
+/*
+  1 = write a Xing VBR header frame.
+  default = 1
+  this variable must have been added by a Hungarian notation Windows programmer :-)
+*/
+int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int);
+int CDECL lame_get_bWriteVbrTag(const lame_global_flags *);
+
+/* 1=decode only.  use lame/mpglib to convert mp3/ogg to wav.  default=0 */
+int CDECL lame_set_decode_only(lame_global_flags *, int);
+int CDECL lame_get_decode_only(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* 1=encode a Vorbis .ogg file.  default=0 */
+/* DEPRECATED */
+int CDECL lame_set_ogg(lame_global_flags *, int);
+int CDECL lame_get_ogg(const lame_global_flags *);
+#endif
+
+/*
+  internal algorithm selection.  True quality is determined by the bitrate
+  but this variable will effect quality by selecting expensive or cheap algorithms.
+  quality=0..9.  0=best (very slow).  9=worst.
+  recommended:  2     near-best quality, not too slow
+                5     good quality, fast
+                7     ok quality, really fast
+*/
+int CDECL lame_set_quality(lame_global_flags *, int);
+int CDECL lame_get_quality(const lame_global_flags *);
+
+/*
+  mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono
+  default: lame picks based on compression ration and input channels
+*/
+int CDECL lame_set_mode(lame_global_flags *, MPEG_mode);
+MPEG_mode CDECL lame_get_mode(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/*
+  mode_automs.  Use a M/S mode with a switching threshold based on
+  compression ratio
+  DEPRECATED
+*/
+int CDECL lame_set_mode_automs(lame_global_flags *, int);
+int CDECL lame_get_mode_automs(const lame_global_flags *);
+#endif
+
+/*
+  force_ms.  Force M/S for all frames.  For testing only.
+  default = 0 (disabled)
+*/
+int CDECL lame_set_force_ms(lame_global_flags *, int);
+int CDECL lame_get_force_ms(const lame_global_flags *);
+
+/* use free_format?  default = 0 (disabled) */
+int CDECL lame_set_free_format(lame_global_flags *, int);
+int CDECL lame_get_free_format(const lame_global_flags *);
+
+/* perform ReplayGain analysis?  default = 0 (disabled) */
+int CDECL lame_set_findReplayGain(lame_global_flags *, int);
+int CDECL lame_get_findReplayGain(const lame_global_flags *);
+
+/* decode on the fly. Search for the peak sample. If the ReplayGain
+ * analysis is enabled then perform the analysis on the decoded data
+ * stream. default = 0 (disabled)
+ * NOTE: if this option is set the build-in decoder should not be used */
+int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int);
+int CDECL lame_get_decode_on_the_fly(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* DEPRECATED: now does the same as lame_set_findReplayGain()
+   default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_input(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_input(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as
+   lame_set_decode_on_the_fly() && lame_set_findReplayGain()
+   default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_decode(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()
+   default = 0 (disabled) */
+int CDECL lame_set_findPeakSample(lame_global_flags *, int);
+int CDECL lame_get_findPeakSample(const lame_global_flags *);
+#endif
+
+/* counters for gapless encoding */
+int CDECL lame_set_nogap_total(lame_global_flags*, int);
+int CDECL lame_get_nogap_total(const lame_global_flags*);
+
+int CDECL lame_set_nogap_currentindex(lame_global_flags* , int);
+int CDECL lame_get_nogap_currentindex(const lame_global_flags*);
+
+
+/*
+ * OPTIONAL:
+ * Set printf like error/debug/message reporting functions.
+ * The second argument has to be a pointer to a function which looks like
+ *   void my_debugf(const char *format, va_list ap)
+ *   {
+ *       (void) vfprintf(stdout, format, ap);
+ *   }
+ * If you use NULL as the value of the pointer in the set function, the
+ * lame buildin function will be used (prints to stderr).
+ * To quiet any output you have to replace the body of the example function
+ * with just "return;" and use it in the set function.
+ */
+int CDECL lame_set_errorf(lame_global_flags *, lame_report_function);
+int CDECL lame_set_debugf(lame_global_flags *, lame_report_function);
+int CDECL lame_set_msgf  (lame_global_flags *, lame_report_function);
+
+
+
+/* set one of brate compression ratio.  default is compression ratio of 11.  */
+int CDECL lame_set_brate(lame_global_flags *, int);
+int CDECL lame_get_brate(const lame_global_flags *);
+int CDECL lame_set_compression_ratio(lame_global_flags *, float);
+float CDECL lame_get_compression_ratio(const lame_global_flags *);
+
+
+int CDECL lame_set_preset( lame_global_flags*  gfp, int );
+int CDECL lame_set_asm_optimizations( lame_global_flags*  gfp, int, int );
+
+
+
+/********************************************************************
+ *  frame params
+ ***********************************************************************/
+/* mark as copyright.  default=0 */
+int CDECL lame_set_copyright(lame_global_flags *, int);
+int CDECL lame_get_copyright(const lame_global_flags *);
+
+/* mark as original.  default=1 */
+int CDECL lame_set_original(lame_global_flags *, int);
+int CDECL lame_get_original(const lame_global_flags *);
+
+/* error_protection.  Use 2 bytes from each frame for CRC checksum. default=0 */
+int CDECL lame_set_error_protection(lame_global_flags *, int);
+int CDECL lame_get_error_protection(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* padding_type. 0=pad no frames  1=pad all frames 2=adjust padding(default) */
+int CDECL lame_set_padding_type(lame_global_flags *, Padding_type);
+Padding_type CDECL lame_get_padding_type(const lame_global_flags *);
+#endif
+
+/* MP3 'private extension' bit  Meaningless.  default=0 */
+int CDECL lame_set_extension(lame_global_flags *, int);
+int CDECL lame_get_extension(const lame_global_flags *);
+
+/* enforce strict ISO compliance.  default=0 */
+int CDECL lame_set_strict_ISO(lame_global_flags *, int);
+int CDECL lame_get_strict_ISO(const lame_global_flags *);
+
+
+/********************************************************************
+ * quantization/noise shaping
+ ***********************************************************************/
+
+/* disable the bit reservoir. For testing only. default=0 */
+int CDECL lame_set_disable_reservoir(lame_global_flags *, int);
+int CDECL lame_get_disable_reservoir(const lame_global_flags *);
+
+/* select a different "best quantization" function. default=0  */
+int CDECL lame_set_quant_comp(lame_global_flags *, int);
+int CDECL lame_get_quant_comp(const lame_global_flags *);
+int CDECL lame_set_quant_comp_short(lame_global_flags *, int);
+int CDECL lame_get_quant_comp_short(const lame_global_flags *);
+
+int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/
+int CDECL lame_get_experimentalX(const lame_global_flags *);
+
+/* another experimental option.  for testing only */
+int CDECL lame_set_experimentalY(lame_global_flags *, int);
+int CDECL lame_get_experimentalY(const lame_global_flags *);
+
+/* another experimental option.  for testing only */
+int CDECL lame_set_experimentalZ(lame_global_flags *, int);
+int CDECL lame_get_experimentalZ(const lame_global_flags *);
+
+/* Naoki's psycho acoustic model.  default=0 */
+int CDECL lame_set_exp_nspsytune(lame_global_flags *, int);
+int CDECL lame_get_exp_nspsytune(const lame_global_flags *);
+
+void CDECL lame_set_msfix(lame_global_flags *, double);
+float CDECL lame_get_msfix(const lame_global_flags *);
+
+
+/********************************************************************
+ * VBR control
+ ***********************************************************************/
+/* Types of VBR.  default = vbr_off = CBR */
+int CDECL lame_set_VBR(lame_global_flags *, vbr_mode);
+vbr_mode CDECL lame_get_VBR(const lame_global_flags *);
+
+/* VBR quality level.  0=highest  9=lowest  */
+int CDECL lame_set_VBR_q(lame_global_flags *, int);
+int CDECL lame_get_VBR_q(const lame_global_flags *);
+
+/* VBR quality level.  0=highest  9=lowest, Range [0,...,10[  */
+int CDECL lame_set_VBR_quality(lame_global_flags *, float);
+float CDECL lame_get_VBR_quality(const lame_global_flags *);
+
+/* Ignored except for VBR=vbr_abr (ABR mode) */
+int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *);
+
+/*
+  1=strictly enforce VBR_min_bitrate.  Normally it will be violated for
+  analog silence
+*/
+int CDECL lame_set_VBR_hard_min(lame_global_flags *, int);
+int CDECL lame_get_VBR_hard_min(const lame_global_flags *);
+
+/* for preset */
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+int CDECL lame_set_preset_expopts(lame_global_flags *, int);
+#endif
+
+/********************************************************************
+ * Filtering control
+ ***********************************************************************/
+/* freq in Hz to apply lowpass. Default = 0 = lame chooses.  -1 = disabled */
+int CDECL lame_set_lowpassfreq(lame_global_flags *, int);
+int CDECL lame_get_lowpassfreq(const lame_global_flags *);
+/* width of transition band, in Hz.  Default = one polyphase filter band */
+int CDECL lame_set_lowpasswidth(lame_global_flags *, int);
+int CDECL lame_get_lowpasswidth(const lame_global_flags *);
+
+/* freq in Hz to apply highpass. Default = 0 = lame chooses.  -1 = disabled */
+int CDECL lame_set_highpassfreq(lame_global_flags *, int);
+int CDECL lame_get_highpassfreq(const lame_global_flags *);
+/* width of transition band, in Hz.  Default = one polyphase filter band */
+int CDECL lame_set_highpasswidth(lame_global_flags *, int);
+int CDECL lame_get_highpasswidth(const lame_global_flags *);
+
+
+/********************************************************************
+ * psycho acoustics and other arguments which you should not change
+ * unless you know what you are doing
+ ***********************************************************************/
+
+/* only use ATH for masking */
+int CDECL lame_set_ATHonly(lame_global_flags *, int);
+int CDECL lame_get_ATHonly(const lame_global_flags *);
+
+/* only use ATH for short blocks */
+int CDECL lame_set_ATHshort(lame_global_flags *, int);
+int CDECL lame_get_ATHshort(const lame_global_flags *);
+
+/* disable ATH */
+int CDECL lame_set_noATH(lame_global_flags *, int);
+int CDECL lame_get_noATH(const lame_global_flags *);
+
+/* select ATH formula */
+int CDECL lame_set_ATHtype(lame_global_flags *, int);
+int CDECL lame_get_ATHtype(const lame_global_flags *);
+
+/* lower ATH by this many db */
+int CDECL lame_set_ATHlower(lame_global_flags *, float);
+float CDECL lame_get_ATHlower(const lame_global_flags *);
+
+/* select ATH adaptive adjustment type */
+int CDECL lame_set_athaa_type( lame_global_flags *, int);
+int CDECL lame_get_athaa_type( const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* select the loudness approximation used by the ATH adaptive auto-leveling  */
+int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int);
+int CDECL lame_get_athaa_loudapprox( const lame_global_flags *);
+#endif
+
+/* adjust (in dB) the point below which adaptive ATH level adjustment occurs */
+int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float);
+float CDECL lame_get_athaa_sensitivity( const lame_global_flags* );
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* OBSOLETE: predictability limit (ISO tonality formula) */
+int CDECL lame_set_cwlimit(lame_global_flags *, int);
+int CDECL lame_get_cwlimit(const lame_global_flags *);
+#endif
+
+/*
+  allow blocktypes to differ between channels?
+  default: 0 for jstereo, 1 for stereo
+*/
+int CDECL lame_set_allow_diff_short(lame_global_flags *, int);
+int CDECL lame_get_allow_diff_short(const lame_global_flags *);
+
+/* use temporal masking effect (default = 1) */
+int CDECL lame_set_useTemporal(lame_global_flags *, int);
+int CDECL lame_get_useTemporal(const lame_global_flags *);
+
+/* use temporal masking effect (default = 1) */
+int CDECL lame_set_interChRatio(lame_global_flags *, float);
+float CDECL lame_get_interChRatio(const lame_global_flags *);
+
+/* disable short blocks */
+int CDECL lame_set_no_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_no_short_blocks(const lame_global_flags *);
+
+/* force short blocks */
+int CDECL lame_set_force_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_force_short_blocks(const lame_global_flags *);
+
+/* Input PCM is emphased PCM (for instance from one of the rarely
+   emphased CDs), it is STRONGLY not recommended to use this, because
+   psycho does not take it into account, and last but not least many decoders
+   ignore these bits */
+int CDECL lame_set_emphasis(lame_global_flags *, int);
+int CDECL lame_get_emphasis(const lame_global_flags *);
+
+
+
+/************************************************************************/
+/* internal variables, cannot be set...                                 */
+/* provided because they may be of use to calling application           */
+/************************************************************************/
+/* version  0=MPEG-2  1=MPEG-1  (2=MPEG-2.5)     */
+int CDECL lame_get_version(const lame_global_flags *);
+
+/* encoder delay   */
+int CDECL lame_get_encoder_delay(const lame_global_flags *);
+
+/*
+  padding appended to the input to make sure decoder can fully decode
+  all input.  Note that this value can only be calculated during the
+  call to lame_encoder_flush().  Before lame_encoder_flush() has
+  been called, the value of encoder_padding = 0.
+*/
+int CDECL lame_get_encoder_padding(const lame_global_flags *);
+
+/* size of MPEG frame */
+int CDECL lame_get_framesize(const lame_global_flags *);
+
+/* number of PCM samples buffered, but not yet encoded to mp3 data. */
+int CDECL lame_get_mf_samples_to_encode( const lame_global_flags*  gfp );
+
+/*
+  size (bytes) of mp3 data buffered, but not yet encoded.
+  this is the number of bytes which would be output by a call to
+  lame_encode_flush_nogap.  NOTE: lame_encode_flush() will return
+  more bytes than this because it will encode the reamining buffered
+  PCM samples before flushing the mp3 buffers.
+*/
+int CDECL lame_get_size_mp3buffer( const lame_global_flags*  gfp );
+
+/* number of frames encoded so far */
+int CDECL lame_get_frameNum(const lame_global_flags *);
+
+/*
+  lame's estimate of the total number of frames to be encoded
+   only valid if calling program set num_samples
+*/
+int CDECL lame_get_totalframes(const lame_global_flags *);
+
+/* RadioGain value. Multiplied by 10 and rounded to the nearest. */
+int CDECL lame_get_RadioGain(const lame_global_flags *);
+
+/* AudiophileGain value. Multipled by 10 and rounded to the nearest. */
+int CDECL lame_get_AudiophileGain(const lame_global_flags *);
+
+/* the peak sample */
+float CDECL lame_get_PeakSample(const lame_global_flags *);
+
+/* Gain change required for preventing clipping. The value is correct only if
+   peak sample searching was enabled. If negative then the waveform
+   already does not clip. The value is multiplied by 10 and rounded up. */
+int CDECL lame_get_noclipGainChange(const lame_global_flags *);
+
+/* user-specified scale factor required for preventing clipping. Value is
+   correct only if peak sample searching was enabled and no user-specified
+   scaling was performed. If negative then either the waveform already does
+   not clip or the value cannot be determined */
+float CDECL lame_get_noclipScale(const lame_global_flags *);
+
+
+
+
+
+
+
+/*
+ * REQUIRED:
+ * sets more internal configuration based on data provided above.
+ * returns -1 if something failed.
+ */
+int CDECL lame_init_params(lame_global_flags *);
+
+
+/*
+ * OPTIONAL:
+ * get the version number, in a string. of the form:
+ * "3.63 (beta)" or just "3.63".
+ */
+const char*  CDECL get_lame_version       ( void );
+const char*  CDECL get_lame_short_version ( void );
+const char*  CDECL get_lame_very_short_version ( void );
+const char*  CDECL get_psy_version        ( void );
+const char*  CDECL get_lame_url           ( void );
+const char*  CDECL get_lame_os_bitness    ( void );
+
+/*
+ * OPTIONAL:
+ * get the version numbers in numerical form.
+ */
+typedef struct {
+    /* generic LAME version */
+    int major;
+    int minor;
+    int alpha;               /* 0 if not an alpha version                  */
+    int beta;                /* 0 if not a beta version                    */
+
+    /* version of the psy model */
+    int psy_major;
+    int psy_minor;
+    int psy_alpha;           /* 0 if not an alpha version                  */
+    int psy_beta;            /* 0 if not a beta version                    */
+
+    /* compile time features */
+    const char *features;    /* Don't make assumptions about the contents! */
+} lame_version_t;
+void CDECL get_lame_version_numerical(lame_version_t *);
+
+
+/*
+ * OPTIONAL:
+ * print internal lame configuration to message handler
+ */
+void CDECL lame_print_config(const lame_global_flags*  gfp);
+
+void CDECL lame_print_internals( const lame_global_flags *gfp);
+
+
+/*
+ * input pcm data, output (maybe) mp3 frames.
+ * This routine handles all buffering, resampling and filtering for you.
+ *
+ * return code     number of bytes output in mp3buf. Can be 0
+ *                 -1:  mp3buf was too small
+ *                 -2:  malloc() problem
+ *                 -3:  lame_init_params() not called
+ *                 -4:  psycho acoustic problems
+ *
+ * The required mp3buf_size can be computed from num_samples,
+ * samplerate and encoding rate, but here is a worst case estimate:
+ *
+ * mp3buf_size in bytes = 1.25*num_samples + 7200
+ *
+ * I think a tighter bound could be:  (mt, March 2000)
+ * MPEG1:
+ *    num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512
+ * MPEG2:
+ *    num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256
+ *
+ * but test first if you use that!
+ *
+ * set mp3buf_size = 0 and LAME will not check if mp3buf_size is
+ * large enough.
+ *
+ * NOTE:
+ * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels
+ * will be averaged into the L channel before encoding only the L channel
+ * This will overwrite the data in buffer_l[] and buffer_r[].
+ *
+*/
+int CDECL lame_encode_buffer (
+        lame_global_flags*  gfp,           /* global context handle         */
+        const short int     buffer_l [],   /* PCM data for left channel     */
+        const short int     buffer_r [],   /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/*
+ * as above, but input has L & R channel data interleaved.
+ * NOTE:
+ * num_samples = number of samples in the L (or R)
+ * channel, not the total number of samples in pcm[]
+ */
+int CDECL lame_encode_buffer_interleaved(
+        lame_global_flags*  gfp,           /* global context handlei        */
+        short int           pcm[],         /* PCM data for left and right
+                                              channel, interleaved          */
+        int                 num_samples,   /* number of samples per channel,
+                                              _not_ number of samples in
+                                              pcm[]                         */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        int                 mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+
+/* as lame_encode_buffer, but for 'float's.
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * short int, +/- 32768
+ */
+int CDECL lame_encode_buffer_float(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const float         pcm_l [],      /* PCM data for left channel     */
+        const float         pcm_r [],      /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/* as lame_encode_buffer, but for 'float's.
+ * !! NOTE: !! data must be scaled to +/- 1 full scale
+ */
+int CDECL lame_encode_buffer_ieee_float(
+        lame_t          gfp,
+        const float     pcm_l [],          /* PCM data for left channel     */
+        const float     pcm_r [],          /* PCM data for right channel    */
+        const int       nsamples,
+        unsigned char * mp3buf,
+        const int       mp3buf_size);
+int CDECL lame_encode_buffer_interleaved_ieee_float(
+        lame_t          gfp,
+        const float     pcm[],             /* PCM data for left and right
+                                              channel, interleaved          */
+        const int       nsamples,
+        unsigned char * mp3buf,
+        const int       mp3buf_size);
+
+/* as lame_encode_buffer, but for 'double's.
+ * !! NOTE: !! data must be scaled to +/- 1 full scale
+ */
+int CDECL lame_encode_buffer_ieee_double(
+        lame_t          gfp,
+        const double    pcm_l [],          /* PCM data for left channel     */
+        const double    pcm_r [],          /* PCM data for right channel    */
+        const int       nsamples,
+        unsigned char * mp3buf,
+        const int       mp3buf_size);
+int CDECL lame_encode_buffer_interleaved_ieee_double(
+        lame_t          gfp,
+        const double    pcm[],             /* PCM data for left and right
+                                              channel, interleaved          */
+        const int       nsamples,
+        unsigned char * mp3buf,
+        const int       mp3buf_size);
+
+/* as lame_encode_buffer, but for long's
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * short int, +/- 32768
+ *
+ * This scaling was a mistake (doesn't allow one to exploit full
+ * precision of type 'long'.  Use lame_encode_buffer_long2() instead.
+ *
+ */
+int CDECL lame_encode_buffer_long(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const long     buffer_l [],       /* PCM data for left channel     */
+        const long     buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/* Same as lame_encode_buffer_long(), but with correct scaling.
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * type 'long'.   Data should be in the range:  +/- 2^(8*size(long)-1)
+ *
+ */
+int CDECL lame_encode_buffer_long2(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const long     buffer_l [],       /* PCM data for left channel     */
+        const long     buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+/* as lame_encode_buffer, but for int's
+ * !! NOTE: !! input should be scaled to the maximum range of 'int'
+ * If int is 4 bytes, then the values should range from
+ * +/- 2147483648.
+ *
+ * This routine does not (and cannot, without loosing precision) use
+ * the same scaling as the rest of the lame_encode_buffer() routines.
+ *
+ */
+int CDECL lame_encode_buffer_int(
+        lame_global_flags*  gfp,           /* global context handle         */
+        const int      buffer_l [],       /* PCM data for left channel     */
+        const int      buffer_r [],       /* PCM data for right channel    */
+        const int           nsamples,      /* number of samples per channel */
+        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */
+        const int           mp3buf_size ); /* number of valid octets in this
+                                              stream                        */
+
+
+
+
+
+/*
+ * REQUIRED:
+ * lame_encode_flush will flush the intenal PCM buffers, padding with
+ * 0's to make sure the final frame is complete, and then flush
+ * the internal MP3 buffers, and thus may return a
+ * final few mp3 frames.  'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * will also write id3v1 tags (if any) into the bitstream
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush(
+        lame_global_flags *  gfp,    /* global context handle                 */
+        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */
+        int                  size);  /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * lame_encode_flush_nogap will flush the internal mp3 buffers and pad
+ * the last frame with ancillary data so it is a complete mp3 frame.
+ *
+ * 'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * After a call to this routine, the outputed mp3 data is complete, but
+ * you may continue to encode new PCM samples and write future mp3 data
+ * to a different file.  The two mp3 files will play back with no gaps
+ * if they are concatenated together.
+ *
+ * This routine will NOT write id3v1 tags into the bitstream.
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush_nogap(
+        lame_global_flags *  gfp,    /* global context handle                 */
+        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */
+        int                  size);  /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * Normally, this is called by lame_init_params().  It writes id3v2 and
+ * Xing headers into the front of the bitstream, and sets frame counters
+ * and bitrate histogram data to 0.  You can also call this after
+ * lame_encode_flush_nogap().
+ */
+int CDECL lame_init_bitstream(
+        lame_global_flags *  gfp);    /* global context handle                 */
+
+
+
+/*
+ * OPTIONAL:    some simple statistics
+ * a bitrate histogram to visualize the distribution of used frame sizes
+ * a stereo mode histogram to visualize the distribution of used stereo
+ *   modes, useful in joint-stereo mode only
+ *   0: LR    left-right encoded
+ *   1: LR-I  left-right and intensity encoded (currently not supported)
+ *   2: MS    mid-side encoded
+ *   3: MS-I  mid-side and intensity encoded (currently not supported)
+ *
+ * attention: don't call them after lame_encode_finish
+ * suggested: lame_encode_flush -> lame_*_hist -> lame_close
+ */
+
+void CDECL lame_bitrate_hist(
+        const lame_global_flags * gfp,
+        int bitrate_count[14] );
+void CDECL lame_bitrate_kbps(
+        const lame_global_flags * gfp,
+        int bitrate_kbps [14] );
+void CDECL lame_stereo_mode_hist(
+        const lame_global_flags * gfp,
+        int stereo_mode_count[4] );
+
+void CDECL lame_bitrate_stereo_mode_hist (
+        const lame_global_flags * gfp,
+        int bitrate_stmode_count[14][4] );
+
+void CDECL lame_block_type_hist (
+        const lame_global_flags * gfp,
+        int btype_count[6] );
+
+void CDECL lame_bitrate_block_type_hist (
+        const lame_global_flags * gfp,
+        int bitrate_btype_count[14][6] );
+
+#if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0)
+#else
+/*
+ * OPTIONAL:
+ * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file
+ * pointer fid.  These calls perform forward and backwards seeks, so make
+ * sure fid is a real file.  Make sure lame_encode_flush has been called,
+ * and all mp3 data has been written to the file before calling this
+ * function.
+ * NOTE:
+ * if VBR  tags are turned off by the user, or turned off by LAME because
+ * the output is not a regular file, this call does nothing
+ * NOTE:
+ * LAME wants to read from the file to skip an optional ID3v2 tag, so
+ * make sure you opened the file for writing and reading.
+ * NOTE:
+ * You can call lame_get_lametag_frame instead, if you want to insert
+ * the lametag yourself.
+*/
+void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid);
+#endif
+
+/*
+ * OPTIONAL:
+ * lame_get_lametag_frame copies the final LAME-tag into 'buffer'.
+ * The function returns the number of bytes copied into buffer, or
+ * the required buffer size, if the provided buffer is too small.
+ * Function failed, if the return value is larger than 'size'!
+ * Make sure lame_encode flush has been called before calling this function.
+ * NOTE:
+ * if VBR  tags are turned off by the user, or turned off by LAME,
+ * this call does nothing and returns 0.
+ * NOTE:
+ * LAME inserted an empty frame in the beginning of mp3 audio data,
+ * which you have to replace by the final LAME-tag frame after encoding.
+ * In case there is no ID3v2 tag, usually this frame will be the very first
+ * data in your mp3 file. If you put some other leading data into your
+ * file, you'll have to do some bookkeeping about where to write this buffer.
+ */
+size_t CDECL lame_get_lametag_frame(
+        const lame_global_flags *, unsigned char* buffer, size_t size);
+
+/*
+ * REQUIRED:
+ * final call to free all remaining buffers
+ */
+int  CDECL lame_close (lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/*
+ * OBSOLETE:
+ * lame_encode_finish combines lame_encode_flush() and lame_close() in
+ * one call.  However, once this call is made, the statistics routines
+ * will no longer work because the data will have been cleared, and
+ * lame_mp3_tags_fid() cannot be called to add data to the VBR header
+ */
+int CDECL lame_encode_finish(
+        lame_global_flags*  gfp,
+        unsigned char*      mp3buf,
+        int                 size );
+#endif
+
+
+
+
+
+
+/*********************************************************************
+ *
+ * decoding
+ *
+ * a simple interface to mpglib, part of mpg123, is also included if
+ * libmp3lame is compiled with HAVE_MPGLIB
+ *
+ *********************************************************************/
+
+struct hip_global_struct;
+typedef struct hip_global_struct hip_global_flags;
+typedef hip_global_flags *hip_t;
+
+
+typedef struct {
+  int header_parsed;   /* 1 if header was parsed and following data was
+                          computed                                       */
+  int stereo;          /* number of channels                             */
+  int samplerate;      /* sample rate                                    */
+  int bitrate;         /* bitrate                                        */
+  int mode;            /* mp3 frame type                                 */
+  int mode_ext;        /* mp3 frame type                                 */
+  int framesize;       /* number of samples per mp3 frame                */
+
+  /* this data is only computed if mpglib detects a Xing VBR header */
+  unsigned long nsamp; /* number of samples in mp3 file.                 */
+  int totalframes;     /* total number of frames in mp3 file             */
+
+  /* this data is not currently computed by the mpglib routines */
+  int framenum;        /* frames decoded counter                         */
+} mp3data_struct;
+
+/* required call to initialize decoder */
+hip_t CDECL hip_decode_init(void);
+
+/* cleanup call to exit decoder  */
+int CDECL hip_decode_exit(hip_t gfp);
+
+/* HIP reporting functions */
+void CDECL hip_set_errorf(hip_t gfp, lame_report_function f);
+void CDECL hip_set_debugf(hip_t gfp, lame_report_function f);
+void CDECL hip_set_msgf  (hip_t gfp, lame_report_function f);
+
+/*********************************************************************
+ * input 1 mp3 frame, output (maybe) pcm data.
+ *
+ *  nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r);
+ *
+ * input:
+ *    len          :  number of bytes of mp3 data in mp3buf
+ *    mp3buf[len]  :  mp3 data to be decoded
+ *
+ * output:
+ *    nout:  -1    : decoding error
+ *            0    : need more data before we can complete the decode
+ *           >0    : returned 'nout' samples worth of data in pcm_l,pcm_r
+ *    pcm_l[nout]  : left channel data
+ *    pcm_r[nout]  : right channel data
+ *
+ *********************************************************************/
+int CDECL hip_decode( hip_t           gfp
+                    , unsigned char * mp3buf
+                    , size_t          len
+                    , short           pcm_l[]
+                    , short           pcm_r[]
+                    );
+
+/* same as hip_decode, and also returns mp3 header data */
+int CDECL hip_decode_headers( hip_t           gfp
+                            , unsigned char*  mp3buf
+                            , size_t          len
+                            , short           pcm_l[]
+                            , short           pcm_r[]
+                            , mp3data_struct* mp3data
+                            );
+
+/* same as hip_decode, but returns at most one frame */
+int CDECL hip_decode1( hip_t          gfp
+                     , unsigned char* mp3buf
+                     , size_t         len
+                     , short          pcm_l[]
+                     , short          pcm_r[]
+                     );
+
+/* same as hip_decode1, but returns at most one frame and mp3 header data */
+int CDECL hip_decode1_headers( hip_t           gfp
+                             , unsigned char*  mp3buf
+                             , size_t          len
+                             , short           pcm_l[]
+                             , short           pcm_r[]
+                             , mp3data_struct* mp3data
+                             );
+
+/* same as hip_decode1_headers, but also returns enc_delay and enc_padding
+   from VBR Info tag, (-1 if no info tag was found) */
+int CDECL hip_decode1_headersB( hip_t gfp
+                              , unsigned char*   mp3buf
+                              , size_t           len
+                              , short            pcm_l[]
+                              , short            pcm_r[]
+                              , mp3data_struct*  mp3data
+                              , int             *enc_delay
+                              , int             *enc_padding
+                              );
+
+
+
+/* OBSOLETE:
+ * lame_decode... functions are there to keep old code working
+ * but it is strongly recommended to replace calls by hip_decode...
+ * function calls, see above.
+ */
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+int CDECL lame_decode_init(void);
+int CDECL lame_decode(
+        unsigned char *  mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[] );
+int CDECL lame_decode_headers(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data );
+int CDECL lame_decode1(
+        unsigned char*  mp3buf,
+        int             len,
+        short           pcm_l[],
+        short           pcm_r[] );
+int CDECL lame_decode1_headers(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data );
+int CDECL lame_decode1_headersB(
+        unsigned char*   mp3buf,
+        int              len,
+        short            pcm_l[],
+        short            pcm_r[],
+        mp3data_struct*  mp3data,
+        int              *enc_delay,
+        int              *enc_padding );
+int CDECL lame_decode_exit(void);
+
+#endif /* obsolete lame_decode API calls */
+
+
+/*********************************************************************
+ *
+ * id3tag stuff
+ *
+ *********************************************************************/
+
+/*
+ * id3tag.h -- Interface to write ID3 version 1 and 2 tags.
+ *
+ * Copyright (C) 2000 Don Melton.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* utility to obtain alphabetically sorted list of genre names with numbers */
+void CDECL id3tag_genre_list(
+        void (*handler)(int, const char *, void *),
+        void*  cookie);
+
+void CDECL id3tag_init     (lame_t gfp);
+
+/* force addition of version 2 tag */
+void CDECL id3tag_add_v2   (lame_t gfp);
+
+/* add only a version 1 tag */
+void CDECL id3tag_v1_only  (lame_t gfp);
+
+/* add only a version 2 tag */
+void CDECL id3tag_v2_only  (lame_t gfp);
+
+/* pad version 1 tag with spaces instead of nulls */
+void CDECL id3tag_space_v1 (lame_t gfp);
+
+/* pad version 2 tag with extra 128 bytes */
+void CDECL id3tag_pad_v2   (lame_t gfp);
+
+/* pad version 2 tag with extra n bytes */
+void CDECL id3tag_set_pad  (lame_t gfp, size_t n);
+
+void CDECL id3tag_set_title(lame_t gfp, const char* title);
+void CDECL id3tag_set_artist(lame_t gfp, const char* artist);
+void CDECL id3tag_set_album(lame_t gfp, const char* album);
+void CDECL id3tag_set_year(lame_t gfp, const char* year);
+void CDECL id3tag_set_comment(lame_t gfp, const char* comment);
+            
+/* return -1 result if track number is out of ID3v1 range
+                    and ignored for ID3v1 */
+int CDECL id3tag_set_track(lame_t gfp, const char* track);
+
+/* return non-zero result if genre name or number is invalid
+  result 0: OK
+  result -1: genre number out of range
+  result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other'
+             but taken as-is for ID3v2 genre tag */
+int CDECL id3tag_set_genre(lame_t gfp, const char* genre);
+
+/* return non-zero result if field name is invalid */
+int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue);
+
+/* return non-zero result if image type is invalid */
+int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size);
+
+/* lame_get_id3v1_tag copies ID3v1 tag into buffer.
+ * Function returns number of bytes copied into buffer, or number
+ * of bytes rquired if buffer 'size' is too small.
+ * Function fails, if returned value is larger than 'size'.
+ * NOTE:
+ * This functions does nothing, if user/LAME disabled ID3v1 tag.
+ */
+size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size);
+
+/* lame_get_id3v2_tag copies ID3v2 tag into buffer.
+ * Function returns number of bytes copied into buffer, or number
+ * of bytes rquired if buffer 'size' is too small.
+ * Function fails, if returned value is larger than 'size'.
+ * NOTE:
+ * This functions does nothing, if user/LAME disabled ID3v2 tag.
+ */
+size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size);
+
+/* normaly lame_init_param writes ID3v2 tags into the audio stream
+ * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param
+ * to turn off this behaviour and get ID3v2 tag with above function
+ * write it yourself into your file.
+ */
+void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int);
+int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp);
+
+/* experimental */
+int CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* experimental */
+int CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang,
+                                  unsigned short const *desc, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue);
+#endif
+
+/* experimental */
+int CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue);
+
+/* experimental */
+int CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text);
+
+
+/***********************************************************************
+*
+*  list of valid bitrates [kbps] & sample frequencies [Hz].
+*  first index: 0: MPEG-2   values  (sample frequencies 16...24 kHz)
+*               1: MPEG-1   values  (sample frequencies 32...48 kHz)
+*               2: MPEG-2.5 values  (sample frequencies  8...12 kHz)
+***********************************************************************/
+
+extern const int     bitrate_table    [3][16];
+extern const int     samplerate_table [3][ 4];
+
+/* access functions for use in DLL, global vars are not exported */
+int CDECL lame_get_bitrate(int mpeg_version, int table_index);
+int CDECL lame_get_samplerate(int mpeg_version, int table_index);
+
+
+/* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER
+   as well since lame_encode_buffer() also returns ID3v2 tag data */
+#define LAME_MAXALBUMART    (128 * 1024)
+
+/* maximum size of mp3buffer needed if you encode at most 1152 samples for
+   each call to lame_encode_buffer.  see lame_encode_buffer() below  
+   (LAME_MAXMP3BUFFER is now obsolete)  */
+#define LAME_MAXMP3BUFFER   (16384 + LAME_MAXALBUMART)
+
+
+typedef enum {
+    LAME_OKAY             =   0,
+    LAME_NOERROR          =   0,
+    LAME_GENERICERROR     =  -1,
+    LAME_NOMEM            = -10,
+    LAME_BADBITRATE       = -11,
+    LAME_BADSAMPFREQ      = -12,
+    LAME_INTERNALERROR    = -13,
+
+    FRONTEND_READERROR    = -80,
+    FRONTEND_WRITEERROR   = -81,
+    FRONTEND_FILETOOLARGE = -82
+
+} lame_errorcodes_t;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* LAME_LAME_H */
+

BIN
ios/Frameworks/lame.framework/lame


+ 6 - 6
ios/speech_plugin.podspec

@@ -16,12 +16,12 @@ A new Flutter plugin.
   s.source_files = 'Classes/**/*'
   s.source_files = 'Classes/**/*'
   s.public_header_files = 'Classes/**/*.h'
   s.public_header_files = 'Classes/**/*.h'
   s.dependency 'Flutter'
   s.dependency 'Flutter'
-  s.platform = :ios, '8.0'
-
-  s.frameworks = 'AVFoundation', 'SystemConfiguration', 'Foundation', 'CoreTelephony', 'AudioToolbox', 'UIKit', 'CoreLocation', 'QuartzCore', 'CoreGraphics'
-  s.libraries = 'z', 'c++'
-  s.vendored_frameworks = 'Frameworks/iflyMSC.framework'
-
+  s.platform = :ios, '8.0'
+  s.resource = "Classes/Libraries/libai/aiengine.provision"
+  s.frameworks = 'AVFoundation', 'SystemConfiguration', 'Foundation', 'CoreTelephony', 'AudioToolbox', 'UIKit', 'CoreLocation', 'QuartzCore', 'CoreGraphics', 'SystemConfiguration'
+  s.libraries = 'z', 'c++'
+  s.vendored_frameworks = 'Frameworks/iflyMSC.framework' , 'Frameworks/lame.framework' , 'Frameworks/TAISDK.framework'
+  s.vendored_libraries = 'Classes/Libraries/libai/libaiengine.a'
   # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
   # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
   s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
   s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
 end
 end

+ 126 - 0
lib/generated/i18n.dart

@@ -0,0 +1,126 @@
+import 'dart:async';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: camel_case_types
+// ignore_for_file: prefer_single_quotes
+
+// This file is automatically generated. DO NOT EDIT, all your changes would be lost.
+class S implements WidgetsLocalizations {
+  const S();
+
+  static S current;
+
+  static const GeneratedLocalizationsDelegate delegate =
+    GeneratedLocalizationsDelegate();
+
+  static S of(BuildContext context) => Localizations.of<S>(context, S);
+
+  @override
+  TextDirection get textDirection => TextDirection.ltr;
+
+}
+
+class $en extends S {
+  const $en();
+}
+
+class GeneratedLocalizationsDelegate extends LocalizationsDelegate<S> {
+  const GeneratedLocalizationsDelegate();
+
+  List<Locale> get supportedLocales {
+    return const <Locale>[
+      Locale("en", ""),
+    ];
+  }
+
+  LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) {
+    return (List<Locale> locales, Iterable<Locale> supported) {
+      if (locales == null || locales.isEmpty) {
+        return fallback ?? supported.first;
+      } else {
+        return _resolve(locales.first, fallback, supported, withCountry);
+      }
+    };
+  }
+
+  LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) {
+    return (Locale locale, Iterable<Locale> supported) {
+      return _resolve(locale, fallback, supported, withCountry);
+    };
+  }
+
+  @override
+  Future<S> load(Locale locale) {
+    final String lang = getLang(locale);
+    if (lang != null) {
+      switch (lang) {
+        case "en":
+          S.current = const $en();
+          return SynchronousFuture<S>(S.current);
+        default:
+          // NO-OP.
+      }
+    }
+    S.current = const S();
+    return SynchronousFuture<S>(S.current);
+  }
+
+  @override
+  bool isSupported(Locale locale) => _isSupported(locale, true);
+
+  @override
+  bool shouldReload(GeneratedLocalizationsDelegate old) => false;
+
+  ///
+  /// Internal method to resolve a locale from a list of locales.
+  ///
+  Locale _resolve(Locale locale, Locale fallback, Iterable<Locale> supported, bool withCountry) {
+    if (locale == null || !_isSupported(locale, withCountry)) {
+      return fallback ?? supported.first;
+    }
+
+    final Locale languageLocale = Locale(locale.languageCode, "");
+    if (supported.contains(locale)) {
+      return locale;
+    } else if (supported.contains(languageLocale)) {
+      return languageLocale;
+    } else {
+      final Locale fallbackLocale = fallback ?? supported.first;
+      return fallbackLocale;
+    }
+  }
+
+  ///
+  /// Returns true if the specified locale is supported, false otherwise.
+  ///
+  bool _isSupported(Locale locale, bool withCountry) {
+    if (locale != null) {
+      for (Locale supportedLocale in supportedLocales) {
+        // Language must always match both locales.
+        if (supportedLocale.languageCode != locale.languageCode) {
+          continue;
+        }
+
+        // If country code matches, return this locale.
+        if (supportedLocale.countryCode == locale.countryCode) {
+          return true;
+        }
+
+        // If no country requirement is requested, check if this locale has no country.
+        if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+String getLang(Locale l) => l == null
+  ? null
+  : l.countryCode != null && l.countryCode.isEmpty
+    ? l.languageCode
+    : l.toString();

+ 1 - 1
lib/speech_plugin.dart

@@ -82,5 +82,5 @@ class SpeechPlugin {
 }
 }
 
 
 enum SpeechSdk {
 enum SpeechSdk {
-  IFly, Chivox, SmartOral
+  IFly, Chivox, SmartOral // 0 讯飞 1 词声 2 腾讯
 }
 }

+ 29 - 29
pubspec.lock

@@ -5,56 +5,56 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: archive
       name: archive
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "2.0.10"
+    version: "2.0.11"
   args:
   args:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: args
       name: args
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.5.2"
     version: "1.5.2"
   async:
   async:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: async
       name: async
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "2.3.0"
+    version: "2.4.0"
   boolean_selector:
   boolean_selector:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: boolean_selector
       name: boolean_selector
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.0.5"
     version: "1.0.5"
   charcode:
   charcode:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: charcode
       name: charcode
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.2"
     version: "1.1.2"
   collection:
   collection:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: collection
       name: collection
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.14.11"
     version: "1.14.11"
   convert:
   convert:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: convert
       name: convert
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.1"
     version: "2.1.1"
   crypto:
   crypto:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: crypto
       name: crypto
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.3"
     version: "2.1.3"
   flutter:
   flutter:
@@ -71,49 +71,49 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: image
       name: image
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.1.4"
     version: "2.1.4"
   matcher:
   matcher:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: matcher
       name: matcher
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "0.12.5"
+    version: "0.12.6"
   meta:
   meta:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: meta
       name: meta
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "1.1.7"
+    version: "1.1.8"
   path:
   path:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: path
       name: path
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.6.4"
     version: "1.6.4"
   pedantic:
   pedantic:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: pedantic
       name: pedantic
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.8.0+1"
     version: "1.8.0+1"
   petitparser:
   petitparser:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: petitparser
       name: petitparser
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.4.0"
     version: "2.4.0"
   quiver:
   quiver:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: quiver
       name: quiver
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.5"
     version: "2.0.5"
   sky_engine:
   sky_engine:
@@ -125,63 +125,63 @@ packages:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: source_span
       name: source_span
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.5.5"
     version: "1.5.5"
   stack_trace:
   stack_trace:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: stack_trace
       name: stack_trace
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.9.3"
     version: "1.9.3"
   stream_channel:
   stream_channel:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: stream_channel
       name: stream_channel
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.0"
     version: "2.0.0"
   string_scanner:
   string_scanner:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: string_scanner
       name: string_scanner
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.0.5"
     version: "1.0.5"
   term_glyph:
   term_glyph:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: term_glyph
       name: term_glyph
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.0"
     version: "1.1.0"
   test_api:
   test_api:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: test_api
       name: test_api
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "0.2.5"
+    version: "0.2.11"
   typed_data:
   typed_data:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: typed_data
       name: typed_data
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "1.1.6"
     version: "1.1.6"
   vector_math:
   vector_math:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: vector_math
       name: vector_math
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "2.0.8"
     version: "2.0.8"
   xml:
   xml:
     dependency: transitive
     dependency: transitive
     description:
     description:
       name: xml
       name: xml
-      url: "https://pub.flutter-io.cn"
+      url: "https://pub.dev"
     source: hosted
     source: hosted
     version: "3.5.0"
     version: "3.5.0"
 sdks:
 sdks:

+ 1 - 0
res/values/strings_en.arb

@@ -0,0 +1 @@
+{}

+ 1 - 0
speech_plugin.iml

@@ -11,6 +11,7 @@
       <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
       <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
       <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
       <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
       <excludeFolder url="file://$MODULE_DIR$/example/build" />
       <excludeFolder url="file://$MODULE_DIR$/example/build" />
+      <excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
     </content>
     </content>
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="Dart SDK" level="project" />
     <orderEntry type="library" name="Dart SDK" level="project" />