Fangjun Kuang
Committed by GitHub

Add Pascal API for Moonshine models (#1482)

@@ -165,6 +165,10 @@ jobs: @@ -165,6 +165,10 @@ jobs:
165 cd ./pascal-api-examples 165 cd ./pascal-api-examples
166 166
167 pushd vad-with-non-streaming-asr 167 pushd vad-with-non-streaming-asr
  168 + time ./run-vad-with-moonshine.sh
  169 + rm -rf sherpa-onnx-*
  170 + echo "---"
  171 +
168 time ./run-vad-with-whisper.sh 172 time ./run-vad-with-whisper.sh
169 rm -rf sherpa-onnx-* 173 rm -rf sherpa-onnx-*
170 echo "---" 174 echo "---"
@@ -220,6 +224,10 @@ jobs: @@ -220,6 +224,10 @@ jobs:
220 rm -rf sherpa-onnx-* 224 rm -rf sherpa-onnx-*
221 echo "---" 225 echo "---"
222 226
  227 + ./run-moonshine.sh
  228 + rm -rf sherpa-onnx-*
  229 + echo "---"
  230 +
223 ./run-whisper.sh 231 ./run-whisper.sh
224 rm -rf sherpa-onnx-* 232 rm -rf sherpa-onnx-*
225 echo "---" 233 echo "---"
@@ -7,3 +7,4 @@ paraformer @@ -7,3 +7,4 @@ paraformer
7 paraformer_itn 7 paraformer_itn
8 sense_voice 8 sense_voice
9 telespeech_ctc 9 telespeech_ctc
  10 +moonshine
  1 +{ Copyright (c) 2024 Xiaomi Corporation }
  2 +
  3 +{
  4 +This file shows how to use a non-streaming Moonshine model
  5 +to decode files.
  6 +
  7 +You can download the model files from
  8 +https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models
  9 +}
  10 +
  11 +program moonshine;
  12 +
  13 +{$mode objfpc}
  14 +
  15 +uses
  16 + sherpa_onnx,
  17 + DateUtils,
  18 + SysUtils;
  19 +
  20 +var
  21 + Wave: TSherpaOnnxWave;
  22 + WaveFilename: AnsiString;
  23 +
  24 + Config: TSherpaOnnxOfflineRecognizerConfig;
  25 + Recognizer: TSherpaOnnxOfflineRecognizer;
  26 + Stream: TSherpaOnnxOfflineStream;
  27 + RecognitionResult: TSherpaOnnxOfflineRecognizerResult;
  28 +
  29 + Start: TDateTime;
  30 + Stop: TDateTime;
  31 +
  32 + Elapsed: Single;
  33 + Duration: Single;
  34 + RealTimeFactor: Single;
  35 +begin
  36 + Initialize(Config);
  37 +
  38 + Config.ModelConfig.Moonshine.Preprocessor := './sherpa-onnx-moonshine-tiny-en-int8/preprocess.onnx';
  39 + Config.ModelConfig.Moonshine.Encoder := './sherpa-onnx-moonshine-tiny-en-int8/encode.int8.onnx';
  40 + Config.ModelConfig.Moonshine.UncachedDecoder := './sherpa-onnx-moonshine-tiny-en-int8/uncached_decode.int8.onnx';
  41 + Config.ModelConfig.Moonshine.CachedDecoder := './sherpa-onnx-moonshine-tiny-en-int8/cached_decode.int8.onnx';
  42 +
  43 + Config.ModelConfig.Tokens := './sherpa-onnx-moonshine-tiny-en-int8/tokens.txt';
  44 + Config.ModelConfig.Provider := 'cpu';
  45 + Config.ModelConfig.NumThreads := 1;
  46 + Config.ModelConfig.Debug := False;
  47 +
  48 + WaveFilename := './sherpa-onnx-moonshine-tiny-en-int8/test_wavs/0.wav';
  49 +
  50 + Wave := SherpaOnnxReadWave(WaveFilename);
  51 +
  52 + Recognizer := TSherpaOnnxOfflineRecognizer.Create(Config);
  53 + Stream := Recognizer.CreateStream();
  54 + Start := Now;
  55 +
  56 + Stream.AcceptWaveform(Wave.Samples, Wave.SampleRate);
  57 + Recognizer.Decode(Stream);
  58 +
  59 + RecognitionResult := Recognizer.GetResult(Stream);
  60 +
  61 + Stop := Now;
  62 +
  63 + Elapsed := MilliSecondsBetween(Stop, Start) / 1000;
  64 + Duration := Length(Wave.Samples) / Wave.SampleRate;
  65 + RealTimeFactor := Elapsed / Duration;
  66 +
  67 + WriteLn(RecognitionResult.ToString);
  68 + WriteLn(Format('NumThreads %d', [Config.ModelConfig.NumThreads]));
  69 + WriteLn(Format('Elapsed %.3f s', [Elapsed]));
  70 + WriteLn(Format('Wave duration %.3f s', [Duration]));
  71 + WriteLn(Format('RTF = %.3f/%.3f = %.3f', [Elapsed, Duration, RealTimeFactor]));
  72 +
  73 + {Free resources to avoid memory leak.
  74 +
  75 + Note: You don't need to invoke them for this simple script.
  76 + However, you have to invoke them in your own large/complex project.
  77 + }
  78 + FreeAndNil(Stream);
  79 + FreeAndNil(Recognizer);
  80 +end.
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
  6 +SHERPA_ONNX_DIR=$(cd $SCRIPT_DIR/../.. && pwd)
  7 +
  8 +echo "SHERPA_ONNX_DIR: $SHERPA_ONNX_DIR"
  9 +
  10 +if [[ ! -f ../../build/install/lib/libsherpa-onnx-c-api.dylib && ! -f ../../build/install/lib/libsherpa-onnx-c-api.so && ! -f ../../build/install/lib/sherpa-onnx-c-api.dll ]]; then
  11 + mkdir -p ../../build
  12 + pushd ../../build
  13 + cmake \
  14 + -DCMAKE_INSTALL_PREFIX=./install \
  15 + -DSHERPA_ONNX_ENABLE_PYTHON=OFF \
  16 + -DSHERPA_ONNX_ENABLE_TESTS=OFF \
  17 + -DSHERPA_ONNX_ENABLE_CHECK=OFF \
  18 + -DBUILD_SHARED_LIBS=ON \
  19 + -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
  20 + ..
  21 +
  22 + cmake --build . --target install --config Release
  23 + ls -lh lib
  24 + popd
  25 +fi
  26 +
  27 +if [ ! -f ./sherpa-onnx-moonshine-tiny-en-int8/tokens.txt ]; then
  28 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  29 + tar xvf sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  30 + rm sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  31 +fi
  32 +
  33 +fpc \
  34 + -dSHERPA_ONNX_USE_SHARED_LIBS \
  35 + -Fu$SHERPA_ONNX_DIR/sherpa-onnx/pascal-api \
  36 + -Fl$SHERPA_ONNX_DIR/build/install/lib \
  37 + ./moonshine.pas
  38 +
  39 +export LD_LIBRARY_PATH=$SHERPA_ONNX_DIR/build/install/lib:$LD_LIBRARY_PATH
  40 +export DYLD_LIBRARY_PATH=$SHERPA_ONNX_DIR/build/install/lib:$DYLD_LIBRARY_PATH
  41 +
  42 +./moonshine
1 !run-*.sh 1 !run-*.sh
2 vad_with_whisper 2 vad_with_whisper
3 vad_with_sense_voice 3 vad_with_sense_voice
  4 +vad_with_moonshine
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
  6 +SHERPA_ONNX_DIR=$(cd $SCRIPT_DIR/../.. && pwd)
  7 +
  8 +echo "SHERPA_ONNX_DIR: $SHERPA_ONNX_DIR"
  9 +
  10 +if [[ ! -f ../../build/install/lib/libsherpa-onnx-c-api.dylib && ! -f ../../build/install/lib/libsherpa-onnx-c-api.so && ! -f ../../build/install/lib/sherpa-onnx-c-api.dll ]]; then
  11 + mkdir -p ../../build
  12 + pushd ../../build
  13 + cmake \
  14 + -DCMAKE_INSTALL_PREFIX=./install \
  15 + -DSHERPA_ONNX_ENABLE_PYTHON=OFF \
  16 + -DSHERPA_ONNX_ENABLE_TESTS=OFF \
  17 + -DSHERPA_ONNX_ENABLE_CHECK=OFF \
  18 + -DBUILD_SHARED_LIBS=ON \
  19 + -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
  20 + ..
  21 +
  22 + cmake --build . --target install --config Release
  23 + popd
  24 +fi
  25 +
  26 +if [[ ! -f ./silero_vad.onnx ]]; then
  27 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx
  28 +fi
  29 +
  30 +if [ ! -f ./Obama.wav ]; then
  31 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/Obama.wav
  32 +fi
  33 +
  34 +if [ ! -f ./sherpa-onnx-moonshine-tiny-en-int8/tokens.txt ]; then
  35 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  36 + tar xvf sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  37 + rm sherpa-onnx-moonshine-tiny-en-int8.tar.bz2
  38 +fi
  39 +
  40 +fpc \
  41 + -dSHERPA_ONNX_USE_SHARED_LIBS \
  42 + -Fu$SHERPA_ONNX_DIR/sherpa-onnx/pascal-api \
  43 + -Fl$SHERPA_ONNX_DIR/build/install/lib \
  44 + ./vad_with_moonshine.pas
  45 +
  46 +export LD_LIBRARY_PATH=$SHERPA_ONNX_DIR/build/install/lib:$LD_LIBRARY_PATH
  47 +export DYLD_LIBRARY_PATH=$SHERPA_ONNX_DIR/build/install/lib:$DYLD_LIBRARY_PATH
  48 +
  49 +./vad_with_moonshine
  1 +{ Copyright (c) 2024 Xiaomi Corporation }
  2 +
  3 +{
  4 +This file shows how to use a non-streaming Moonshine model
  5 +with silero VAD to decode files.
  6 +
  7 +You can download the model files from
  8 +https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models
  9 +}
  10 +
  11 +program vad_with_moonshine;
  12 +
  13 +{$mode objfpc}
  14 +
  15 +uses
  16 + sherpa_onnx,
  17 + SysUtils;
  18 +
  19 +function CreateVad(): TSherpaOnnxVoiceActivityDetector;
  20 +var
  21 + Config: TSherpaOnnxVadModelConfig;
  22 +
  23 + SampleRate: Integer;
  24 + WindowSize: Integer;
  25 +begin
  26 + Initialize(Config);
  27 +
  28 + SampleRate := 16000; {Please don't change it unless you know the details}
  29 + WindowSize := 512; {Please don't change it unless you know the details}
  30 +
  31 + Config.SileroVad.Model := './silero_vad.onnx';
  32 + Config.SileroVad.MinSpeechDuration := 0.5;
  33 + Config.SileroVad.MinSilenceDuration := 0.5;
  34 + Config.SileroVad.Threshold := 0.5;
  35 + Config.SileroVad.WindowSize := WindowSize;
  36 + Config.NumThreads:= 1;
  37 + Config.Debug:= True;
  38 + Config.Provider:= 'cpu';
  39 + Config.SampleRate := SampleRate;
  40 +
  41 + Result := TSherpaOnnxVoiceActivityDetector.Create(Config, 30);
  42 +end;
  43 +
  44 +function CreateOfflineRecognizer(): TSherpaOnnxOfflineRecognizer;
  45 +var
  46 + Config: TSherpaOnnxOfflineRecognizerConfig;
  47 +begin
  48 + Initialize(Config);
  49 +
  50 + Config.ModelConfig.Moonshine.Preprocessor := './sherpa-onnx-moonshine-tiny-en-int8/preprocess.onnx';
  51 + Config.ModelConfig.Moonshine.Encoder := './sherpa-onnx-moonshine-tiny-en-int8/encode.int8.onnx';
  52 + Config.ModelConfig.Moonshine.UncachedDecoder := './sherpa-onnx-moonshine-tiny-en-int8/uncached_decode.int8.onnx';
  53 + Config.ModelConfig.Moonshine.CachedDecoder := './sherpa-onnx-moonshine-tiny-en-int8/cached_decode.int8.onnx';
  54 +
  55 + Config.ModelConfig.Tokens := './sherpa-onnx-moonshine-tiny-en-int8/tokens.txt';
  56 + Config.ModelConfig.Provider := 'cpu';
  57 + Config.ModelConfig.NumThreads := 1;
  58 + Config.ModelConfig.Debug := False;
  59 +
  60 + Result := TSherpaOnnxOfflineRecognizer.Create(Config);
  61 +end;
  62 +
  63 +var
  64 + Wave: TSherpaOnnxWave;
  65 +
  66 + Recognizer: TSherpaOnnxOfflineRecognizer;
  67 + Vad: TSherpaOnnxVoiceActivityDetector;
  68 +
  69 + Offset: Integer;
  70 + WindowSize: Integer;
  71 + SpeechSegment: TSherpaOnnxSpeechSegment;
  72 +
  73 + Start: Single;
  74 + Duration: Single;
  75 +
  76 + Stream: TSherpaOnnxOfflineStream;
  77 + RecognitionResult: TSherpaOnnxOfflineRecognizerResult;
  78 +begin
  79 + Vad := CreateVad();
  80 + Recognizer := CreateOfflineRecognizer();
  81 +
  82 + Wave := SherpaOnnxReadWave('./Obama.wav');
  83 + if Wave.SampleRate <> Vad.Config.SampleRate then
  84 + begin
  85 + WriteLn(Format('Expected sample rate: %d. Given: %d',
  86 + [Vad.Config.SampleRate, Wave.SampleRate]));
  87 +
  88 + Exit;
  89 + end;
  90 +
  91 + WindowSize := Vad.Config.SileroVad.WindowSize;
  92 + Offset := 0;
  93 + while Offset + WindowSize <= Length(Wave.Samples) do
  94 + begin
  95 + Vad.AcceptWaveform(Wave.Samples, Offset, WindowSize);
  96 + Offset += WindowSize;
  97 +
  98 + while not Vad.IsEmpty do
  99 + begin
  100 + SpeechSegment := Vad.Front();
  101 + Vad.Pop();
  102 + Stream := Recognizer.CreateStream();
  103 +
  104 + Stream.AcceptWaveform(SpeechSegment.Samples, Wave.SampleRate);
  105 + Recognizer.Decode(Stream);
  106 + RecognitionResult := Recognizer.GetResult(Stream);
  107 +
  108 + Start := SpeechSegment.Start / Wave.SampleRate;
  109 + Duration := Length(SpeechSegment.Samples) / Wave.SampleRate;
  110 + WriteLn(Format('%.3f -- %.3f %s',
  111 + [Start, Start + Duration, RecognitionResult.Text]));
  112 +
  113 + FreeAndNil(Stream);
  114 + end;
  115 + end;
  116 +
  117 + Vad.Flush;
  118 +
  119 + while not Vad.IsEmpty do
  120 + begin
  121 + SpeechSegment := Vad.Front();
  122 + Vad.Pop();
  123 + Stream := Recognizer.CreateStream();
  124 +
  125 + Stream.AcceptWaveform(SpeechSegment.Samples, Wave.SampleRate);
  126 + Recognizer.Decode(Stream);
  127 + RecognitionResult := Recognizer.GetResult(Stream);
  128 +
  129 + Start := SpeechSegment.Start / Wave.SampleRate;
  130 + Duration := Length(SpeechSegment.Samples) / Wave.SampleRate;
  131 + WriteLn(Format('%.3f -- %.3f %s',
  132 + [Start, Start + Duration, RecognitionResult.Text]));
  133 +
  134 + FreeAndNil(Stream);
  135 + end;
  136 +
  137 + FreeAndNil(Recognizer);
  138 + FreeAndNil(Vad);
  139 +end.
@@ -250,6 +250,14 @@ type @@ -250,6 +250,14 @@ type
250 class operator Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Dest: TSherpaOnnxOfflineWhisperModelConfig); 250 class operator Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Dest: TSherpaOnnxOfflineWhisperModelConfig);
251 end; 251 end;
252 252
  253 + TSherpaOnnxOfflineMoonshineModelConfig = record
  254 + Preprocessor: AnsiString;
  255 + Encoder: AnsiString;
  256 + UncachedDecoder: AnsiString;
  257 + CachedDecoder: AnsiString;
  258 + function ToString: AnsiString;
  259 + end;
  260 +
253 TSherpaOnnxOfflineTdnnModelConfig = record 261 TSherpaOnnxOfflineTdnnModelConfig = record
254 Model: AnsiString; 262 Model: AnsiString;
255 function ToString: AnsiString; 263 function ToString: AnsiString;
@@ -285,6 +293,7 @@ type @@ -285,6 +293,7 @@ type
285 BpeVocab: AnsiString; 293 BpeVocab: AnsiString;
286 TeleSpeechCtc: AnsiString; 294 TeleSpeechCtc: AnsiString;
287 SenseVoice: TSherpaOnnxOfflineSenseVoiceModelConfig; 295 SenseVoice: TSherpaOnnxOfflineSenseVoiceModelConfig;
  296 + Moonshine: TSherpaOnnxOfflineMoonshineModelConfig;
288 class operator Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Dest: TSherpaOnnxOfflineModelConfig); 297 class operator Initialize({$IFDEF FPC}var{$ELSE}out{$ENDIF} Dest: TSherpaOnnxOfflineModelConfig);
289 function ToString: AnsiString; 298 function ToString: AnsiString;
290 end; 299 end;
@@ -617,6 +626,12 @@ type @@ -617,6 +626,12 @@ type
617 Task: PAnsiChar; 626 Task: PAnsiChar;
618 TailPaddings: cint32; 627 TailPaddings: cint32;
619 end; 628 end;
  629 + SherpaOnnxOfflineMoonshineModelConfig = record
  630 + Preprocessor: PAnsiChar;
  631 + Encoder: PAnsiChar;
  632 + UncachedDecoder: PAnsiChar;
  633 + CachedDecoder: PAnsiChar;
  634 + end;
