相关文章推荐

使用Delphi,我试图改变AndroidTTS的音量,但我似乎一直得到错误 "外部异常1"

1 人关注

我正在使用这些库。

https://github.com/jimmckeeth/FireMonkey-Android-Voice

https://github.com/FMXExpress/android-object-pascal-wrapper/tree/master/android-25

Here is my source code:

unit Unit1;
interface
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  SpeechRecognition, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo,
  FMX.StdCtrls, FMX.Memo.Types, AndroidTTS, FMX.Media, System.IOUtils;
  TForm1 = class(TForm)
    SpeechRecognition1: TSpeechRecognition;
    Memo1: TMemo;
    Button1: TButton;
    AndroidTTS1: TAndroidTTS;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    MediaPlayer1: TMediaPlayer;
    Button5: TButton;
    procedure SpeechRecognition1Command(Sender: TObject; Guess: string);
    procedure SpeechRecognition1Recognition(Sender: TObject; Guess: string);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  Form1: TForm1;
implementation
{$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID}
procedure TForm1.Button1Click(Sender: TObject);
begin
  SpeechRecognition1.Prompt := 'What you want?';
  SpeechRecognition1.Listen;
procedure TForm1.Button2Click(Sender: TObject);
begin
  AndroidTTS1.setSpeechRate(0.75);
  AndroidTTS1.SpeakVolume('Hello, whats up?',0.75);
procedure TForm1.Button3Click(Sender: TObject);
begin
  MediaPlayer1.Volume := 0.25;
  MediaPlayer1.FileName := TPath.GetDocumentsPath + PathDelim + 'HerosOfLegend.wav';
  MediaPlayer1.Play;
procedure TForm1.Button4Click(Sender: TObject);
begin
  MediaPlayer1.Stop;
procedure TForm1.Button5Click(Sender: TObject);
begin
  AndroidTTS1.setSpeechRate(0.75);
  AndroidTTS1.SpeakBundle('Hello bundle is this method!');
procedure TForm1.SpeechRecognition1Command(Sender: TObject; Guess: string);
begin
  memo1.Lines.Add('Command: ' + Guess);
procedure TForm1.SpeechRecognition1Recognition(Sender: TObject; Guess: string);
begin
  memo1.Lines.Add('OnRecognition: ' + Guess);

On line 123 in https://github.com/jimmckeeth/FireMonkey-Android-Voice/blob/master/JNIBridge/Androidapi.JNI.TTS.pas ....我把它改成了。

function speak(text: JString; queueMode: Integer; params: JHashMap) : Integer; cdecl; Overload;
function speak(text: JString; queueMode: Integer; params: JBundle; utteranceId: JString) : Integer; cdecl; Overload;

On line 44 in https://github.com/jimmckeeth/FireMonkey-Android-Voice/blob/master/Components/AndroidTTS.pas ...我把它改成了。

  procedure Speak(say: String);
  procedure SpeakBundle(say: String);
  procedure SpeakVolume(say: String; volume: single);
  procedure setPitch(pitch: Single);
  procedure setSpeechRate(speechRate: Single);
  function isSpeaking: Boolean;

On line 80 to 97 in https://github.com/jimmckeeth/FireMonkey-Android-Voice/blob/master/Components/AndroidTTS.pas ...我把它改成了这样。

procedure TAndroidTTS.SpeakBundle(say: String);
{$IFDEF ANDROID}
  params: JBundle;
begin
  params := nil;
  //params := TJHashMap.Create;
  //params.put(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,
     //StringToJString('0.75'));
  //params := TJBundle.JavaClass.init();
  //params.putFloat(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,volume);
// This needs to be a <String,String> hashmap for the OnDone to work.
{  params := TJHashMap.JavaClass.init();
  params.put(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_UTTERANCE_ID,
     StringToJString('id'));   }
  ftts.speak(StringToJString(say), TJTextToSpeech.JavaClass.QUEUE_FLUSH, params, StringToJString('1'));
{$ELSE}
begin
{$ENDIF}
procedure TAndroidTTS.SpeakVolume(say: String; volume: single);
{$IFDEF ANDROID}
  params: JBundle;
