test.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright (c) 2023 Xiaomi Corporation (authors: Fangjun Kuang)
  2. //
  3. const fs = require('fs');
  4. const {Readable} = require('stream');
  5. const wav = require('wav');
  6. sherpa_ncnn = require('./index.js')
  7. const featConfig = new sherpa_ncnn.FeatureConfig();
  8. featConfig.sampleRate = 16000;
  9. featConfig.featureDim = 80;
  10. const decoderConfig = new sherpa_ncnn.DecoderConfig();
  11. decoderConfig.decodingMethod = 'greedy_search';
  12. decoderConfig.numActivePaths = 4;
  13. const modelConfig = new sherpa_ncnn.ModelConfig();
  14. modelConfig.encoderParam =
  15. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param';
  16. modelConfig.encoderBin =
  17. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin';
  18. modelConfig.decoderParam =
  19. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param';
  20. modelConfig.decoderBin =
  21. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin';
  22. modelConfig.joinerParam =
  23. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param';
  24. modelConfig.joinerBin =
  25. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin';
  26. modelConfig.tokens =
  27. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt';
  28. modelConfig.useVulkanCompute = 0;
  29. modelConfig.numThreads = 1;
  30. const recognizerConfig = new sherpa_ncnn.RecognizerConfig();
  31. recognizerConfig.featConfig = featConfig;
  32. recognizerConfig.modelConfig = modelConfig;
  33. recognizerConfig.decoderConfig = decoderConfig;
  34. const recognizer = new sherpa_ncnn.Recognizer(recognizerConfig);
  35. const waveFilename =
  36. './sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/2.wav'
  37. const reader = new wav.Reader();
  38. const readable = new Readable().wrap(reader);
  39. function decode(samples) {
  40. recognizer.acceptWaveform(recognizerConfig.featConfig.sampleRate, samples);
  41. while (recognizer.isReady()) {
  42. recognizer.decode();
  43. }
  44. const text = recognizer.getResult();
  45. console.log(text);
  46. }
  47. reader.on('format', ({audioFormat, sampleRate, channels, bitDepth}) => {
  48. if (audioFormat != 1) {
  49. throw new Error(`Only support PCM format. Given ${audioFormat}`);
  50. }
  51. if (channels != 1) {
  52. throw new Error(`Only a single channel. Given ${channel}`);
  53. }
  54. if (bitDepth != 16) {
  55. throw new Error(`Only support 16-bit samples. Given ${bitDepth}`);
  56. }
  57. });
  58. fs.createReadStream(waveFilename, {'highWaterMark': 4096})
  59. .pipe(reader)
  60. .on('finish', function(err) {
  61. // tail padding
  62. const floatSamples =
  63. new Float32Array(recognizerConfig.featConfig.sampleRate * 0.5);
  64. decode(floatSamples);
  65. recognizer.free()
  66. });
  67. readable.on('readable', function() {
  68. let chunk;
  69. while ((chunk = readable.read()) != null) {
  70. const int16Samples = new Int16Array(
  71. chunk.buffer, chunk.byteOffset,
  72. chunk.length / Int16Array.BYTES_PER_ELEMENT);
  73. let floatSamples = new Float32Array(int16Samples.length);
  74. for (let i = 0; i < floatSamples.length; i++) {
  75. floatSamples[i] = int16Samples[i] / 32768.0;
  76. }
  77. decode(floatSamples);
  78. }
  79. });