620 SherpaOnnxOfflineTdnnModelConfig = record 635 SherpaOnnxOfflineTdnnModelConfig = record
621 Model: PAnsiChar; 636 Model: PAnsiChar;
622 end; 637 end;
@@ -644,6 +659,7 @@ type @@ -644,6 +659,7 @@ type
644 BpeVocab: PAnsiChar; 659 BpeVocab: PAnsiChar;
645 TeleSpeechCtc: PAnsiChar; 660 TeleSpeechCtc: PAnsiChar;
646 SenseVoice: SherpaOnnxOfflineSenseVoiceModelConfig; 661 SenseVoice: SherpaOnnxOfflineSenseVoiceModelConfig;
  662 + Moonshine: SherpaOnnxOfflineMoonshineModelConfig;
647 end; 663 end;
648 664
649 SherpaOnnxOfflineRecognizerConfig = record 665 SherpaOnnxOfflineRecognizerConfig = record
@@ -1312,6 +1328,16 @@ begin @@ -1312,6 +1328,16 @@ begin
1312 [Self.Encoder, Self.Decoder, Self.Language, Self.Task, Self.TailPaddings]); 1328 [Self.Encoder, Self.Decoder, Self.Language, Self.Task, Self.TailPaddings]);
1313 end; 1329 end;
1314 1330
  1331 +function TSherpaOnnxOfflineMoonshineModelConfig.ToString: AnsiString;
  1332 +begin
  1333 + Result := Format('TSherpaOnnxOfflineMoonshineModelConfig(' +
  1334 + 'Preprocessor := %s, ' +
  1335 + 'Encoder := %s, ' +
  1336 + 'UncachedDecoder := %s, ' +
  1337 + 'CachedDecoder := %s)',
  1338 + [Self.Preprocessor, Self.Encoder, Self.UncachedDecoder, Self.CachedDecoder]);
  1339 +end;
  1340 +