begin
  //params := TJHashMap.Create;
  //params.put(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,
     //StringToJString('0.75'));
  //params := nil;
  params := TJBundle.JavaClass.init();
  params.putFloat(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,0.75);
// This needs to be a <String,String> hashmap for the OnDone to work.
{  params := TJHashMap.JavaClass.init();
  params.put(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_UTTERANCE_ID,
     StringToJString('id'));   }
  //ftts.speak(StringToJString(say), TJTextToSpeech.JavaClass.QUEUE_ADD, params, StringToJString('1'));
{$ELSE}
begin
{$ENDIF}
procedure TAndroidTTS.setPitch(pitch: Single);
{$IFDEF ANDROID}
begin
  //pitch   float: Speech pitch. 1.0 is the normal pitch, lower values lower the tone of the synthesized voice, greater values increase it.
  ftts.setPitch(pitch);
{$ELSE}
begin
{$ENDIF}
procedure TAndroidTTS.setSpeechRate(speechRate: Single);
{$IFDEF ANDROID}
begin
  //float: Speech rate. 1.0 is the normal speech rate, lower values slow down the speech (0.5 is half the normal speech rate), greater values accelerate it (2.0 is twice the normal speech rate).
  ftts.setSpeechRate(speechRate);
{$ELSE}
begin
{$ENDIF}
function TAndroidTTS.isSpeaking: Boolean;
{$IFDEF ANDROID}
begin
  // Checks whether the TTS engine is busy speaking.
  result := ftts.isSpeaking;
{$ELSE}
begin
  result := false;
{$ENDIF}

我似乎无法让过程TAndroidTTS.SpeakVolume(say: String; volume: single);正确工作。 在 "params.putFloat(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,0.75)。 "这一行,Android给了我一个错误 "外部异常1。"

我改变并更新了代码,连同https://developer.android.com/reference/android/speech/tts/TextToSpeech.Engine#KEY_PARAM_VOLUME因为他们把它改成了使用Bundles而不是Hashmaps。

我并不完全清楚什么是错的params.putFloat(TJTextToSpeech_Engine.JavaClass.KEY_PARAM_VOLUME,0.75)。......这是安卓系统停止的地方,并给出了代码。

Other resources:

我已经看过了,这就是为什么我的代码使用params.putFloat。

安卓文字转语音的音量没有变化

The only thing I could find on my error with Delphi is this:

https://community.idera.com/developer-tools/platforms/f/android-platform/70741/inapppurchase

which should be fixed in Delphi 10.4.1, right? I checked the https://quality.embarcadero.com/browse/RSP-27140网页上发现那是固定的。 我是不是遇到了不同的问题?

非常感谢任何帮助!

android
delphi
text
volume
speech
Greg T
Greg T
发布于 2020-11-02
1 个回答
Dave Nottage
Dave Nottage
发布于 2020-11-02
已采纳
0 人赞同

你收到的异常是由于这个导入有一个错误。

https://github.com/jimmckeeth/FireMonkey-Android-Voice/blob/master/JNIBridge/Androidapi.JNI.TTS.pas

...因为 JTextToSpeech_Engine 没有 JavaSignature 的属性。它应该是。

  [JavaSignature('android/speech/tts/TextToSpeech$Engine')]
  JTextToSpeech_Engine = interface(JObject)
    ['{5BAC3048-CB0C-4DC4-AF62-D0D9AE4394CF}']

Reference:

https://developer.android.com/reference/android/speech/tts/TextToSpeech#speak(java.lang.CharSequence,%20int,%20android.os.Bundle,%20java.lang.String)

发言方法的声明应该是。

function speak(text: JCharSequence; queueMode: Integer; params: JBundle; utteranceId: JString): Integer; cdecl; overload;
 
推荐文章