1315 function TSherpaOnnxOfflineTdnnModelConfig.ToString: AnsiString; 1341 function TSherpaOnnxOfflineTdnnModelConfig.ToString: AnsiString;
1316 begin 1342 begin
1317 Result := Format('TSherpaOnnxOfflineTdnnModelConfig(Model := %s)', 1343 Result := Format('TSherpaOnnxOfflineTdnnModelConfig(Model := %s)',
@@ -1353,13 +1379,14 @@ begin @@ -1353,13 +1379,14 @@ begin
1353 'ModelingUnit := %s, ' + 1379 'ModelingUnit := %s, ' +
1354 'BpeVocab := %s, ' + 1380 'BpeVocab := %s, ' +
1355 'TeleSpeechCtc := %s, ' + 1381 'TeleSpeechCtc := %s, ' +
1356 - 'SenseVoice := %s' + 1382 + 'SenseVoice := %s, ' +
  1383 + 'Moonshine := %s' +
1357 ')', 1384 ')',
1358 [Self.Transducer.ToString, Self.Paraformer.ToString, 1385 [Self.Transducer.ToString, Self.Paraformer.ToString,
1359 Self.NeMoCtc.ToString, Self.Whisper.ToString, Self.Tdnn.ToString, 1386 Self.NeMoCtc.ToString, Self.Whisper.ToString, Self.Tdnn.ToString,
1360 Self.Tokens, Self.NumThreads, Self.Debug.ToString, Self.Provider, 1387 Self.Tokens, Self.NumThreads, Self.Debug.ToString, Self.Provider,
1361 Self.ModelType, Self.ModelingUnit, Self.BpeVocab, 1388 Self.ModelType, Self.ModelingUnit, Self.BpeVocab,
1362 - Self.TeleSpeechCtc, Self.SenseVoice.ToString 1389 + Self.TeleSpeechCtc, Self.SenseVoice.ToString, Self.Moonshine.ToString
1363 ]); 1390 ]);
1364 end; 1391 end;
1365 1392
@@ -1407,7 +1434,6 @@ begin @@ -1407,7 +1434,6 @@ begin
1407 1434
1408 C.ModelConfig.Tdnn.Model := PAnsiChar(Config.ModelConfig.Tdnn.Model); 1435 C.ModelConfig.Tdnn.Model := PAnsiChar(Config.ModelConfig.Tdnn.Model);
1409 1436
1410 -  
1411 C.ModelConfig.Tokens := PAnsiChar(Config.ModelConfig.Tokens); 1437 C.ModelConfig.Tokens := PAnsiChar(Config.ModelConfig.Tokens);
1412 C.ModelConfig.NumThreads := Config.ModelConfig.NumThreads; 1438 C.ModelConfig.NumThreads := Config.ModelConfig.NumThreads;
1413 C.ModelConfig.Debug := Ord(Config.ModelConfig.Debug); 1439 C.ModelConfig.Debug := Ord(Config.ModelConfig.Debug);
@@ -1421,6 +1447,11 @@ begin @@ -1421,6 +1447,11 @@ begin
1421 C.ModelConfig.SenseVoice.Language := PAnsiChar(Config.ModelConfig.SenseVoice.Language); 1447 C.ModelConfig.SenseVoice.Language := PAnsiChar(Config.ModelConfig.SenseVoice.Language);
1422 C.ModelConfig.SenseVoice.UseItn := Ord(Config.ModelConfig.SenseVoice.UseItn); 1448 C.ModelConfig.SenseVoice.UseItn := Ord(Config.ModelConfig.SenseVoice.UseItn);
1423 1449
  1450 + C.ModelConfig.Moonshine.Preprocessor := PAnsiChar(Config.ModelConfig.Moonshine.Preprocessor);
  1451 + C.ModelConfig.Moonshine.Encoder := PAnsiChar(Config.ModelConfig.Moonshine.Encoder);
  1452 + C.ModelConfig.Moonshine.UncachedDecoder := PAnsiChar(Config.ModelConfig.Moonshine.UncachedDecoder);
  1453 + C.ModelConfig.Moonshine.CachedDecoder := PAnsiChar(Config.ModelConfig.Moonshine.CachedDecoder);
  1454 +
1424 C.LMConfig.Model := PAnsiChar(Config.LMConfig.Model); 1455 C.LMConfig.Model := PAnsiChar(Config.LMConfig.Model);
1425 C.LMConfig.Scale := Config.LMConfig.Scale; 1456 C.LMConfig.Scale := Config.LMConfig.Scale;
1426 1457