+# sherpa
-[](https://k2-fsa.github.io/sherpa/)
-**Documentation**:
+`sherpa` is an open-source speech-text-text inference framework using
+PyTorch, focusing **exclusively** on end-to-end (E2E) models,
+namely transducer- and CTC-based models. It provides both C++ and Python APIs.
-Try `sherpa` from within your browser without installing anything:
-
-
-See for more details.
-
-## Introduction
-
-An ASR server framework in **Python**, supporting both streaming
-and non-streaming recognition.
-
-CPU-bound tasks, such as neural network computation, are implemented in
-C++; while IO-bound tasks, such as socket communication, are implemented
-in Python.
-
-**Caution**: For offline ASR, we assume the model is trained using pruned
-stateless RNN-T from [icefall][icefall] and it is from a directory like
-`pruned_transducer_statelessX` where `X` >=2. For streaming ASR, we
-assume the model is using `pruned_stateless_emformer_rnnt2`.
-
-For the offline ASR, we provide a Colab notebook, containing how to start the
-server, how to start the client, and how to decode `test-clean` of LibriSpeech.
-
-[](https://colab.research.google.com/drive/1JX5Ph2onYm1ZjNP_94eGqZ-DIRMLlIca?usp=sharing)
-
-For the streaming ASR, we provide a YouTube demo, showing you how to use it.
-See
-
-## Installation
-
-Please refer to
-
-for installation.
-
-## Usage
-
-First, check that `sherpa` has been installed successfully:
-
-```bash
-python3 -c "import sherpa; print(sherpa.__version__)"
-```
-
-It should print the version of `sherpa`.
-
-Visit
-
-to see more tutorials of `sherpa`.
-
-#### Streaming ASR with pruned stateless Emformer RNN-T
-
-#### Start the server
-
-To start the server, you need to first generate two files:
-
-- (1) The torch script model file. You can use `export.py --jit=1` in
-`pruned_stateless_emformer_rnnt2` from [icefall][icefall].
-
-- (2) The BPE model file. You can find it in `data/lang_bpe_XXX/bpe.model`
-in [icefall][icefall], where `XXX` is the number of BPE tokens used in
-the training.
-
-With the above two files ready, you can start the server with the
-following command:
-
-```bash
-./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_server.py \
- --port 6006 \
- --max-batch-size 50 \
- --max-wait-ms 5 \
- --max-active-connections 500 \
- --nn-pool-size 1 \
- --nn-model-filename ./path/to/exp/cpu_jit.pt \
- --bpe-model-filename ./path/to/data/lang_bpe_500/bpe.model
-```
-
-You can use `./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_server.py --help`
-to view the help message.
-
-**Hint**: You can use the environment variable `CUDA_VISIBLE_DEVICES` to control
-which GPU is used. For instance, to use GPU 3 in the server, just set
-`export CUDA_VISIBLE_DEVICES="3"` before starting the server.
-
-**Note**: To keep the server from OOM error, please tune `--max-batch-size`
-and `--max-active-connections`.
-
-We provide a pretrained model using the LibriSpeech dataset at
-
-
-The following shows how to use the above pretrained model to start the server.
-
-```bash
-git lfs install
-git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01
-
-./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_server.py \
- --port 6006 \
- --max-batch-size 50 \
- --max-wait-ms 5 \
- --nn-pool-size 1 \
- --nn-model-filename ./icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01/exp/cpu_jit-epoch-39-avg-6-use-averaged-model-1.pt \
- --bpe-model-filename ./icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01/data/lang_bpe_500/bpe.model
-```
-Here, before running the web client, you need to map your server ports to your local ports in the server terminal firstly with the following command:
-```
-ssh -R 6006:localhost:6006 -R 6008:localhost:6008 your_local_username@your_local_ip
-```
-**Note**:
-(1) You only need to do this if the asr server is running on a machine different from the client.
-(2) The command is run in the terminal on the server machine.
-#### Start the client
-
-We provide two clients at present:
-
- - (1) [./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_client.py](./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_client.py)
- It shows how to decode a single sound file.
-
- - (2) [./sherpa/bin/pruned_stateless_emformer_rnnt2/web](./sherpa/bin/pruned_stateless_emformer_rnnt2/web)
- You can record your speech in real-time within a browser and send it to the server for recognition.
-
-##### streaming_client.py
-
-```bash
-./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_client.py --help
-
-./sherpa/bin/pruned_stateless_emformer_rnnt2/streaming_client.py \
- --server-addr localhost \
- --server-port 6006 \
- ./icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01/test_wavs/1221-135766-0001.wav
-```
-
-##### Web client
-
-```bash
-cd ./sherpa/bin/web
-python3 -m http.server 6008
-```
-
-Then open your browser and go to `http://localhost:6008/record.html`. You will
-see a UI like the following screenshot.
-
-
-
-Click the button `Record`.
+This project focuses on deployment, i.e., using pre-trained models to
+transcribe speech. If you are interested in how to train or fine-tune your own
+models, please refer to [icefall][icefall].
-Now you can `speak` and you will get recognition results from the
-server in real-time.
+We also have other **similar** projects that don't depend on PyTorch:
-**Caution**: For the web client, we hard-code the server port to `6006`.
-You can change the file [./sherpa/bin/web/record.js](./sherpa/bin/web/record.js)
-to replace `6006` in it to whatever port the server is using.
+ - [sherpa-onnx][sherpa-onnx]
+ - [sherpa-ncnn][sherpa-ncnn]
-**Caution**: `http://0.0.0.0:6008/record.html` or `http://127.0.0.1:6008/record.html`
-won't work. You have to use `localhost`. Otherwise, you won't be able to use
-your microphone in your browser since we are not using `https` which requires
-a certificate.
+> `sherpa-onnx` and `sherpa-ncnn` also support iOS, Android and embedded systems.
-### Offline ASR
+## Installation and Usage
-#### Start the server
+Please refer to the **documentation** at
-To start the server, you need to first generate two files:
+## Try it in your browser
-- (1) The torch script model file. You can use `export.py --jit=1` in
-`pruned_transducer_statelessX` from [icefall][icefall].
-
-- (2) The BPE model file. You can find it in `data/lang_bpe_XXX/bpe.model`
-in [icefall][icefall], where `XXX` is the number of BPE tokens used in
-the training. If you use a dataset like aishell to train your model where
-the modeling unit is Chinese characters, you need to provide a `tokens.txt`
-file which can be found in `data/lang_char/tokens.txt` in [icefall][icefall].
-
-With the above two files ready, you can start the server with the
-following command:
-
-```bash
-# If you provide a bpe.model, e.g., for LibriSpeech,
-# you can use the following command:
-#
-sherpa/bin/pruned_transducer_statelessX/offline_server.py \
- --port 6006 \
- --num-device 1 \
- --max-batch-size 10 \
- --max-wait-ms 5 \
- --max-active-connections 500 \
- --feature-extractor-pool-size 5 \
- --nn-pool-size 1 \
- --nn-model-filename ./path/to/exp/cpu_jit.pt \
- --bpe-model-filename ./path/to/data/lang_bpe_500/bpe.model
-```
-
-```bash
-# If you provide a tokens.txt, e.g., for aishell,
-# you can use the following command:
-#
-sherpa/bin/pruned_transducer_statelessX/offline_server.py \
- --port 6006 \
- --num-device 1 \
- --max-batch-size 10 \
- --max-wait-ms 5 \
- --max-active-connections 500 \
- --feature-extractor-pool-size 5 \
- --nn-pool-size 1 \
- --nn-model-filename ./path/to/exp/cpu_jit.pt \
- --token-filename ./path/to/data/lang_char/tokens.txt
-```
-
-You can use `./sherpa/bin/pruned_transducer_statelessX/offline_server.py --help` to view the help message.
-
-**HINT**: If you don't have GPU, please set `--num-device` to `0`.
-
-**Caution**: To keep the server from out-of-memory error, you can tune
-`--max-batch-size` and `--max-active-connections`.
-
-We provide pretrained models for the following two datasets:
-
-- (1) LibriSpeech:
- It uses a BPE model with vocabulary size 500.
-
-- (2) aishell:
- It uses Chinese characters as models units. The vocabulary size is 4336.
-
-The following shows how to use the above pretrained models to start the server.
-
-- **Use the pretrained model trained with the Librispeech dataset**
-
-```bash
-git lfs install
-git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13
-
-sherpa/bin/pruned_transducer_statelessX/offline_server.py \
- --port 6006 \
- --num-device 1 \
- --max-batch-size 10 \
- --max-wait-ms 5 \
- --max-active-connections 500 \
- --feature-extractor-pool-size 5 \
- --nn-pool-size 1 \
- --nn-model-filename ./icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13/exp/cpu_jit.pt \
- --bpe-model-filename ./icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13/data/lang_bpe_500/bpe.model
-```
-
-- **For the pretrained model trained with the aishell dataset**
-
-```bash
-git lfs install
-git clone https://huggingface.co/csukuangfj/icefall-aishell-pruned-transducer-stateless3-2022-06-20
-
-sherpa/bin/pruned_transducer_statelessX/offline_server.py \
- --port 6006 \
- --num-device 1 \
- --max-batch-size 10 \
- --max-wait-ms 5 \
- --max-active-connections 500 \
- --feature-extractor-pool-size 5 \
- --nn-pool-size 1 \
- --nn-model-filename ./icefall-aishell-pruned-transducer-stateless3-2022-06-20/exp/cpu_jit-epoch-29-avg-5-torch-1.6.0.pt \
- --token-filename ./icefall-aishell-pruned-transducer-stateless3-2022-06-20/data/lang_char/tokens.txt
-```
-
-#### Start the client
-After starting the server, you can use the following command to start the client:
-
-```bash
-./sherpa/bin/pruned_transducer_statelessX/offline_client.py \
- --server-addr localhost \
- --server-port 6006 \
- /path/to/foo.wav \
- /path/to/bar.wav
-```
-
-You can use `./sherpa/bin/pruned_transducer_statelessX/offline_client.py --help` to view the usage message.
-
-The following shows how to use the client to send some test waves to the server
-for recognition.
-
-```bash
-# If you use the pretrained model from the LibriSpeech dataset
-sherpa/bin/pruned_transducer_statelessX/offline_client.py \
- --server-addr localhost \
- --server-port 6006 \
- icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13//test_wavs/1089-134686-0001.wav \
- icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13//test_wavs/1221-135766-0001.wav \
- icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13//test_wavs/1221-135766-0002.wav
-```
-
-```bash
-# If you use the pretrained model from the aishell dataset
-sherpa/bin/pruned_transducer_statelessX/offline_client.py \
- --server-addr localhost \
- --server-port 6006 \
- ./icefall-aishell-pruned-transducer-stateless3-2022-06-20/test_wavs/BAC009S0764W0121.wav \
- ./icefall-aishell-pruned-transducer-stateless3-2022-06-20/test_wavs/BAC009S0764W0122.wav \
- ./icefall-aishell-pruned-transducer-stateless3-2022-06-20/test_wavs/BAC009S0764W0123.wav
-```
-
-#### RTF test
-
-We provide a demo [./sherpa/bin/pruned_transducer_statelessX/decode_manifest.py](./sherpa/bin/pruned_transducer_statelessX/decode_manifest.py)
-to decode the `test-clean` dataset from the LibriSpeech corpus.
-
-It creates 50 connections to the server using websockets and sends audio files
-to the server for recognition.
-
-At the end, it will display the RTF and the WER.
-
-To give you an idea of the performance of the pretrained model,
-the Colab notebook
-[](https://colab.research.google.com/drive/1JX5Ph2onYm1ZjNP_94eGqZ-DIRMLlIca?usp=sharing)
-shows the following results:
-
-```
-RTF: 0.0094
-total_duration: 19452.481 seconds (5.40 hours)
-processing time: 183.305 seconds (0.05 hours)
-%WER = 2.06
-
-Errors: 112 insertions, 93 deletions, 876 substitutions, over 52576 reference words (51607 correct)
-```
-
-If you have a GPU with a larger RAM (e.g., 32 GB), you can get an even **lower** RTF.
-
-[icefall]: https://github.com/k2-fsa/icefall/
-
-
-### Contributing
-
-Contributions to `sherpa` are very welcomed. There are many possible ways to make contributions
-and two of them are:
-- To write documentation
-- To write code:
- - To follow the code style in the repository
- - To write a new features (support new architectures, new beam search, etc)
-
-### Follow the code style
-
-We use the following tools to make the code style to be as consistent as possible:
-
- - [black](https://github.com/psf/black), to format the code
- - [flake8](https://github.com/PyCQA/flake8), to check the style and quality of the code
- - [isort](https://github.com/PyCQA/isort), to sort ``imports``
-
-After running the following commands:
-
- $ git clone https://github.com/k2-fsa/sherpa
- $ cd sherpa
- $ pip install pre-commit
- $ pre-commit install
+Try `sherpa` from within your browser without installing anything:
+
-it will run the checks whenever you run ``git commit`` **automatically**
+[icefall]: https://github.com/k2-fsa/icefall
+[sherpa-onnx]: https://github.com/k2-fsa/sherpa-onnx
+[sherpa-ncnn]: https://github.com/k2-fsa/sherpa-ncnn
diff --git a/sherpa/bin/pruned_transducer_statelessX/__init__.py b/__init__.py
similarity index 100%
rename from sherpa/bin/pruned_transducer_statelessX/__init__.py
rename to __init__.py
diff --git a/cmake/Modules/FetchContent.cmake b/cmake/Modules/FetchContent.cmake
deleted file mode 100644
index 98cdf6cb9..000000000
--- a/cmake/Modules/FetchContent.cmake
+++ /dev/null
@@ -1,916 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#[=======================================================================[.rst:
-FetchContent
-------------------
-
-.. only:: html
-
- .. contents::
-
-Overview
-^^^^^^^^
-
-This module enables populating content at configure time via any method
-supported by the :module:`ExternalProject` module. Whereas
-:command:`ExternalProject_Add` downloads at build time, the
-``FetchContent`` module makes content available immediately, allowing the
-configure step to use the content in commands like :command:`add_subdirectory`,
-:command:`include` or :command:`file` operations.
-
-Content population details would normally be defined separately from the
-command that performs the actual population. Projects should also
-check whether the content has already been populated somewhere else in the
-project hierarchy. Typical usage would look something like this:
-
-.. code-block:: cmake
-
- FetchContent_Declare(
- googletest
- GIT_REPOSITORY https://github.com/google/googletest.git
- GIT_TAG release-1.8.0
- )
-
- FetchContent_GetProperties(googletest)
- if(NOT googletest_POPULATED)
- FetchContent_Populate(googletest)
- add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
- endif()
-
-When using the above pattern with a hierarchical project arrangement,
-projects at higher levels in the hierarchy are able to define or override
-the population details of content specified anywhere lower in the project
-hierarchy. The ability to detect whether content has already been
-populated ensures that even if multiple child projects want certain content
-to be available, the first one to populate it wins. The other child project
-can simply make use of the already available content instead of repeating
-the population for itself. See the
-:ref:`Examples ` section which demonstrates
-this scenario.
-
-The ``FetchContent`` module also supports defining and populating
-content in a single call, with no check for whether the content has been
-populated elsewhere in the project already. This is a more low level
-operation and would not normally be the way the module is used, but it is
-sometimes useful as part of implementing some higher level feature or to
-populate some content in CMake's script mode.
-
-
-Declaring Content Details
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. command:: FetchContent_Declare
-
- .. code-block:: cmake
-
- FetchContent_Declare(...)
-
- The ``FetchContent_Declare()`` function records the options that describe
- how to populate the specified content, but if such details have already
- been recorded earlier in this project (regardless of where in the project
- hierarchy), this and all later calls for the same content ```` are
- ignored. This "first to record, wins" approach is what allows hierarchical
- projects to have parent projects override content details of child projects.
-
- The content ```` can be any string without spaces, but good practice
- would be to use only letters, numbers and underscores. The name will be
- treated case-insensitively and it should be obvious for the content it
- represents, often being the name of the child project or the value given
- to its top level :command:`project` command (if it is a CMake project).
- For well-known public projects, the name should generally be the official
- name of the project. Choosing an unusual name makes it unlikely that other
- projects needing that same content will use the same name, leading to
- the content being populated multiple times.
-
- The ```` can be any of the download or update/patch options
- that the :command:`ExternalProject_Add` command understands. The configure,
- build, install and test steps are explicitly disabled and therefore options
- related to them will be ignored. In most cases, ```` will
- just be a couple of options defining the download method and method-specific
- details like a commit tag or archive hash. For example:
-
- .. code-block:: cmake
-
- FetchContent_Declare(
- googletest
- GIT_REPOSITORY https://github.com/google/googletest.git
- GIT_TAG release-1.8.0
- )
-
- FetchContent_Declare(
- myCompanyIcons
- URL https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
- URL_HASH 5588a7b18261c20068beabfb4f530b87
- )
-
- FetchContent_Declare(
- myCompanyCertificates
- SVN_REPOSITORY svn+ssh://svn.mycompany.com/srv/svn/trunk/certs
- SVN_REVISION -r12345
- )
-
-Populating The Content
-^^^^^^^^^^^^^^^^^^^^^^
-
-.. command:: FetchContent_Populate
-
- .. code-block:: cmake
-
- FetchContent_Populate( )
-
- In most cases, the only argument given to ``FetchContent_Populate()`` is the
- ````. When used this way, the command assumes the content details have
- been recorded by an earlier call to :command:`FetchContent_Declare`. The
- details are stored in a global property, so they are unaffected by things
- like variable or directory scope. Therefore, it doesn't matter where in the
- project the details were previously declared, as long as they have been
- declared before the call to ``FetchContent_Populate()``. Those saved details
- are then used to construct a call to :command:`ExternalProject_Add` in a
- private sub-build to perform the content population immediately. The
- implementation of ``ExternalProject_Add()`` ensures that if the content has
- already been populated in a previous CMake run, that content will be reused
- rather than repopulating them again. For the common case where population
- involves downloading content, the cost of the download is only paid once.
-
- An internal global property records when a particular content population
- request has been processed. If ``FetchContent_Populate()`` is called more
- than once for the same content name within a configure run, the second call
- will halt with an error. Projects can and should check whether content
- population has already been processed with the
- :command:`FetchContent_GetProperties` command before calling
- ``FetchContent_Populate()``.
-
- ``FetchContent_Populate()`` will set three variables in the scope of the
- caller; ``_POPULATED``, ``_SOURCE_DIR`` and
- ``_BINARY_DIR``, where ```` is the lowercased ````.
- ``_POPULATED`` will always be set to ``True`` by the call.
- ``_SOURCE_DIR`` is the location where the
- content can be found upon return (it will have already been populated), while
- ``_BINARY_DIR`` is a directory intended for use as a corresponding
- build directory. The main use case for the two directory variables is to
- call :command:`add_subdirectory` immediately after population, i.e.:
-
- .. code-block:: cmake
-
- FetchContent_Populate(FooBar ...)
- add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})
-
- The values of the three variables can also be retrieved from anywhere in the
- project hierarchy using the :command:`FetchContent_GetProperties` command.
-
- A number of cache variables influence the behavior of all content population
- performed using details saved from a :command:`FetchContent_Declare` call:
-
- ``FETCHCONTENT_BASE_DIR``
- In most cases, the saved details do not specify any options relating to the
- directories to use for the internal sub-build, final source and build areas.
- It is generally best to leave these decisions up to the ``FetchContent``
- module to handle on the project's behalf. The ``FETCHCONTENT_BASE_DIR``
- cache variable controls the point under which all content population
- directories are collected, but in most cases developers would not need to
- change this. The default location is ``${CMAKE_BINARY_DIR}/_deps``, but if
- developers change this value, they should aim to keep the path short and
- just below the top level of the build tree to avoid running into path
- length problems on Windows.
-
- ``FETCHCONTENT_QUIET``
- The logging output during population can be quite verbose, making the
- configure stage quite noisy. This cache option (``ON`` by default) hides
- all population output unless an error is encountered. If experiencing
- problems with hung downloads, temporarily switching this option off may
- help diagnose which content population is causing the issue.
-
- ``FETCHCONTENT_FULLY_DISCONNECTED``
- When this option is enabled, no attempt is made to download or update
- any content. It is assumed that all content has already been populated in
- a previous run or the source directories have been pointed at existing
- contents the developer has provided manually (using options described
- further below). When the developer knows that no changes have been made to
- any content details, turning this option ``ON`` can significantly speed up
- the configure stage. It is ``OFF`` by default.
-
- ``FETCHCONTENT_UPDATES_DISCONNECTED``
- This is a less severe download/update control compared to
- ``FETCHCONTENT_FULLY_DISCONNECTED``. Instead of bypassing all download and
- update logic, the ``FETCHCONTENT_UPDATES_DISCONNECTED`` only disables the
- update stage. Therefore, if content has not been downloaded previously,
- it will still be downloaded when this option is enabled. This can speed up
- the configure stage, but not as much as
- ``FETCHCONTENT_FULLY_DISCONNECTED``. It is ``OFF`` by default.
-
- In addition to the above cache variables, the following cache variables are
- also defined for each content name (```` is the uppercased value of
- ````):
-
- ``FETCHCONTENT_SOURCE_DIR_``
- If this is set, no download or update steps are performed for the specified
- content and the ``_SOURCE_DIR`` variable returned to the caller is
- pointed at this location. This gives developers a way to have a separate
- checkout of the content that they can modify freely without interference
- from the build. The build simply uses that existing source, but it still
- defines ``_BINARY_DIR`` to point inside its own build area.
- Developers are strongly encouraged to use this mechanism rather than
- editing the sources populated in the default location, as changes to
- sources in the default location can be lost when content population details
- are changed by the project.
-
- ``FETCHCONTENT_UPDATES_DISCONNECTED_``
- This is the per-content equivalent of
- ``FETCHCONTENT_UPDATES_DISCONNECTED``. If the global option or this option
- is ``ON``, then updates will be disabled for the named content.
- Disabling updates for individual content can be useful for content whose
- details rarely change, while still leaving other frequently changing
- content with updates enabled.
-
-
- The ``FetchContent_Populate()`` command also supports a syntax allowing the
- content details to be specified directly rather than using any saved
- details. This is more low-level and use of this form is generally to be
- avoided in favour of using saved content details as outlined above.
- Nevertheless, in certain situations it can be useful to invoke the content
- population as an isolated operation (typically as part of implementing some
- other higher level feature or when using CMake in script mode):
-
- .. code-block:: cmake
-
- FetchContent_Populate(
- [QUIET]
- [SUBBUILD_DIR ]
- [SOURCE_DIR ]
- [BINARY_DIR ]
- ...
- )
-
- This form has a number of key differences to that where only ```` is
- provided:
-
- - All required population details are assumed to have been provided directly
- in the call to ``FetchContent_Populate()``. Any saved details for
- ```` are ignored.
- - No check is made for whether content for ```` has already been
- populated.
- - No global property is set to record that the population has occurred.
- - No global properties record the source or binary directories used for the
- populated content.
- - The ``FETCHCONTENT_FULLY_DISCONNECTED`` and
- ``FETCHCONTENT_UPDATES_DISCONNECTED`` cache variables are ignored.
-
- The ``_SOURCE_DIR`` and ``_BINARY_DIR`` variables are still
- returned to the caller, but since these locations are not stored as global
- properties when this form is used, they are only available to the calling
- scope and below rather than the entire project hierarchy. No
- ``_POPULATED`` variable is set in the caller's scope with this form.
-
- The supported options for ``FetchContent_Populate()`` are the same as those
- for :command:`FetchContent_Declare()`. Those few options shown just
- above are either specific to ``FetchContent_Populate()`` or their behavior is
- slightly modified from how :command:`ExternalProject_Add` treats them.
-
- ``QUIET``
- The ``QUIET`` option can be given to hide the output associated with
- populating the specified content. If the population fails, the output will
- be shown regardless of whether this option was given or not so that the
- cause of the failure can be diagnosed. The global ``FETCHCONTENT_QUIET``
- cache variable has no effect on ``FetchContent_Populate()`` calls where the
- content details are provided directly.
-
- ``SUBBUILD_DIR``
- The ``SUBBUILD_DIR`` argument can be provided to change the location of the
- sub-build created to perform the population. The default value is
- ``${CMAKE_CURRENT_BINARY_DIR}/-subbuild`` and it would be unusual
- to need to override this default. If a relative path is specified, it will
- be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
-
- ``SOURCE_DIR``, ``BINARY_DIR``
- The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by
- :command:`ExternalProject_Add`, but different default values are used by
- ``FetchContent_Populate()``. ``SOURCE_DIR`` defaults to
- ``${CMAKE_CURRENT_BINARY_DIR}/-src`` and ``BINARY_DIR`` defaults to
- ``${CMAKE_CURRENT_BINARY_DIR}/-build``. If a relative path is
- specified, it will be interpreted as relative to
- :variable:`CMAKE_CURRENT_BINARY_DIR`.
-
- In addition to the above explicit options, any other unrecognized options are
- passed through unmodified to :command:`ExternalProject_Add` to perform the
- download, patch and update steps. The following options are explicitly
- prohibited (they are disabled by the ``FetchContent_Populate()`` command):
-
- - ``CONFIGURE_COMMAND``
- - ``BUILD_COMMAND``
- - ``INSTALL_COMMAND``
- - ``TEST_COMMAND``
-
- If using ``FetchContent_Populate()`` within CMake's script mode, be aware
- that the implementation sets up a sub-build which therefore requires a CMake
- generator and build tool to be available. If these cannot be found by
- default, then the :variable:`CMAKE_GENERATOR` and/or
- :variable:`CMAKE_MAKE_PROGRAM` variables will need to be set appropriately
- on the command line invoking the script.
-
-
-Retrieve Population Properties
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. command:: FetchContent_GetProperties
-
- When using saved content details, a call to :command:`FetchContent_Populate`
- records information in global properties which can be queried at any time.
- This information includes the source and binary directories associated with
- the content and also whether or not the content population has been processed
- during the current configure run.
-
- .. code-block:: cmake
-
- FetchContent_GetProperties(
- [SOURCE_DIR ]
- [BINARY_DIR ]
- [POPULATED ]
- )
-
- The ``SOURCE_DIR``, ``BINARY_DIR`` and ``POPULATED`` options can be used to
- specify which properties should be retrieved. Each option accepts a value
- which is the name of the variable in which to store that property. Most of
- the time though, only ```` is given, in which case the call will then
- set the same variables as a call to
- :command:`FetchContent_Populate(name) `. This allows
- the following canonical pattern to be used, which ensures that the relevant
- variables will always be defined regardless of whether or not the population
- has been performed elsewhere in the project already:
-
- .. code-block:: cmake
-
- FetchContent_GetProperties(foobar)
- if(NOT foobar_POPULATED)
- FetchContent_Populate(foobar)
-
- # Set any custom variables, etc. here, then
- # populate the content as part of this build
-
- add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})
- endif()
-
- The above pattern allows other parts of the overall project hierarchy to
- re-use the same content and ensure that it is only populated once.
-
-
-.. _`fetch-content-examples`:
-
-Examples
-^^^^^^^^
-
-Consider a project hierarchy where ``projA`` is the top level project and it
-depends on projects ``projB`` and ``projC``. Both ``projB`` and ``projC``
-can be built standalone and they also both depend on another project
-``projD``. For simplicity, this example will assume that all four projects
-are available on a company git server. The ``CMakeLists.txt`` of each project
-might have sections like the following:
-
-*projA*:
-
-.. code-block:: cmake
-
- include(FetchContent)
- FetchContent_Declare(
- projB
- GIT_REPOSITORY git@mycompany.com/git/projB.git
- GIT_TAG 4a89dc7e24ff212a7b5167bef7ab079d
- )
- FetchContent_Declare(
- projC
- GIT_REPOSITORY git@mycompany.com/git/projC.git
- GIT_TAG 4ad4016bd1d8d5412d135cf8ceea1bb9
- )
- FetchContent_Declare(
- projD
- GIT_REPOSITORY git@mycompany.com/git/projD.git
- GIT_TAG origin/integrationBranch
- )
-
- FetchContent_GetProperties(projB)
- if(NOT projb_POPULATED)
- FetchContent_Populate(projB)
- add_subdirectory(${projb_SOURCE_DIR} ${projb_BINARY_DIR})
- endif()
-
- FetchContent_GetProperties(projC)
- if(NOT projc_POPULATED)
- FetchContent_Populate(projC)
- add_subdirectory(${projc_SOURCE_DIR} ${projc_BINARY_DIR})
- endif()
-
-*projB*:
-
-.. code-block:: cmake
-
- include(FetchContent)
- FetchContent_Declare(
- projD
- GIT_REPOSITORY git@mycompany.com/git/projD.git
- GIT_TAG 20b415f9034bbd2a2e8216e9a5c9e632
- )
-
- FetchContent_GetProperties(projD)
- if(NOT projd_POPULATED)
- FetchContent_Populate(projD)
- add_subdirectory(${projd_SOURCE_DIR} ${projd_BINARY_DIR})
- endif()
-
-
-*projC*:
-
-.. code-block:: cmake
-
- include(FetchContent)
- FetchContent_Declare(
- projD
- GIT_REPOSITORY git@mycompany.com/git/projD.git
- GIT_TAG 7d9a17ad2c962aa13e2fbb8043fb6b8a
- )
-
- FetchContent_GetProperties(projD)
- if(NOT projd_POPULATED)
- FetchContent_Populate(projD)
- add_subdirectory(${projd_SOURCE_DIR} ${projd_BINARY_DIR})
- endif()
-
-A few key points should be noted in the above:
-
-- ``projB`` and ``projC`` define different content details for ``projD``,
- but ``projA`` also defines a set of content details for ``projD`` and
- because ``projA`` will define them first, the details from ``projB`` and
- ``projC`` will not be used. The override details defined by ``projA``
- are not required to match either of those from ``projB`` or ``projC``, but
- it is up to the higher level project to ensure that the details it does
- define still make sense for the child projects.
-- While ``projA`` defined content details for ``projD``, it did not need
- to explicitly call ``FetchContent_Populate(projD)`` itself. Instead, it
- leaves that to a child project to do (in this case it will be ``projB``
- since it is added to the build ahead of ``projC``). If ``projA`` needed to
- customize how the ``projD`` content was brought into the build as well
- (e.g. define some CMake variables before calling
- :command:`add_subdirectory` after populating), it would do the call to
- ``FetchContent_Populate()``, etc. just as it did for the ``projB`` and
- ``projC`` content. For higher level projects, it is usually enough to
- just define the override content details and leave the actual population
- to the child projects. This saves repeating the same thing at each level
- of the project hierarchy unnecessarily.
-- Even though ``projA`` is the top level project in this example, it still
- checks whether ``projB`` and ``projC`` have already been populated before
- going ahead to do those populations. This makes ``projA`` able to be more
- easily incorporated as a child of some other higher level project in the
- future if required. Always protect a call to
- :command:`FetchContent_Populate` with a check to
- :command:`FetchContent_GetProperties`, even in what may be considered a top
- level project at the time.
-
-
-The following example demonstrates how one might download and unpack a
-firmware tarball using CMake's :manual:`script mode `. The call to
-:command:`FetchContent_Populate` specifies all the content details and the
-unpacked firmware will be placed in a ``firmware`` directory below the
-current working directory.
-
-*getFirmware.cmake*:
-
-.. code-block:: cmake
-
- # NOTE: Intended to be run in script mode with cmake -P
- include(FetchContent)
- FetchContent_Populate(
- firmware
- URL https://mycompany.com/assets/firmware-1.23-arm.tar.gz
- URL_HASH MD5=68247684da89b608d466253762b0ff11
- SOURCE_DIR firmware
- )
-
-#]=======================================================================]
-
-
-set(__FetchContent_privateDir "${CMAKE_CURRENT_LIST_DIR}/FetchContent")
-
-#=======================================================================
-# Recording and retrieving content details for later population
-#=======================================================================
-
-# Internal use, projects must not call this directly. It is
-# intended for use by FetchContent_Declare() only.
-#
-# Sets a content-specific global property (not meant for use
-# outside of functions defined here in this file) which can later
-# be retrieved using __FetchContent_getSavedDetails() with just the
-# same content name. If there is already a value stored in the
-# property, it is left unchanged and this call has no effect.
-# This allows parent projects to define the content details,
-# overriding anything a child project may try to set (properties
-# are not cached between runs, so the first thing to set it in a
-# build will be in control).
-function(__FetchContent_declareDetails contentName)
-
- string(TOLOWER ${contentName} contentNameLower)
- set(propertyName "_FetchContent_${contentNameLower}_savedDetails")
- get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
- if(NOT alreadyDefined)
- define_property(GLOBAL PROPERTY ${propertyName}
- BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
- FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}"
- )
- set_property(GLOBAL PROPERTY ${propertyName} ${ARGN})
- endif()
-
-endfunction()
-
-
-# Internal use, projects must not call this directly. It is
-# intended for use by the FetchContent_Declare() function.
-#
-# Retrieves details saved for the specified content in an
-# earlier call to __FetchContent_declareDetails().
-function(__FetchContent_getSavedDetails contentName outVar)
-
- string(TOLOWER ${contentName} contentNameLower)
- set(propertyName "_FetchContent_${contentNameLower}_savedDetails")
- get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
- if(NOT alreadyDefined)
- message(FATAL_ERROR "No content details recorded for ${contentName}")
- endif()
- get_property(propertyValue GLOBAL PROPERTY ${propertyName})
- set(${outVar} "${propertyValue}" PARENT_SCOPE)
-
-endfunction()
-
-
-# Saves population details of the content, sets defaults for the
-# SOURCE_DIR and BUILD_DIR.
-function(FetchContent_Declare contentName)
-
- set(options "")
- set(oneValueArgs SVN_REPOSITORY)
- set(multiValueArgs "")
-
- cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- unset(srcDirSuffix)
- unset(svnRepoArgs)
- if(ARG_SVN_REPOSITORY)
- # Add a hash of the svn repository URL to the source dir. This works
- # around the problem where if the URL changes, the download would
- # fail because it tries to checkout/update rather than switch the
- # old URL to the new one. We limit the hash to the first 7 characters
- # so that the source path doesn't get overly long (which can be a
- # problem on windows due to path length limits).
- string(SHA1 urlSHA ${ARG_SVN_REPOSITORY})
- string(SUBSTRING ${urlSHA} 0 7 urlSHA)
- set(srcDirSuffix "-${urlSHA}")
- set(svnRepoArgs SVN_REPOSITORY ${ARG_SVN_REPOSITORY})
- endif()
-
- string(TOLOWER ${contentName} contentNameLower)
- __FetchContent_declareDetails(
- ${contentNameLower}
- SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}"
- BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build"
- ${svnRepoArgs}
- # List these last so they can override things we set above
- ${ARG_UNPARSED_ARGUMENTS}
- )
-
-endfunction()
-
-
-#=======================================================================
-# Set/get whether the specified content has been populated yet.
-# The setter also records the source and binary dirs used.
-#=======================================================================
-
-# Internal use, projects must not call this directly. It is
-# intended for use by the FetchContent_Populate() function to
-# record when FetchContent_Populate() is called for a particular
-# content name.
-function(__FetchContent_setPopulated contentName sourceDir binaryDir)
-
- string(TOLOWER ${contentName} contentNameLower)
- set(prefix "_FetchContent_${contentNameLower}")
-
- set(propertyName "${prefix}_sourceDir")
- define_property(GLOBAL PROPERTY ${propertyName}
- BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
- FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}"
- )
- set_property(GLOBAL PROPERTY ${propertyName} ${sourceDir})
-
- set(propertyName "${prefix}_binaryDir")
- define_property(GLOBAL PROPERTY ${propertyName}
- BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
- FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}"
- )
- set_property(GLOBAL PROPERTY ${propertyName} ${binaryDir})
-
- set(propertyName "${prefix}_populated")
- define_property(GLOBAL PROPERTY ${propertyName}
- BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
- FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}"
- )
- set_property(GLOBAL PROPERTY ${propertyName} True)
-
-endfunction()
-
-
-# Set variables in the calling scope for any of the retrievable
-# properties. If no specific properties are requested, variables
-# will be set for all retrievable properties.
-#
-# This function is intended to also be used by projects as the canonical
-# way to detect whether they should call FetchContent_Populate()
-# and pull the populated source into the build with add_subdirectory(),
-# if they are using the populated content in that way.
-function(FetchContent_GetProperties contentName)
-
- string(TOLOWER ${contentName} contentNameLower)
-
- set(options "")
- set(oneValueArgs SOURCE_DIR BINARY_DIR POPULATED)
- set(multiValueArgs "")
-
- cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- if(NOT ARG_SOURCE_DIR AND
- NOT ARG_BINARY_DIR AND
- NOT ARG_POPULATED)
- # No specific properties requested, provide them all
- set(ARG_SOURCE_DIR ${contentNameLower}_SOURCE_DIR)
- set(ARG_BINARY_DIR ${contentNameLower}_BINARY_DIR)
- set(ARG_POPULATED ${contentNameLower}_POPULATED)
- endif()
-
- set(prefix "_FetchContent_${contentNameLower}")
-
- if(ARG_SOURCE_DIR)
- set(propertyName "${prefix}_sourceDir")
- get_property(value GLOBAL PROPERTY ${propertyName})
- if(value)
- set(${ARG_SOURCE_DIR} ${value} PARENT_SCOPE)
- endif()
- endif()
-
- if(ARG_BINARY_DIR)
- set(propertyName "${prefix}_binaryDir")
- get_property(value GLOBAL PROPERTY ${propertyName})
- if(value)
- set(${ARG_BINARY_DIR} ${value} PARENT_SCOPE)
- endif()
- endif()
-
- if(ARG_POPULATED)
- set(propertyName "${prefix}_populated")
- get_property(value GLOBAL PROPERTY ${propertyName} DEFINED)
- set(${ARG_POPULATED} ${value} PARENT_SCOPE)
- endif()
-
-endfunction()
-
-
-#=======================================================================
-# Performing the population
-#=======================================================================
-
-# The value of contentName will always have been lowercased by the caller.
-# All other arguments are assumed to be options that are understood by
-# ExternalProject_Add(), except for QUIET and SUBBUILD_DIR.
-function(__FetchContent_directPopulate contentName)
-
- set(options
- QUIET
- )
- set(oneValueArgs
- SUBBUILD_DIR
- SOURCE_DIR
- BINARY_DIR
- # Prevent the following from being passed through
- CONFIGURE_COMMAND
- BUILD_COMMAND
- INSTALL_COMMAND
- TEST_COMMAND
- )
- set(multiValueArgs "")
-
- cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- if(NOT ARG_SUBBUILD_DIR)
- message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set")
- elseif(NOT IS_ABSOLUTE "${ARG_SUBBUILD_DIR}")
- set(ARG_SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SUBBUILD_DIR}")
- endif()
-
- if(NOT ARG_SOURCE_DIR)
- message(FATAL_ERROR "Internal error: SOURCE_DIR not set")
- elseif(NOT IS_ABSOLUTE "${ARG_SOURCE_DIR}")
- set(ARG_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SOURCE_DIR}")
- endif()
-
- if(NOT ARG_BINARY_DIR)
- message(FATAL_ERROR "Internal error: BINARY_DIR not set")
- elseif(NOT IS_ABSOLUTE "${ARG_BINARY_DIR}")
- set(ARG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY_DIR}")
- endif()
-
- # Ensure the caller can know where to find the source and build directories
- # with some convenient variables. Doing this here ensures the caller sees
- # the correct result in the case where the default values are overridden by
- # the content details set by the project.
- set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
- set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)
-
- # The unparsed arguments may contain spaces, so build up ARG_EXTRA
- # in such a way that it correctly substitutes into the generated
- # CMakeLists.txt file with each argument quoted.
- unset(ARG_EXTRA)
- foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
- set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
- endforeach()
-
- # Hide output if requested, but save it to a variable in case there's an
- # error so we can show the output upon failure. When not quiet, don't
- # capture the output to a variable because the user may want to see the
- # output as it happens (e.g. progress during long downloads). Combine both
- # stdout and stderr in the one capture variable so the output stays in order.
- if (ARG_QUIET)
- set(outputOptions
- OUTPUT_VARIABLE capturedOutput
- ERROR_VARIABLE capturedOutput
- )
- else()
- set(capturedOutput)
- set(outputOptions)
- message(STATUS "Populating ${contentName}")
- endif()
-
- if(CMAKE_GENERATOR)
- set(generatorOpts "-G${CMAKE_GENERATOR}")
- if(CMAKE_GENERATOR_PLATFORM)
- list(APPEND generatorOpts "-A${CMAKE_GENERATOR_PLATFORM}")
- endif()
- if(CMAKE_GENERATOR_TOOLSET)
- list(APPEND generatorOpts "-T${CMAKE_GENERATOR_TOOLSET}")
- endif()
-
- if(CMAKE_MAKE_PROGRAM)
- list(APPEND generatorOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
- endif()
-
- else()
- # Likely we've been invoked via CMake's script mode where no
- # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
- # trusted even if provided). We will have to rely on being
- # able to find the default generator and build tool.
- unset(generatorOpts)
- endif()
-
- # Create and build a separate CMake project to carry out the population.
- # If we've already previously done these steps, they will not cause
- # anything to be updated, so extra rebuilds of the project won't occur.
- # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
- # has this set to something not findable on the PATH.
- configure_file("${__FetchContent_privateDir}/CMakeLists.cmake.in"
- "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
- execute_process(
- COMMAND ${CMAKE_COMMAND} ${generatorOpts} .
- RESULT_VARIABLE result
- ${outputOptions}
- WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
- )
- if(result)
- if(capturedOutput)
- message("${capturedOutput}")
- endif()
- message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
- endif()
- execute_process(
- COMMAND ${CMAKE_COMMAND} --build .
- RESULT_VARIABLE result
- ${outputOptions}
- WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
- )
- if(result)
- if(capturedOutput)
- message("${capturedOutput}")
- endif()
- message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
- endif()
-
-endfunction()
-
-
-option(FETCHCONTENT_FULLY_DISCONNECTED "Disables all attempts to download or update content and assumes source dirs already exist")
-option(FETCHCONTENT_UPDATES_DISCONNECTED "Enables UPDATE_DISCONNECTED behavior for all content population")
-option(FETCHCONTENT_QUIET "Enables QUIET option for all content population" ON)
-set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps" CACHE PATH "Directory under which to collect all populated content")
-
-# Populate the specified content using details stored from
-# an earlier call to FetchContent_Declare().
-function(FetchContent_Populate contentName)
-
- if(NOT contentName)
- message(FATAL_ERROR "Empty contentName not allowed for FetchContent_Populate()")
- endif()
-
- string(TOLOWER ${contentName} contentNameLower)
-
- if(ARGN)
- # This is the direct population form with details fully specified
- # as part of the call, so we already have everything we need
- __FetchContent_directPopulate(
- ${contentNameLower}
- SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-subbuild"
- SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-src"
- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-build"
- ${ARGN} # Could override any of the above ..._DIR variables
- )
-
- # Pass source and binary dir variables back to the caller
- set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
- set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)
-
- # Don't set global properties, or record that we did this population, since
- # this was a direct call outside of the normal declared details form.
- # We only want to save values in the global properties for content that
- # honours the hierarchical details mechanism so that projects are not
- # robbed of the ability to override details set in nested projects.
- return()
- endif()
-
- # No details provided, so assume they were saved from an earlier call
- # to FetchContent_Declare(). Do a check that we haven't already
- # populated this content before in case the caller forgot to check.
- FetchContent_GetProperties(${contentName})
- if(${contentNameLower}_POPULATED)
- message(FATAL_ERROR "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}")
- endif()
-
- string(TOUPPER ${contentName} contentNameUpper)
- set(FETCHCONTENT_SOURCE_DIR_${contentNameUpper}
- "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}"
- CACHE PATH "When not empty, overrides where to find pre-populated content for ${contentName}")
-
- if(FETCHCONTENT_SOURCE_DIR_${contentNameUpper})
- # The source directory has been explicitly provided in the cache,
- # so no population is required
- set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
- set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
-
- elseif(FETCHCONTENT_FULLY_DISCONNECTED)
- # Bypass population and assume source is already there from a previous run
- set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
- set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
-
- else()
- # Support both a global "disconnect all updates" and a per-content
- # update test (either one being set disables updates for this content).
- option(FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper}
- "Enables UPDATE_DISCONNECTED behavior just for population of ${contentName}")
- if(FETCHCONTENT_UPDATES_DISCONNECTED OR
- FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper})
- set(disconnectUpdates True)
- else()
- set(disconnectUpdates False)
- endif()
-
- if(FETCHCONTENT_QUIET)
- set(quietFlag QUIET)
- else()
- unset(quietFlag)
- endif()
-
- __FetchContent_getSavedDetails(${contentName} contentDetails)
- if("${contentDetails}" STREQUAL "")
- message(FATAL_ERROR "No details have been set for content: ${contentName}")
- endif()
-
- __FetchContent_directPopulate(
- ${contentNameLower}
- ${quietFlag}
- UPDATE_DISCONNECTED ${disconnectUpdates}
- SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild"
- SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src"
- BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build"
- # Put the saved details last so they can override any of the
- # the options we set above (this can include SOURCE_DIR or
- # BUILD_DIR)
- ${contentDetails}
- )
- endif()
-
- __FetchContent_setPopulated(
- ${contentName}
- ${${contentNameLower}_SOURCE_DIR}
- ${${contentNameLower}_BINARY_DIR}
- )
-
- # Pass variables back to the caller. The variables passed back here
- # must match what FetchContent_GetProperties() sets when it is called
- # with just the content name.
- set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
- set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)
- set(${contentNameLower}_POPULATED True PARENT_SCOPE)
-
-endfunction()
diff --git a/cmake/Modules/FetchContent/CMakeLists.cmake.in b/cmake/Modules/FetchContent/CMakeLists.cmake.in
deleted file mode 100644
index 9a7a7715a..000000000
--- a/cmake/Modules/FetchContent/CMakeLists.cmake.in
+++ /dev/null
@@ -1,21 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-cmake_minimum_required(VERSION ${CMAKE_VERSION})
-
-# We name the project and the target for the ExternalProject_Add() call
-# to something that will highlight to the user what we are working on if
-# something goes wrong and an error message is produced.
-
-project(${contentName}-populate NONE)
-
-include(ExternalProject)
-ExternalProject_Add(${contentName}-populate
- ${ARG_EXTRA}
- SOURCE_DIR "${ARG_SOURCE_DIR}"
- BINARY_DIR "${ARG_BINARY_DIR}"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- TEST_COMMAND ""
-)
diff --git a/cmake/Modules/README.md b/cmake/Modules/README.md
deleted file mode 100644
index c8d275f11..000000000
--- a/cmake/Modules/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-## FetchContent
-
-`FetchContent.cmake` and `FetchContent/CMakeLists.cmake.in`
-are copied from `cmake/3.11.0/share/cmake-3.11/Modules`.
diff --git a/cmake/asio.cmake b/cmake/asio.cmake
new file mode 100644
index 000000000..c1d01cdc7
--- /dev/null
+++ b/cmake/asio.cmake
@@ -0,0 +1,44 @@
+function(download_asio)
+ include(FetchContent)
+
+ set(asio_URL "https://github.com/chriskohlhoff/asio/archive/refs/tags/asio-1-24-0.tar.gz")
+ set(asio_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/asio-asio-1-24-0.tar.gz")
+ set(asio_HASH "SHA256=cbcaaba0f66722787b1a7c33afe1befb3a012b5af3ad7da7ff0f6b8c9b7a8a5b")
+
+ # If you don't have access to the Internet,
+ # please pre-download asio
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/asio-asio-1-24-0.tar.gz
+ ${PROJECT_SOURCE_DIR}/asio-asio-1-24-0.tar.gz
+ ${PROJECT_BINARY_DIR}/asio-asio-1-24-0.tar.gz
+ /tmp/asio-asio-1-24-0.tar.gz
+ /star-fj/fangjun/download/github/asio-asio-1-24-0.tar.gz
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(asio_URL "${f}")
+ file(TO_CMAKE_PATH "${asio_URL}" asio_URL)
+ set(asio_URL2)
+ break()
+ endif()
+ endforeach()
+
+ FetchContent_Declare(asio
+ URL
+ ${asio_URL}
+ ${asio_URL2}
+ URL_HASH ${asio_HASH}
+ )
+
+ FetchContent_GetProperties(asio)
+ if(NOT asio_POPULATED)
+ message(STATUS "Downloading asio ${asio_URL}")
+ FetchContent_Populate(asio)
+ endif()
+ message(STATUS "asio is downloaded to ${asio_SOURCE_DIR}")
+ # add_subdirectory(${asio_SOURCE_DIR} ${asio_BINARY_DIR} EXCLUDE_FROM_ALL)
+ include_directories(${asio_SOURCE_DIR}/asio/include)
+endfunction()
+
+download_asio()
diff --git a/cmake/cmake_extension.py b/cmake/cmake_extension.py
index f508fa3b2..9d419eab3 100644
--- a/cmake/cmake_extension.py
+++ b/cmake/cmake_extension.py
@@ -1,4 +1,5 @@
# Copyright (c) 2021-2022 Xiaomi Corporation (author: Fangjun Kuang)
+# flake8: noqa
import os
import platform
@@ -8,7 +9,7 @@
import setuptools
from setuptools.command.build_ext import build_ext
-
+import torch
def is_for_pypi():
ans = os.environ.get("SHERPA_IS_FOR_PYPI", None)
@@ -23,6 +24,11 @@ def is_windows():
return platform.system() == "Windows"
+def get_pytorch_version():
+ # if it is 1.7.1+cuda101, then strip +cuda101
+ return torch.__version__.split("+")[0]
+
+
try:
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
@@ -76,6 +82,12 @@ def build_extension(self, ext: setuptools.extension.Extension):
print(f"Setting PYTHON_EXECUTABLE to {sys.executable}")
cmake_args += f" -DPYTHON_EXECUTABLE={sys.executable}"
+ major, minor = get_pytorch_version().split(".")[:2]
+ major = int(major)
+ minor = int(minor)
+ if major == 2 and minor >= 1:
+ extra_cmake_args += f" -DCMAKE_CXX_STANDARD=17 "
+
cmake_args += extra_cmake_args
if is_windows():
@@ -107,7 +119,7 @@ def build_extension(self, ext: setuptools.extension.Extension):
cmake {cmake_args} {sherpa_dir}
- make {make_args} install
+ make {make_args} install/strip
"""
print(f"build command is:\n{build_cmd}")
@@ -119,7 +131,20 @@ def build_extension(self, ext: setuptools.extension.Extension):
"\nClick:\n\thttps://github.com/k2-fsa/sherpa/issues/new\n" # noqa
)
- for f in ["sherpa", "sherpa-version"]:
- src_file = install_dir / "bin" / f
+ suffix = ".exe" if is_windows() else ""
+ # Remember to also change setup.py
+ binaries = ["sherpa-offline"]
+ binaries += ["sherpa-online", "sherpa-version"]
+ binaries += ["sherpa-online-microphone"]
+ binaries += ["sherpa-offline-microphone"]
+ binaries += ["sherpa-offline-websocket-server"]
+ binaries += ["sherpa-offline-websocket-client"]
+ binaries += ["sherpa-online-websocket-server"]
+ binaries += ["sherpa-online-websocket-client"]
+ binaries += ["sherpa-online-websocket-client-microphone"]
+
+ for f in binaries:
+ src_file = install_dir / "bin" / (f + suffix)
print(f"Copying {src_file} to {out_bin_dir}/")
shutil.copy(f"{src_file}", f"{out_bin_dir}/")
+ src_file.unlink()
diff --git a/cmake/googletest.cmake b/cmake/googletest.cmake
index 0252268cd..d5ff6c620 100644
--- a/cmake/googletest.cmake
+++ b/cmake/googletest.cmake
@@ -1,31 +1,28 @@
-# Copyright 2020 Fangjun Kuang (csukuangfj@gmail.com)
-# See ../LICENSE for clarification regarding multiple authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
function(download_googltest)
- if(CMAKE_VERSION VERSION_LESS 3.11)
- # FetchContent is available since 3.11,
- # we've copied it to ${CMAKE_SOURCE_DIR}/cmake/Modules
- # so that it can be used in lower CMake versions.
- message(STATUS "Use FetchContent provided by k2")
- list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
- endif()
-
include(FetchContent)
- set(googletest_URL "https://github.com/google/googletest/archive/release-1.10.0.tar.gz")
- set(googletest_HASH "SHA256=9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb")
+ set(googletest_URL "https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz")
+ set(googletest_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/googletest-1.13.0.tar.gz")
+ set(googletest_HASH "SHA256=ad7fdba11ea011c1d925b3289cf4af2c66a352e18d4c7264392fead75e919363")
+
+ # If you don't have access to the Internet,
+ # please pre-download googletest
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/googletest-1.13.0.tar.gz
+ ${PROJECT_SOURCE_DIR}/googletest-1.13.0.tar.gz
+ ${PROJECT_BINARY_DIR}/googletest-1.13.0.tar.gz
+ /tmp/googletest-1.13.0.tar.gz
+ /star-fj/fangjun/download/github/googletest-1.13.0.tar.gz
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(googletest_URL "${f}")
+ file(TO_CMAKE_PATH "${googletest_URL}" googletest_URL)
+ set(googletest_URL2)
+ break()
+ endif()
+ endforeach()
set(BUILD_GMOCK ON CACHE BOOL "" FORCE)
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
@@ -33,13 +30,15 @@ function(download_googltest)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_Declare(googletest
- URL ${googletest_URL}
+ URL
+ ${googletest_URL}
+ ${googletest_URL2}
URL_HASH ${googletest_HASH}
)
FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
- message(STATUS "Downloading googletest")
+ message(STATUS "Downloading googletest from ${googletest_URL}")
FetchContent_Populate(googletest)
endif()
message(STATUS "googletest is downloaded to ${googletest_SOURCE_DIR}")
diff --git a/cmake/grpc.cmake b/cmake/grpc.cmake
new file mode 100644
index 000000000..4451b260d
--- /dev/null
+++ b/cmake/grpc.cmake
@@ -0,0 +1,17 @@
+function(download_grpc)
+ message(STATUS "Using gRPC via add_subdirectory")
+ include(FetchContent)
+ #SET(CMAKE_CXX_FLAGS "-DBUILD_SHARED_LIBS=ON")
+
+ set(ABSL_ENABLE_INSTALL ON)
+ FetchContent_Declare(gRPC
+ GIT_REPOSITORY https://github.com/grpc/grpc
+ GIT_TAG v1.57.0
+ )
+ set(FETCHCONTENT_QUIET OFF)
+ FetchContent_MakeAvailable(gRPC)
+
+ message(STATUS "grpc is downloaded to ${grpc_SOURCE_DIR}")
+endfunction()
+
+download_grpc()
diff --git a/cmake/json.cmake b/cmake/json.cmake
new file mode 100644
index 000000000..3ec935b30
--- /dev/null
+++ b/cmake/json.cmake
@@ -0,0 +1,44 @@
+function(download_json)
+ include(FetchContent)
+
+ set(json_URL "https://github.com/nlohmann/json/archive/refs/tags/v3.11.2.tar.gz")
+ set(json_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/json-3.11.2.tar.gz")
+ set(json_HASH "SHA256=d69f9deb6a75e2580465c6c4c5111b89c4dc2fa94e3a85fcd2ffcd9a143d9273")
+
+ # If you don't have access to the Internet,
+ # please pre-download json
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/json-3.11.2.tar.gz
+ ${PROJECT_SOURCE_DIR}/json-3.11.2.tar.gz
+ ${PROJECT_BINARY_DIR}/json-3.11.2.tar.gz
+ /tmp/json-3.11.2.tar.gz
+ /star-fj/fangjun/download/github/json-3.11.2.tar.gz
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(json_URL "${f}")
+ file(TO_CMAKE_PATH "${json_URL}" json_URL)
+ set(json_URL2)
+ break()
+ endif()
+ endforeach()
+
+ FetchContent_Declare(json
+ URL
+ ${json_URL}
+ ${json_URL2}
+ URL_HASH ${json_HASH}
+ )
+
+ FetchContent_GetProperties(json)
+ if(NOT json_POPULATED)
+ message(STATUS "Downloading json from ${json_URL}")
+ FetchContent_Populate(json)
+ endif()
+ message(STATUS "json is downloaded to ${json_SOURCE_DIR}")
+ include_directories(${json_SOURCE_DIR}/include)
+ # Use #include "nlohmann/json.hpp"
+endfunction()
+
+download_json()
diff --git a/cmake/k2.cmake b/cmake/k2.cmake
index b80438db3..ca4234e37 100644
--- a/cmake/k2.cmake
+++ b/cmake/k2.cmake
@@ -1,4 +1,3 @@
-
if(DEFINED ENV{K2_INSTALL_PREFIX})
message(STATUS "Using environment variable K2_INSTALL_PREFIX: $ENV{K2_INSTALL_PREFIX}")
set(K2_CMAKE_PREFIX_PATH $ENV{K2_INSTALL_PREFIX})
@@ -16,7 +15,7 @@ endif()
message(STATUS "K2_CMAKE_PREFIX_PATH: ${K2_CMAKE_PREFIX_PATH}")
list(APPEND CMAKE_PREFIX_PATH "${K2_CMAKE_PREFIX_PATH}")
-find_package(k2 REQUIRED)
+find_package(k2 1.23.2 REQUIRED)
message(STATUS "K2_FOUND: ${K2_FOUND}")
message(STATUS "K2_INCLUDE_DIRS: ${K2_INCLUDE_DIRS}")
diff --git a/cmake/kaldi_native_io.cmake b/cmake/kaldi_native_io.cmake
index b729e415d..c08535c03 100644
--- a/cmake/kaldi_native_io.cmake
+++ b/cmake/kaldi_native_io.cmake
@@ -1,28 +1,42 @@
function(download_kaldi_native_io)
- if(CMAKE_VERSION VERSION_LESS 3.11)
- # FetchContent is available since 3.11,
- # we've copied it to ${CMAKE_SOURCE_DIR}/cmake/Modules
- # so that it can be used in lower CMake versions.
- message(STATUS "Use FetchContent provided by sherpa")
- list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
- endif()
-
include(FetchContent)
- set(kaldi_native_io_URL "https://github.com/csukuangfj/kaldi_native_io/archive/refs/tags/v1.14.tar.gz")
- set(kaldi_native_io_HASH "SHA256=c7dc0a2cda061751a121094ad850f8575f3552d223747021aba0b3abd3827622")
+ set(kaldi_native_io_URL "https://github.com/csukuangfj/kaldi_native_io/archive/refs/tags/v1.22.1.tar.gz")
+ set(kaldi_native_io_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/kaldi_native_io-1.22.1.tar.gz")
+ set(kaldi_native_io_HASH "SHA256=de8ad3398162870b4e1f3ac78101af209c981a8628555710ed4f1adbfed0af43")
+
+ # If you don't have access to the Internet,
+ # please pre-download kaldi_native_io
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/kaldi_native_io-1.22.1.tar.gz
+ ${PROJECT_SOURCE_DIR}/kaldi_native_io-1.22.1.tar.gz
+ ${PROJECT_BINARY_DIR}/kaldi_native_io-1.22.1.tar.gz
+ /tmp/kaldi_native_io-1.22.1.tar.gz
+ /star-fj/fangjun/download/github/kaldi_native_io-1.22.1.tar.gz
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(kaldi_native_io_URL "${f}")
+ file(TO_CMAKE_PATH "${kaldi_native_io_URL}" kaldi_native_io_URL)
+ set(kaldi_native_io_URL2)
+ break()
+ endif()
+ endforeach()
set(KALDI_NATIVE_IO_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(KALDI_NATIVE_IO_BUILD_PYTHON OFF CACHE BOOL "" FORCE)
FetchContent_Declare(kaldi_native_io
- URL ${kaldi_native_io_URL}
+ URL
+ ${kaldi_native_io_URL}
+ ${kaldi_native_io_URL2}
URL_HASH ${kaldi_native_io_HASH}
)
FetchContent_GetProperties(kaldi_native_io)
if(NOT kaldi_native_io_POPULATED)
- message(STATUS "Downloading kaldi_native_io${kaldi_native_io_URL}")
+ message(STATUS "Downloading kaldi_native_io from ${kaldi_native_io_URL}")
FetchContent_Populate(kaldi_native_io)
endif()
message(STATUS "kaldi_native_io is downloaded to ${kaldi_native_io_SOURCE_DIR}")
@@ -34,6 +48,10 @@ function(download_kaldi_native_io)
PUBLIC
${kaldi_native_io_SOURCE_DIR}/
)
+
+ set_target_properties(kaldi_native_io_core PROPERTIES OUTPUT_NAME "sherpa_kaldi_native_io_core")
+
+ install(TARGETS kaldi_native_io_core DESTINATION lib)
endfunction()
download_kaldi_native_io()
diff --git a/cmake/portaudio.cmake b/cmake/portaudio.cmake
new file mode 100644
index 000000000..f14534bc5
--- /dev/null
+++ b/cmake/portaudio.cmake
@@ -0,0 +1,66 @@
+function(download_portaudio)
+ include(FetchContent)
+
+ set(portaudio_URL "http://files.portaudio.com/archives/pa_stable_v190700_20210406.tgz")
+ set(portaudio_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/pa_stable_v190700_20210406.tgz")
+ set(portaudio_HASH "SHA256=47efbf42c77c19a05d22e627d42873e991ec0c1357219c0d74ce6a2948cb2def")
+
+ # If you don't have access to the Internet, please download it to your
+ # local drive and modify the following line according to your needs.
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/pa_stable_v190700_20210406.tgz
+ $ENV{HOME}/asr/pa_stable_v190700_20210406.tgz
+ ${PROJECT_SOURCE_DIR}/pa_stable_v190700_20210406.tgz
+ ${PROJECT_BINARY_DIR}/pa_stable_v190700_20210406.tgz
+ /tmp/pa_stable_v190700_20210406.tgz
+ /star-fj/fangjun/download/github/pa_stable_v190700_20210406.tgz
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(portaudio_URL "${f}")
+ file(TO_CMAKE_PATH "${portaudio_URL}" portaudio_URL)
+ set(portaudio_URL2)
+ break()
+ endif()
+ endforeach()
+
+ if(BUILD_SHARED_LIBS)
+ set(PA_BUILD_SHARED ON CACHE BOOL "" FORCE)
+ set(PA_BUILD_STATIC OFF CACHE BOOL "" FORCE)
+ else()
+ set(PA_BUILD_SHARED OFF CACHE BOOL "" FORCE)
+ set(PA_BUILD_STATIC ON CACHE BOOL "" FORCE)
+ endif()
+
+ FetchContent_Declare(portaudio
+ URL
+ ${portaudio_URL}
+ ${portaudio_URL2}
+ URL_HASH ${portaudio_HASH}
+ )
+
+ FetchContent_GetProperties(portaudio)
+ if(NOT portaudio_POPULATED)
+ message(STATUS "Downloading portaudio from ${portaudio_URL}")
+ FetchContent_Populate(portaudio)
+ endif()
+ message(STATUS "portaudio is downloaded to ${portaudio_SOURCE_DIR}")
+ message(STATUS "portaudio's binary dir is ${portaudio_BINARY_DIR}")
+
+ add_subdirectory(${portaudio_SOURCE_DIR} ${portaudio_BINARY_DIR} EXCLUDE_FROM_ALL)
+
+ if(BUILD_SHARED_LIBS)
+ set_target_properties(portaudio PROPERTIES OUTPUT_NAME "sherpa_portaudio")
+ install(TARGETS portaudio DESTINATION lib)
+ else()
+ set_target_properties(portaudio_static PROPERTIES OUTPUT_NAME "sherpa_portaudio_static")
+ install(TARGETS portaudio_static DESTINATION lib)
+ endif()
+endfunction()
+
+download_portaudio()
+
+# Note
+# See http://portaudio.com/docs/v19-doxydocs/tutorial_start.html
+# for how to use portaudio
diff --git a/cmake/pybind11.cmake b/cmake/pybind11.cmake
index 76cf090e4..eeeb8fe5a 100644
--- a/cmake/pybind11.cmake
+++ b/cmake/pybind11.cmake
@@ -1,21 +1,39 @@
function(download_pybind11)
- if(CMAKE_VERSION VERSION_LESS 3.11)
- list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
- endif()
-
include(FetchContent)
- set(pybind11_URL "https://github.com/pybind/pybind11/archive/v2.9.2.tar.gz")
- set(pybind11_HASH "SHA256=6bd528c4dbe2276635dc787b6b1f2e5316cf6b49ee3e150264e455a0d68d19c1")
+ set(pybind11_URL "https://github.com/pybind/pybind11/archive/5bc0943ed96836f46489f53961f6c438d2935357.zip")
+ set(pybind11_URL2 "https://huggingface.co/csukuangfj/k2-cmake-deps/resolve/main/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip")
+ set(pybind11_HASH "SHA256=ff65a1a8c9e6ceec11e7ed9d296f2e22a63e9ff0c4264b3af29c72b4f18f25a0")
+
+ # If you don't have access to the Internet,
+ # please pre-download pybind11
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip
+ ${PROJECT_SOURCE_DIR}/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip
+ ${PROJECT_BINARY_DIR}/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip
+ /tmp/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip
+ /star-fj/fangjun/download/github/pybind11-5bc0943ed96836f46489f53961f6c438d2935357.zip
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(pybind11_URL "${f}")
+ file(TO_CMAKE_PATH "${pybind11_URL}" pybind11_URL)
+ set(pybind11_URL2)
+ break()
+ endif()
+ endforeach()
FetchContent_Declare(pybind11
- URL ${pybind11_URL}
+ URL
+ ${pybind11_URL}
+ ${pybind11_URL2}
URL_HASH ${pybind11_HASH}
)
FetchContent_GetProperties(pybind11)
if(NOT pybind11_POPULATED)
- message(STATUS "Downloading pybind11")
+ message(STATUS "Downloading pybind11 from ${pybind11_URL}")
FetchContent_Populate(pybind11)
endif()
message(STATUS "pybind11 is downloaded to ${pybind11_SOURCE_DIR}")
diff --git a/cmake/websocketpp.cmake b/cmake/websocketpp.cmake
new file mode 100644
index 000000000..33bbbc348
--- /dev/null
+++ b/cmake/websocketpp.cmake
@@ -0,0 +1,45 @@
+function(download_websocketpp)
+ include(FetchContent)
+
+ # The latest commit on the develop branch os as 2022-10-22
+ set(websocketpp_URL "https://github.com/zaphoyd/websocketpp/archive/b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip")
+ set(websocketpp_URL2 "https://huggingface.co/csukuangfj/sherpa-cmake-deps/resolve/main/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip")
+ set(websocketpp_HASH "SHA256=1385135ede8191a7fbef9ec8099e3c5a673d48df0c143958216cd1690567f583")
+
+ # If you don't have access to the Internet,
+ # please pre-download websocketpp
+ set(possible_file_locations
+ $ENV{HOME}/Downloads/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip
+ ${PROJECT_SOURCE_DIR}/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip
+ ${PROJECT_BINARY_DIR}/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip
+ /tmp/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip
+ /star-fj/fangjun/download/github/websocketpp-b9aeec6eaf3d5610503439b4fae3581d9aff08e8.zip
+ )
+
+ foreach(f IN LISTS possible_file_locations)
+ if(EXISTS ${f})
+ set(websocketpp_URL "${f}")
+ file(TO_CMAKE_PATH "${websocketpp_URL}" websocketpp_URL)
+ set(websocketpp_URL2)
+ break()
+ endif()
+ endforeach()
+
+ FetchContent_Declare(websocketpp
+ URL
+ ${websocketpp_URL}
+ ${websocketpp_URL2}
+ URL_HASH ${websocketpp_HASH}
+ )
+
+ FetchContent_GetProperties(websocketpp)
+ if(NOT websocketpp_POPULATED)
+ message(STATUS "Downloading websocketpp from ${websocketpp_URL}")
+ FetchContent_Populate(websocketpp)
+ endif()
+ message(STATUS "websocketpp is downloaded to ${websocketpp_SOURCE_DIR}")
+ # add_subdirectory(${websocketpp_SOURCE_DIR} ${websocketpp_BINARY_DIR} EXCLUDE_FROM_ALL)
+ include_directories(${websocketpp_SOURCE_DIR})
+endfunction()
+
+download_websocketpp()
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 2ec5d24f2..504c3f938 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,6 +1,7 @@
recommonmark==0.7.1
-sphinx==4.3.2
+sphinx==5.0.0
sphinx-autodoc-typehints==1.12.0
sphinx_rtd_theme==1.0.0
sphinxcontrib-bibtex==2.4.1
sphinxcontrib-youtube==1.1.0
+sphinx-tabs
diff --git a/docs/source/_static/.gitignore b/docs/source/_static/.gitignore
new file mode 100644
index 000000000..9c42fcdd4
--- /dev/null
+++ b/docs/source/_static/.gitignore
@@ -0,0 +1 @@
+!*.wav
diff --git a/docs/source/_static/audio-tagging/zipformer-small/1.wav b/docs/source/_static/audio-tagging/zipformer-small/1.wav
new file mode 100644
index 000000000..9ce6c583c
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/1.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/10.wav b/docs/source/_static/audio-tagging/zipformer-small/10.wav
new file mode 100644
index 000000000..eaee99c2d
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/10.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/11.wav b/docs/source/_static/audio-tagging/zipformer-small/11.wav
new file mode 100644
index 000000000..deba35a31
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/11.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/12.wav b/docs/source/_static/audio-tagging/zipformer-small/12.wav
new file mode 100644
index 000000000..cc0ab100a
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/12.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/13.wav b/docs/source/_static/audio-tagging/zipformer-small/13.wav
new file mode 100644
index 000000000..a6466de72
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/13.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/2.wav b/docs/source/_static/audio-tagging/zipformer-small/2.wav
new file mode 100644
index 000000000..2eef217cb
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/2.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/3.wav b/docs/source/_static/audio-tagging/zipformer-small/3.wav
new file mode 100644
index 000000000..ed79deabd
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/3.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/4.wav b/docs/source/_static/audio-tagging/zipformer-small/4.wav
new file mode 100644
index 000000000..a44dae3b3
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/4.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/5.wav b/docs/source/_static/audio-tagging/zipformer-small/5.wav
new file mode 100644
index 000000000..f846a8ac0
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/5.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/6.wav b/docs/source/_static/audio-tagging/zipformer-small/6.wav
new file mode 100644
index 000000000..587746bbc
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/6.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/7.wav b/docs/source/_static/audio-tagging/zipformer-small/7.wav
new file mode 100644
index 000000000..60105566d
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/7.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/8.wav b/docs/source/_static/audio-tagging/zipformer-small/8.wav
new file mode 100644
index 000000000..71f448b15
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/8.wav differ
diff --git a/docs/source/_static/audio-tagging/zipformer-small/9.wav b/docs/source/_static/audio-tagging/zipformer-small/9.wav
new file mode 100644
index 000000000..9ddec091b
Binary files /dev/null and b/docs/source/_static/audio-tagging/zipformer-small/9.wav differ
diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css
new file mode 100644
index 000000000..2c6806323
--- /dev/null
+++ b/docs/source/_static/css/custom.css
@@ -0,0 +1,12 @@
+.toggle .header {
+ display: block;
+ clear: both;
+}
+
+.toggle .header:after {
+ content: " ▶";
+}
+
+.toggle .header.open:after {
+ content: " ▼";
+}
diff --git a/docs/source/_static/kokoro-en-v0_19/10-bm_lewis.wav b/docs/source/_static/kokoro-en-v0_19/10-bm_lewis.wav
new file mode 100644
index 000000000..d3b6761cb
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/10-bm_lewis.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/2-af_nicole.wav b/docs/source/_static/kokoro-en-v0_19/2-af_nicole.wav
new file mode 100644
index 000000000..749adc1d5
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/2-af_nicole.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/0-af.wav b/docs/source/_static/kokoro-en-v0_19/sid/0-af.wav
new file mode 100644
index 000000000..d013847f6
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/0-af.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/1-af_bella.wav b/docs/source/_static/kokoro-en-v0_19/sid/1-af_bella.wav
new file mode 100644
index 000000000..31de45503
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/1-af_bella.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/10-bm_lewis.wav b/docs/source/_static/kokoro-en-v0_19/sid/10-bm_lewis.wav
new file mode 100644
index 000000000..7e2ca34fa
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/10-bm_lewis.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/2-af_nicole.wav b/docs/source/_static/kokoro-en-v0_19/sid/2-af_nicole.wav
new file mode 100644
index 000000000..871420565
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/2-af_nicole.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/3-af_sarah.wav b/docs/source/_static/kokoro-en-v0_19/sid/3-af_sarah.wav
new file mode 100644
index 000000000..0af228b58
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/3-af_sarah.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/4-af_sky.wav b/docs/source/_static/kokoro-en-v0_19/sid/4-af_sky.wav
new file mode 100644
index 000000000..bcbe45da4
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/4-af_sky.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/5-am_adam.wav b/docs/source/_static/kokoro-en-v0_19/sid/5-am_adam.wav
new file mode 100644
index 000000000..9b582996d
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/5-am_adam.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/6-am_michael.wav b/docs/source/_static/kokoro-en-v0_19/sid/6-am_michael.wav
new file mode 100644
index 000000000..3c79b767e
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/6-am_michael.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/7-bf_emma.wav b/docs/source/_static/kokoro-en-v0_19/sid/7-bf_emma.wav
new file mode 100644
index 000000000..4945b70a2
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/7-bf_emma.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/8-bf_isabella.wav b/docs/source/_static/kokoro-en-v0_19/sid/8-bf_isabella.wav
new file mode 100644
index 000000000..331025d8a
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/8-bf_isabella.wav differ
diff --git a/docs/source/_static/kokoro-en-v0_19/sid/9-bm_george.wav b/docs/source/_static/kokoro-en-v0_19/sid/9-bm_george.wav
new file mode 100644
index 000000000..52f264671
Binary files /dev/null and b/docs/source/_static/kokoro-en-v0_19/sid/9-bm_george.wav differ
diff --git a/docs/source/_static/kokoro-multi-lang-v1_0/.gitignore b/docs/source/_static/kokoro-multi-lang-v1_0/.gitignore
new file mode 100644
index 000000000..d8dd7532a
--- /dev/null
+++ b/docs/source/_static/kokoro-multi-lang-v1_0/.gitignore
@@ -0,0 +1 @@
+*.wav
diff --git a/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-0.wav b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-0.wav
new file mode 100644
index 000000000..2c8be048b
Binary files /dev/null and b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-0.wav differ
diff --git a/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-1.wav b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-1.wav
new file mode 100644
index 000000000..e27d15383
Binary files /dev/null and b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-1.wav differ
diff --git a/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-2.wav b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-2.wav
new file mode 100644
index 000000000..50c9a9bec
Binary files /dev/null and b/docs/source/_static/matcha-icefall-baker-zh/matcha-baker-2.wav differ
diff --git a/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-0.wav b/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-0.wav
new file mode 100644
index 000000000..d6726715b
Binary files /dev/null and b/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-0.wav differ
diff --git a/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-1.wav b/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-1.wav
new file mode 100644
index 000000000..76c3f7b2b
Binary files /dev/null and b/docs/source/_static/matcha-icefall-en_US-ljspeech/matcha-ljspeech-1.wav differ
diff --git a/docs/source/_static/mms/mms-eng.wav b/docs/source/_static/mms/mms-eng.wav
new file mode 100644
index 000000000..cef186916
Binary files /dev/null and b/docs/source/_static/mms/mms-eng.wav differ
diff --git a/docs/source/_static/onnx/riscv64/a-test.wav b/docs/source/_static/onnx/riscv64/a-test.wav
new file mode 100644
index 000000000..7b590c823
Binary files /dev/null and b/docs/source/_static/onnx/riscv64/a-test.wav differ
diff --git a/docs/source/_static/piper/test.wav b/docs/source/_static/piper/test.wav
new file mode 100644
index 000000000..8c2a118ed
Binary files /dev/null and b/docs/source/_static/piper/test.wav differ
diff --git a/docs/source/_static/sense-voice/.gitignore b/docs/source/_static/sense-voice/.gitignore
new file mode 100644
index 000000000..d8dd7532a
--- /dev/null
+++ b/docs/source/_static/sense-voice/.gitignore
@@ -0,0 +1 @@
+*.wav
diff --git a/docs/source/_static/sense-voice/python-websocket/test.wav b/docs/source/_static/sense-voice/python-websocket/test.wav
new file mode 100644
index 000000000..01c3cb3c1
Binary files /dev/null and b/docs/source/_static/sense-voice/python-websocket/test.wav differ
diff --git a/docs/source/_static/sherpa-onnx-vits-zh-ll/0-value-2x.wav b/docs/source/_static/sherpa-onnx-vits-zh-ll/0-value-2x.wav
new file mode 100644
index 000000000..0e17d2946
Binary files /dev/null and b/docs/source/_static/sherpa-onnx-vits-zh-ll/0-value-2x.wav differ
diff --git a/docs/source/_static/sherpa-onnx-vits-zh-ll/1-numbers.wav b/docs/source/_static/sherpa-onnx-vits-zh-ll/1-numbers.wav
new file mode 100644
index 000000000..fe8807949
Binary files /dev/null and b/docs/source/_static/sherpa-onnx-vits-zh-ll/1-numbers.wav differ
diff --git a/docs/source/_static/sherpa-onnx-vits-zh-ll/2-numbers.wav b/docs/source/_static/sherpa-onnx-vits-zh-ll/2-numbers.wav
new file mode 100644
index 000000000..a21e85494
Binary files /dev/null and b/docs/source/_static/sherpa-onnx-vits-zh-ll/2-numbers.wav differ
diff --git a/docs/source/_static/sherpa-onnx-vits-zh-ll/3-wo-mi.wav b/docs/source/_static/sherpa-onnx-vits-zh-ll/3-wo-mi.wav
new file mode 100644
index 000000000..cb8147897
Binary files /dev/null and b/docs/source/_static/sherpa-onnx-vits-zh-ll/3-wo-mi.wav differ
diff --git a/docs/source/_static/sherpa-onnx-vits-zh-ll/4-heteronym.wav b/docs/source/_static/sherpa-onnx-vits-zh-ll/4-heteronym.wav
new file mode 100644
index 000000000..542d33eaa
Binary files /dev/null and b/docs/source/_static/sherpa-onnx-vits-zh-ll/4-heteronym.wav differ
diff --git a/docs/source/_static/speech-enhancement/gtcrn-simple/enhanced-16k.wav b/docs/source/_static/speech-enhancement/gtcrn-simple/enhanced-16k.wav
new file mode 100644
index 000000000..c49ac49b2
Binary files /dev/null and b/docs/source/_static/speech-enhancement/gtcrn-simple/enhanced-16k.wav differ
diff --git a/docs/source/_static/speech-enhancement/gtcrn-simple/speech_with_noise.wav b/docs/source/_static/speech-enhancement/gtcrn-simple/speech_with_noise.wav
new file mode 100644
index 000000000..425d7c043
Binary files /dev/null and b/docs/source/_static/speech-enhancement/gtcrn-simple/speech_with_noise.wav differ
diff --git a/docs/source/_static/vits-ljs/armstrong.wav b/docs/source/_static/vits-ljs/armstrong.wav
new file mode 100644
index 000000000..3b790b1eb
Binary files /dev/null and b/docs/source/_static/vits-ljs/armstrong.wav differ
diff --git a/docs/source/_static/vits-ljs/liliana.wav b/docs/source/_static/vits-ljs/liliana.wav
new file mode 100644
index 000000000..cc9920804
Binary files /dev/null and b/docs/source/_static/vits-ljs/liliana.wav differ
diff --git a/docs/source/_static/vits-melo-tts/zh-en-0.wav b/docs/source/_static/vits-melo-tts/zh-en-0.wav
new file mode 100644
index 000000000..ade6bdd40
Binary files /dev/null and b/docs/source/_static/vits-melo-tts/zh-en-0.wav differ
diff --git a/docs/source/_static/vits-melo-tts/zh-en-1.wav b/docs/source/_static/vits-melo-tts/zh-en-1.wav
new file mode 100644
index 000000000..b56a5967c
Binary files /dev/null and b/docs/source/_static/vits-melo-tts/zh-en-1.wav differ
diff --git a/docs/source/_static/vits-melo-tts/zh-en-2.wav b/docs/source/_static/vits-melo-tts/zh-en-2.wav
new file mode 100644
index 000000000..016662b7a
Binary files /dev/null and b/docs/source/_static/vits-melo-tts/zh-en-2.wav differ
diff --git a/docs/source/_static/vits-melo-tts/zh-en-3.wav b/docs/source/_static/vits-melo-tts/zh-en-3.wav
new file mode 100644
index 000000000..e85288bce
Binary files /dev/null and b/docs/source/_static/vits-melo-tts/zh-en-3.wav differ
diff --git a/docs/source/_static/vits-piper-glados/glados-bug.wav b/docs/source/_static/vits-piper-glados/glados-bug.wav
new file mode 100644
index 000000000..6c7453b32
Binary files /dev/null and b/docs/source/_static/vits-piper-glados/glados-bug.wav differ
diff --git a/docs/source/_static/vits-piper-glados/glados-code.wav b/docs/source/_static/vits-piper-glados/glados-code.wav
new file mode 100644
index 000000000..c667542b9
Binary files /dev/null and b/docs/source/_static/vits-piper-glados/glados-code.wav differ
diff --git a/docs/source/_static/vits-piper-glados/glados-liliana.wav b/docs/source/_static/vits-piper-glados/glados-liliana.wav
new file mode 100644
index 000000000..d3308c8af
Binary files /dev/null and b/docs/source/_static/vits-piper-glados/glados-liliana.wav differ
diff --git a/docs/source/_static/vits-piper-glados/glados-men.wav b/docs/source/_static/vits-piper-glados/glados-men.wav
new file mode 100644
index 000000000..11c89b203
Binary files /dev/null and b/docs/source/_static/vits-piper-glados/glados-men.wav differ
diff --git a/docs/source/_static/vits-piper-glados/glados-ship.wav b/docs/source/_static/vits-piper-glados/glados-ship.wav
new file mode 100644
index 000000000..d70c94075
Binary files /dev/null and b/docs/source/_static/vits-piper-glados/glados-ship.wav differ
diff --git a/docs/source/_static/vits-piper-libritts/libritts-armstrong-200.wav b/docs/source/_static/vits-piper-libritts/libritts-armstrong-200.wav
new file mode 100644
index 000000000..c3644bb68
Binary files /dev/null and b/docs/source/_static/vits-piper-libritts/libritts-armstrong-200.wav differ
diff --git a/docs/source/_static/vits-piper-libritts/libritts-armstrong-500.wav b/docs/source/_static/vits-piper-libritts/libritts-armstrong-500.wav
new file mode 100644
index 000000000..dd120ac32
Binary files /dev/null and b/docs/source/_static/vits-piper-libritts/libritts-armstrong-500.wav differ
diff --git a/docs/source/_static/vits-piper-libritts/libritts-liliana-109.wav b/docs/source/_static/vits-piper-libritts/libritts-liliana-109.wav
new file mode 100644
index 000000000..8accdba57
Binary files /dev/null and b/docs/source/_static/vits-piper-libritts/libritts-liliana-109.wav differ
diff --git a/docs/source/_static/vits-piper-libritts/libritts-liliana-900.wav b/docs/source/_static/vits-piper-libritts/libritts-liliana-900.wav
new file mode 100644
index 000000000..1e9a9c5d2
Binary files /dev/null and b/docs/source/_static/vits-piper-libritts/libritts-liliana-900.wav differ
diff --git a/docs/source/_static/vits-piper/armstrong-piper-en_US-lessac-medium.wav b/docs/source/_static/vits-piper/armstrong-piper-en_US-lessac-medium.wav
new file mode 100644
index 000000000..9b953a082
Binary files /dev/null and b/docs/source/_static/vits-piper/armstrong-piper-en_US-lessac-medium.wav differ
diff --git a/docs/source/_static/vits-piper/liliana-piper-en_US-lessac-medium.wav b/docs/source/_static/vits-piper/liliana-piper-en_US-lessac-medium.wav
new file mode 100644
index 000000000..f1b84ac29
Binary files /dev/null and b/docs/source/_static/vits-piper/liliana-piper-en_US-lessac-medium.wav differ
diff --git a/docs/source/_static/vits-vctk/einstein-30.wav b/docs/source/_static/vits-vctk/einstein-30.wav
new file mode 100644
index 000000000..3f4ab09a8
Binary files /dev/null and b/docs/source/_static/vits-vctk/einstein-30.wav differ
diff --git a/docs/source/_static/vits-vctk/franklin-66.wav b/docs/source/_static/vits-vctk/franklin-66.wav
new file mode 100644
index 000000000..ae827e5c9
Binary files /dev/null and b/docs/source/_static/vits-vctk/franklin-66.wav differ
diff --git a/docs/source/_static/vits-vctk/kennedy-0.wav b/docs/source/_static/vits-vctk/kennedy-0.wav
new file mode 100644
index 000000000..8b248cc6b
Binary files /dev/null and b/docs/source/_static/vits-vctk/kennedy-0.wav differ
diff --git a/docs/source/_static/vits-vctk/kennedy-10.wav b/docs/source/_static/vits-vctk/kennedy-10.wav
new file mode 100644
index 000000000..761eddb3c
Binary files /dev/null and b/docs/source/_static/vits-vctk/kennedy-10.wav differ
diff --git a/docs/source/_static/vits-vctk/kennedy-108.wav b/docs/source/_static/vits-vctk/kennedy-108.wav
new file mode 100644
index 000000000..c563e8890
Binary files /dev/null and b/docs/source/_static/vits-vctk/kennedy-108.wav differ
diff --git a/docs/source/_static/vits-vctk/martin-99.wav b/docs/source/_static/vits-vctk/martin-99.wav
new file mode 100644
index 000000000..9441385bc
Binary files /dev/null and b/docs/source/_static/vits-vctk/martin-99.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/demokelite-41.wav b/docs/source/_static/vits-zh-aishell3/demokelite-41.wav
new file mode 100644
index 000000000..31889432f
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/demokelite-41.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/liliana-10.wav b/docs/source/_static/vits-zh-aishell3/liliana-10.wav
new file mode 100644
index 000000000..9ab24281a
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/liliana-10.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/liliana-33.wav b/docs/source/_static/vits-zh-aishell3/liliana-33.wav
new file mode 100644
index 000000000..4a40607b1
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/liliana-33.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/liliana-99.wav b/docs/source/_static/vits-zh-aishell3/liliana-99.wav
new file mode 100644
index 000000000..6ec1732c3
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/liliana-99.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/liubei-21.wav b/docs/source/_static/vits-zh-aishell3/liubei-21.wav
new file mode 100644
index 000000000..d4dffd226
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/liubei-21.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/rule-103.wav b/docs/source/_static/vits-zh-aishell3/rule-103.wav
new file mode 100644
index 000000000..8eee53171
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/rule-103.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/rule-66.wav b/docs/source/_static/vits-zh-aishell3/rule-66.wav
new file mode 100644
index 000000000..bedaf6874
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/rule-66.wav differ
diff --git a/docs/source/_static/vits-zh-aishell3/zhugeliang-45.wav b/docs/source/_static/vits-zh-aishell3/zhugeliang-45.wav
new file mode 100644
index 000000000..0f43dc478
Binary files /dev/null and b/docs/source/_static/vits-zh-aishell3/zhugeliang-45.wav differ
diff --git a/docs/source/_static/vits-zh-hf-eula/news-666.wav b/docs/source/_static/vits-zh-hf-eula/news-666.wav
new file mode 100644
index 000000000..5bcc9fbf9
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-eula/news-666.wav differ
diff --git a/docs/source/_static/vits-zh-hf-eula/news-99.wav b/docs/source/_static/vits-zh-hf-eula/news-99.wav
new file mode 100644
index 000000000..5ae5d4c03
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-eula/news-99.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-C/heteronym-102.wav b/docs/source/_static/vits-zh-hf-fanchen-C/heteronym-102.wav
new file mode 100644
index 000000000..3ce71dd7c
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-C/heteronym-102.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-C/numbers-100.wav b/docs/source/_static/vits-zh-hf-fanchen-C/numbers-100.wav
new file mode 100644
index 000000000..4bfe50d4f
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-C/numbers-100.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-C/numbers.wav b/docs/source/_static/vits-zh-hf-fanchen-C/numbers.wav
new file mode 100644
index 000000000..0f34a7fa3
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-C/numbers.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-C/value-2x.wav b/docs/source/_static/vits-zh-hf-fanchen-C/value-2x.wav
new file mode 100644
index 000000000..649440caa
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-C/value-2x.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-C/wo-mi-14.wav b/docs/source/_static/vits-zh-hf-fanchen-C/wo-mi-14.wav
new file mode 100644
index 000000000..49f48f70a
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-C/wo-mi-14.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-wnj/kuayue.wav b/docs/source/_static/vits-zh-hf-fanchen-wnj/kuayue.wav
new file mode 100644
index 000000000..fbbc0144f
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-wnj/kuayue.wav differ
diff --git a/docs/source/_static/vits-zh-hf-fanchen-wnj/os.wav b/docs/source/_static/vits-zh-hf-fanchen-wnj/os.wav
new file mode 100644
index 000000000..2eda3cf4f
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-fanchen-wnj/os.wav differ
diff --git a/docs/source/_static/vits-zh-hf-theresa/mi14-88.wav b/docs/source/_static/vits-zh-hf-theresa/mi14-88.wav
new file mode 100644
index 000000000..b2c45e273
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-theresa/mi14-88.wav differ
diff --git a/docs/source/_static/vits-zh-hf-theresa/reai-0.wav b/docs/source/_static/vits-zh-hf-theresa/reai-0.wav
new file mode 100644
index 000000000..fd96b2151
Binary files /dev/null and b/docs/source/_static/vits-zh-hf-theresa/reai-0.wav differ
diff --git a/triton/model_repo/conformer_transducer/1/.gitkeep b/docs/source/_templates/.gitkeep
similarity index 100%
rename from triton/model_repo/conformer_transducer/1/.gitkeep
rename to docs/source/_templates/.gitkeep
diff --git a/docs/source/_templates/page.html b/docs/source/_templates/page.html
new file mode 100644
index 000000000..399237b5f
--- /dev/null
+++ b/docs/source/_templates/page.html
@@ -0,0 +1,15 @@
+
+{% extends "!page.html" %}
+
+{% block footer %}
+
+{% endblock %}
diff --git a/docs/source/conf.py b/docs/source/conf.py
index e5cc8caba..13d1a7e46 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -10,6 +10,7 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
+import datetime
import os
import re
import sys
@@ -20,8 +21,9 @@
# -- Project information -----------------------------------------------------
+year = datetime.date.today().year
project = "sherpa"
-copyright = "2022, sherpa development team"
+copyright = f"2022-{year}, sherpa development team"
author = "sherpa development team"
@@ -45,14 +47,15 @@ def get_version():
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ "_ext.rst_roles",
"recommonmark",
"sphinx.ext.autodoc",
"sphinx.ext.githubpages",
"sphinx.ext.napoleon",
"sphinx_autodoc_typehints",
"sphinx_rtd_theme",
+ "sphinx_tabs.tabs",
"sphinxcontrib.youtube",
- "_ext.rst_roles",
]
# Add any paths that contain templates here, relative to this directory.
@@ -110,15 +113,73 @@ def get_version():
.. _ConvEmformer: https://arxiv.org/pdf/2110.05241.pdf
.. _Emformer: https://arxiv.org/pdf/2010.10759.pdf
.. _LibriSpeech: https://www.openslr.org/12
+.. _CSJ: https://clrd.ninjal.ac.jp/csj/en/index.html
.. _aishell: https://www.openslr.org/33
.. _sherpa: https://github.com/k2-fsa/sherpa
.. _transducer: https://arxiv.org/pdf/1211.3711.pdf
+.. _CTC: https://www.cs.toronto.edu/~graves/icml_2006.pdf
.. _asyncio: https://docs.python.org/3/library/asyncio.html
.. _k2: https://github.com/k2-fsa/k2
.. _icefall: https://github.com/k2-fsa/icefall
.. _PyTorch: https://pytorch.org/
.. _Huggingface: https://huggingface.co
.. _WenetSpeech: https://github.com/wenet-e2e/WenetSpeech
+.. _WeNet: https://github.com/wenet-e2e/wenet
.. _GigaSpeech: https://github.com/SpeechColab/GigaSpeech
.. _Kaldi: https://github.com/kaldi-asr/kaldi
+.. _kaldifeat: https://csukuangfj.github.io/kaldifeat/installation/index.html
+.. _ncnn: https://github.com/tencent/ncnn
+.. _sherpa-ncnn: https://github.com/k2-fsa/sherpa-ncnn
+.. _onnx: https://github.com/onnx/onnx
+.. _onnxruntime: https://github.com/microsoft/onnxruntime
+.. _sherpa-onnx: https://github.com/k2-fsa/sherpa-onnx
+.. _torchaudio: https://github.com/pytorch/audio
+.. _Docker: https://www.docker.com
+.. _Triton: https://github.com/triton-inference-server
+.. _Triton-server: https://github.com/triton-inference-server/server
+.. _Triton-client: https://github.com/triton-inference-server/client
+.. _WebSocket: https://en.wikipedia.org/wiki/WebSocket
+.. _websocketpp: https://github.com/zaphoyd/websocketpp
+.. _asio: https://github.com/chriskohlhoff/asio
+.. _boost: https://github.com/boostorg/boost
+.. _NeMo: https://github.com/NVIDIA/NeMo
+.. _CommonVoice: https://commonvoice.mozilla.org
+.. _Zipformer: https://github.com/k2-fsa/icefall/tree/master/egs/librispeech/ASR/pruned_transducer_stateless7_streaming
+.. _VisionFive2: https://www.starfivetech.com/en/site/boards
+.. _k2-fsa/sherpa: http://github.com/k2-fsa/sherpa
+.. _k2-fsa/sherpa-onnx: http://github.com/k2-fsa/sherpa-onnx
+.. _k2-fsa/sherpa-ncnn: http://github.com/k2-fsa/sherpa-ncnn
+.. _srs: https://github.com/ossrs/srs
+.. _RTMP: https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol
+.. _Whisper: https://github.com/openai/whisper/
+.. _Go: https://en.wikipedia.org/wiki/Go_(programming_language)
+.. _sherpa-onnx-go: https://github.com/k2-fsa/sherpa-onnx-go
+.. _yesno: https://www.openslr.org/1/
+.. _vits: https://github.com/jaywalnut310/vits
+.. _ljspeech: https://keithito.com/LJ-Speech-Dataset/
+.. _LJ Speech: https://keithito.com/LJ-Speech-Dataset/
+.. _VCTK: https://datashare.ed.ac.uk/handle/10283/2950
+.. _piper: https://github.com/rhasspy/piper
+.. _aishell3: https://www.openslr.org/93/
+.. _lessac_blizzard2013: https://www.cstr.ed.ac.uk/projects/blizzard/2013/lessac_blizzard2013/
+.. _OpenFst: https://www.openfst.org/
+.. _MMS: https://huggingface.co/spaces/mms-meta/MMS
+.. _WebAssembly: https://en.wikipedia.org/wiki/WebAssembly
+.. _emscripten: https://emscripten.org/index.html
+.. _audioset: https://research.google.com/audioset/
+.. _silero-vad: https://github.com/snakers4/silero-vad
+.. _Flutter: https://flutter.dev/
+.. _Dart: https://dart.dev/
+.. _Node: https://nodejs.org/en
+.. _SenseVoice: https://github.com/FunAudioLLM/SenseVoice
+.. _LibriTTS-R: https://www.openslr.org/141/
+.. _ReazonSpeech: https://github.com/reazon-research/ReazonSpeech
+.. _Lazarus: https://www.lazarus-ide.org/
+.. _Moonshine: https://github.com/usefulsensors/moonshine
+.. _moonshine: https://github.com/usefulsensors/moonshine
+.. _FireRedAsr: https://github.com/FireRedTeam/FireRedASR
"""
+
+
+def setup(app):
+ app.add_css_file("custom.css")
diff --git a/docs/source/cpp/installation/conda-linux.rst b/docs/source/cpp/installation/conda-linux.rst
deleted file mode 100644
index 1f476bcac..000000000
--- a/docs/source/cpp/installation/conda-linux.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-conda for Linux
-===============
-
-.. note::
-
- We recommend creating a new virtual environment to install ``sherpa``.
-
-
-CPU version
------------
-
-The command to install a CPU version of ``sherpa`` for Linux using ``conda`` is:
-
-.. code-block:: bash
-
- conda install \
- -c k2-fsa \
- -c k2-fsa-sherpa \
- -c kaldifeat \
- -c kaldi_native_io \
- -c pytorch \
- cpuonly \
- k2 \
- sherpa \
- kaldifeat \
- kaldi_native_io \
- pytorch=1.12.0 \
- python=3.8
-
-or the following command in one line:
-
-.. code-block:: bash
-
- conda install -c k2-fsa -c k2-fsa-sherpa -c kaldifeat -c kaldi_native_io -c pytorch cpuonly k2 sherpa kaldifeat kaldi_native_io pytorch=1.12.0 python=3.8
-
-.. note::
-
- You have to specify ``cpuonly`` to install a CPU version of ``sherpa``.
-
-.. caution::
-
- It is of paramount importance that you specify the ``-c`` options while
- installing ``sherpa``. Otherwise, you will be SAD.
-
- You can switch the orders of different options for ``-c``, but you cannot
- omit them.
-
-We provide pre-built conda packages for ``Python >= 3.7`` and ``PyTorch >= 1.6.0``.
-Please consider installing ``sherpa`` from source if you have other requirements.
-
-You can use:
-
-.. code-block:: bash
-
- conda search -c k2-fsa-sherpa sherpa
-
-to check all available ``sherpa`` packages for different combinations of
-``Python`` and ``PyTorch``. A sample output of the above command is listed below:
-
-.. code-block:: bash
-
- Loading channels: done
- # Name Version Build Channel
- sherpa 0.6 cpu_py3.10_torch1.11.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.10_torch1.12.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.10_torch1.12.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.2 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.11.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.12.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.12.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.6.0 k2-fsa-sherpa
-
-To check whether you have installed ``sherpa`` successfully, you can run:
-
-.. code-block:: bash
-
- sherpa --help
-
-which should show the usage information of ``sherpa``.
-
-To display the information about the environment used to build ``sherpa``, you
-can use:
-
-.. code-block:: bash
-
- sherpa-version
-
-Read :ref:`cpp_non_streaming_asr` to find more.
-
-CUDA version
-------------
-
-To be done.
-
-If you have any issues about installing ``sherpa``, please create an issue
-at the following address:
-
- ``_
-
-.. hint::
-
- If you have a `WeChat `_ account, you can scan
- the following QR code to join the WeChat group of next-gen Kaldi to get
- help.
-
- .. image:: pic/wechat-group-for-next-gen-kaldi.jpg
- :width: 200
- :align: center
- :alt: WeChat group of next-gen Kaldi
diff --git a/docs/source/cpp/installation/conda-windows.rst b/docs/source/cpp/installation/conda-windows.rst
deleted file mode 100644
index 0fa78df78..000000000
--- a/docs/source/cpp/installation/conda-windows.rst
+++ /dev/null
@@ -1,152 +0,0 @@
-conda for Windows
-=================
-
-.. note::
-
- We recommend creating a new virtual environment to install ``sherpa``.
-
-.. hint::
-
- At present, we only provide CPU version of pre-built conda packages for
- Windows. If you want to use a CUDA version of ``sherpa``, please consider
- installing ``sherpa`` from source.
-
-The command to install ``sherpa`` for Windows using ``conda`` is:
-
-.. code-block:: bash
-
- conda install \
- -c k2-fsa \
- -c k2-fsa-sherpa \
- -c kaldifeat \
- -c kaldi_native_io \
- -c pytorch \
- k2 \
- sherpa \
- kaldifeat \
- kaldi_native_io \
- pytorch=1.12.0 \
- python=3.8
-
-or the following command in one line:
-
-.. code-block:: bash
-
- conda install -c k2-fsa -c k2-fsa-sherpa -c kaldifeat -c kaldi_native_io -c pytorch k2 sherpa kaldifeat kaldi_native_io pytorch=1.12.0 python=3.8
-
-.. caution::
-
- It is of paramount importance that you specify the ``-c`` options while
- installing ``sherpa``. Otherwise, you will be SAD.
-
- You can switch the orders of different options for ``-c``, but you cannot
- omit them.
-
-We provide pre-built conda packages for ``Python >= 3.7`` and ``PyTorch >= 1.6.0``.
-Please consider installing ``sherpa`` from source if you have other requirements.
-
-
-You can use:
-
-.. code-block:: bash
-
- conda search -c k2-fsa-sherpa sherpa
-
-to check all available ``sherpa`` packages for different combinations of
-``Python`` and ``PyTorch``. A sample output of the above command is listed below:
-
-.. code-block:: bash
-
- Loading channels: done
- # Name Version Build Channel
- sherpa 0.6 cpu_py3.10_torch1.11.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.10_torch1.12.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.10_torch1.12.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.10.2 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.11.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.12.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.12.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.8.0 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.8.1 k2-fsa-sherpa
- sherpa 0.6 cpu_py3.7_torch1.9.0 k2-fsa-sherpa
-
-Settings after installation
----------------------------
-
-Suppose that you have created an environment named ``sherpa`` for installation
-using the following commands:
-
-.. code-block:: bash
-
- conda create -n sherpa
- conda activate sherpa
-
-To check whether you have installed ``sherpa`` successfully or not, please run
-the following command:
-
-.. code-block:: bash
-
- (sherpa) fangjun@M-0LQSDCC2RV398 C:\Users\fangjun>sherpa
- 'sherpa' is not recognized as an internal or external command,
- operable program or batch file.
-
-It reports that Windows cannot find the executable ``sherpa.exe``. We have
-to set the following environment variable:
-
-.. code-block:: bash
-
- (sherpa) fangjun@M-0LQSDCC2RV398 C:\Users\fangjun>set path=%conda_prefix%\lib\site-packages\sherpa\bin;%path%
-
-After setting the ``path`` environment variable, we can run ``sherpa`` again:
-
-.. code-block:: bash
-
- (sherpa) fangjun@M-0LQSDCC2RV398 C:\Users\fangjun>sherpa
-
- (sherpa) fangjun@M-0LQSDCC2RV398 C:\Users\fangjun>sherpa --help
-
- (sherpa) fangjun@M-0LQSDCC2RV398 C:\Users\fangjun>
-
-It does not complain about being not able to find ``sherpa.exe``. However, it
-prints nothing.
-
-The reason is that ``sherpa.exe`` cannot find ``torch_cpu.dll``. You have to
-add another directory to the environment variable ``path`` using:
-
-.. code-block:: bash
-
- set path=%conda_prefix%\lib\site-packages\torch\lib;%path%
-
-Now you can run ``sherpa`` in the commandline:
-
-.. code-block:: bash
-
- sherpa --help
-
-You will get something like the following screenshot:
-
- .. image:: pic/conda-windows-2.png
- :align: center
- :alt: Output of ``shepa --help``
-
-Congratulations! You have succeeded in installing ``sherpa`` on Windows.
-
-Read :ref:`cpp_non_streaming_asr` to find more.
-
-If you have any issues about installing ``sherpa``, please create an issue
-at the following address:
-
- ``_
-
-.. hint::
-
- If you have a `WeChat `_ account, you can scan
- the following QR code to join the WeChat group of next-gen Kaldi to get
- help.
-
- .. image:: pic/wechat-group-for-next-gen-kaldi.jpg
- :width: 200
- :align: center
- :alt: WeChat group of next-gen Kaldi
diff --git a/docs/source/cpp/installation/from-source.rst b/docs/source/cpp/installation/from-source.rst
deleted file mode 100644
index 2ec838406..000000000
--- a/docs/source/cpp/installation/from-source.rst
+++ /dev/null
@@ -1,107 +0,0 @@
-.. role:: strike
-
-.. _cpp_installation:
-
-Install from source (Linux/macOS/Windows)
-=========================================
-
-Install dependencies
---------------------
-
-Install k2
-^^^^^^^^^^
-
-First, please refer to ``_
-to install `k2`_.
-
-.. hint::
-
- If you are using macOS, you can dowload pre-built wheels from
- ``_
-
-
-Install other dependencies
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: bash
-
- pip install -U kaldifeat kaldi_native_io
-
-Install from source
--------------------
-
-You can select ``one`` of the following methods to install ``sherpa``
-from source.
-
-Option 1
-^^^^^^^^
-
-.. code-block:: bash
-
- git clone https://github.com/k2-fsa/sherpa
- cd sherpa
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release ..
- make -j
-
-
-After running the above commands, you will get two executables:
-``./bin/sherpa`` and ``./bin/sherpa-version`` in the build directory.
-
-You can use
-
-.. code-block:: bash
-
- ./bin/sherpa --help
-
-to view usage information.
-
-``./bin/sherpa-version`` displays the information about the environment that
-was used to build ``sherpa``.
-
-Please read the section :ref:`cpp_non_streaming_asr` for more details.
-
-Option 2
-^^^^^^^^
-
-.. code-block:: bash
-
- git clone https://github.com/k2-fsa/sherpa
- cd sherpa
- python3 setup.py bdist_wheel
-
- # It will generate a file in ./dist
- # For instance, if the file is ./dist/k2_sherpa-0.7.1-cp38-cp38-linux_x86_64.whl
- # You can use
-
- pip install ./dist/k2_sherpa-0.7.1-cp38-cp38-linux_x86_64.whl
-
- # If you want to uninstall it, use
- #
- # pip uninstall k2-sherpa
- #
-
-
-.. caution::
-
- The command to uninstall ``sherpa`` is ``pip uninstall k2-sherpa``,
- **NOT** :strike:`pip uninstall sherpa`
-
-.. hint::
-
- If you use ``python3 setup.py install``, you won't find the executable
- ``sherpa`` and ``sherpa-version`` in your PATH.
-
-To check that you have installed ``sherpa`` successfully, you can use:
-
-.. code-block:: bash
-
- which sherpa
- which sherpa-version
-
- sherpa-version
-
-
- sherpa --help
-
diff --git a/docs/source/cpp/installation/index.rst b/docs/source/cpp/installation/index.rst
index 1e26b4bdf..adc354b99 100644
--- a/docs/source/cpp/installation/index.rst
+++ b/docs/source/cpp/installation/index.rst
@@ -1,14 +1,86 @@
-.. _cpp_fronted_installation:
+.. _cpp_installation:
-C++ frontend Installation
-=========================
+Installation
+============
+Before installing `sherpa`_, we assume you have installed:
-You can select ``one`` of the following methods for installation.
+- `PyTorch`_
+- `k2`_
+- `kaldifeat`_
-.. toctree::
- :maxdepth: 1
+You can use the following commands to install `sherpa`_:
- conda-windows
- conda-linux
- from-source
+.. code-block:: bash
+
+ git clone http://github.com/k2-fsa/sherpa
+ cd sherpa
+ python3 setup.py bdist_wheel
+ ls -lh dist
+ pip install ./dist/k2_sherpa*.whl
+
+.. caution::
+
+ Please don't use ``python3 setup.py install``. Otherwise, you won't get
+ `sherpa`_ related binaries installed, such as ``sherpa-offline`` and
+ ``sherpa-online``.
+
+To uninstall `sherpa`_, please use
+
+.. code-block:: bash
+
+ pip uninstall k2-sherpa
+
+To test that you have installed `sherpa`_ successfully, you can run the
+following commands:
+
+.. code-block:: bash
+
+ sherpa-version
+
+ sherpa-offline --help
+ sherpa-online --help
+ sherpa-online-microphone --help
+
+ sherpa-offline-websocket-server --help
+ sherpa-offline-websocket-client --help
+
+ sherpa-online-websocket-server --help
+ sherpa-online-websocket-client --help
+ sherpa-online-websocket-client-microphone --help
+
+If you have any issues about the installation, please create an issue
+at the following address:
+
+ ``_
+
+.. hint::
+
+ If you have a `WeChat `_ account, you can scan
+ the following QR code to join the WeChat group of next-gen Kaldi to get
+ help.
+
+ .. image:: pic/wechat-group-for-next-gen-kaldi.jpg
+ :width: 200
+ :align: center
+ :alt: WeChat group of next-gen Kaldi
+
+
+Installation for advanced users/developers
+------------------------------------------
+
+As an advanced user/developer, you can use the following method to
+install `sherpa`_:
+
+
+.. code-block:: bash
+
+ git clone http://github.com/k2-fsa/sherpa
+ cd sherpa
+ mkdir build
+ cd build
+ cmake ..
+ make -j
+
+ export PATH=$PWD/bin:$PATH
+ export PYTHONPATH=$PWD/lib:$PWD/../sherpa/python:$PYTHONPATH
diff --git a/docs/source/cpp/offline_asr/gigaspeech.rst b/docs/source/cpp/offline_asr/gigaspeech.rst
index 43425848d..fc50914f0 100644
--- a/docs/source/cpp/offline_asr/gigaspeech.rst
+++ b/docs/source/cpp/offline_asr/gigaspeech.rst
@@ -4,7 +4,7 @@ Pretrained model with GigaSpeech
.. hint::
We assume you have installed ``sherpa`` by following
- :ref:`cpp_fronted_installation` before you start this section.
+ :ref:`cpp_installation` before you start this section.
Download the pretrained model
-----------------------------
diff --git a/docs/source/cpp/offline_asr/wenetspeech.rst b/docs/source/cpp/offline_asr/wenetspeech.rst
index 1838dcc52..fcc3485d0 100644
--- a/docs/source/cpp/offline_asr/wenetspeech.rst
+++ b/docs/source/cpp/offline_asr/wenetspeech.rst
@@ -4,7 +4,7 @@ Pretrained model with WenetSpeech
.. hint::
We assume you have installed ``sherpa`` by following
- :ref:`cpp_fronted_installation` before you start this section.
+ :ref:`cpp_installation` before you start this section.
Download the pretrained model
-----------------------------
diff --git a/docs/source/cpp/online_asr/index.rst b/docs/source/cpp/online_asr/index.rst
new file mode 100644
index 000000000..a35089298
--- /dev/null
+++ b/docs/source/cpp/online_asr/index.rst
@@ -0,0 +1,59 @@
+.. _cpp_streaming_asr:
+
+Streaming ASR
+=============
+
+This page describes how to use the C++ API of `sherpa`_ for
+streaming/online ASR.
+
+.. warning::
+
+ It supports only models from
+ ``_
+ at present.
+
+Please refer to :ref:`cpp_installation` for installation.
+
+
+After running ``make -j``, you should find the following files:
+
+ - ``lib/libsherpa_online_recognizer.so``
+ - ``include/sherpa/cpp_api/online_recognizer.h``
+ - ``include/sherpa/cpp_api/online_stream.h``
+
+You can include the above two header files in your application and link
+``libsherpa_online_recognizer.so`` with you executable to use the C++ APIs.
+
+
+``_
+shows how to use the C++ API for real-time speech recognition with a microphone.
+After running ``make -j``, you can also find an executable ``bin/test_online_recognizer_microphone``.
+The following shows how to use it:
+
+.. code-block:: bash
+
+ cd /path/to/sherpa/build
+
+ git lfs install
+ git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05
+
+ ./bin/test_online_recognizer_microphone \
+ ./icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05/exp/cpu-jit-epoch-30-avg-10-torch-1.10.0.pt \
+ ./icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05/data/lang_bpe_500/tokens.txt
+
+It will print something like below:
+
+.. code-block::
+
+ num devices: 4
+ Use default device: 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Started
+
+Say something and you will see the recognition result printed to the console in real-time.
+
+You can find a demo below:
+
+.. youtube:: 86-YLg3u-WY
+ :width: 120%
diff --git a/docs/source/cpp/pretrained_models/index.rst b/docs/source/cpp/pretrained_models/index.rst
new file mode 100644
index 000000000..28963252a
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/index.rst
@@ -0,0 +1,60 @@
+.. _pretrained_models:
+
+Pre-trained models
+==================
+
+Two kinds of end-to-end (E2E) models are supported by `sherpa`_:
+
+- CTC
+- Transducer
+
+.. hint::
+
+ For transducer-based models, we only support stateless transducers.
+ To the best of our knowledge, only `icefall`_ supports that. In other words,
+ only transducer models from `icefall`_ are currently supported.
+
+ For CTC-based models, we support any type of models trained using CTC loss
+ as long as you can export the model via torchscript. Models from the following
+ frameworks are currently supported: `icefall`_, `WeNet`_, and `torchaudio`_ (Wav2Vec 2.0).
+ If you have a CTC model and want it to be supported in `sherpa`, please
+ create an issue at ``_.
+
+.. hint::
+
+ You can try the pre-trained models in your browser without installing
+ anything. See ``_.
+
+
+This page lists all available pre-trained models that you can download.
+
+.. hint::
+
+ We provide pre-trained models for the following languages:
+
+ - Arabic
+ - Chinese
+ - English
+ - German
+ - Tibetan
+
+
+.. hint::
+
+ We provide a colab notebook
+ |Sherpa offline recognition python api colab notebook|
+ for you to try offline recognition step by step.
+
+ It shows how to install sherpa and use it as offline recognizer,
+ which supports the models from icefall, the `WeNet`_ framework and torchaudio.
+
+.. |Sherpa offline recognition python api colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://colab.research.google.com/drive/1RdU06GcytTpI-r8vkQ7NkI0ugytnwJVB?usp=sharing
+
+.. toctree::
+ :maxdepth: 5
+ :caption: Pretrained models
+
+ offline_ctc/index
+ offline_transducer
+ online_transducer
diff --git a/docs/source/cpp/pretrained_models/offline_ctc/icefall.rst b/docs/source/cpp/pretrained_models/offline_ctc/icefall.rst
new file mode 100644
index 000000000..072aaf292
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_ctc/icefall.rst
@@ -0,0 +1,215 @@
+icefall
+=======
+
+.. hint::
+
+ We use the binary ``sherpa-offline`` below for demonstration.
+ You can replace ``sherpa-offline`` with ``sherpa-offline-websocket-server``.
+
+In this section, we list all pre-trained CTC models from `icefall`_.
+
+icefall-asr-gigaspeech-conformer-ctc (English)
+----------------------------------------------
+
+.. code-block:: bash
+
+ # This model is trained using GigaSpeech
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/wgb14/icefall-asr-gigaspeech-conformer-ctc
+ cd icefall-asr-gigaspeech-conformer-ctc
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/HLG.pt"
+ git lfs pull --include "data/lang_bpe_500/tokens.txt"
+ mkdir test_wavs
+ cd test_wavs
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1089-134686-0001.wav
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1221-135766-0001.wav
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1221-135766-0002.wav
+ cd ..
+
+ # Decode with H
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+ # Decode with HLG
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --hlg=./data/lang_bpe_500/HLG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-conformer-ctc-jit-bpe-500-2021-11-09 (English)
+----------------------------------------------------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-conformer-ctc-jit-bpe-500-2021-11-09
+ cd icefall-asr-librispeech-conformer-ctc-jit-bpe-500-2021-11-09
+
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/tokens.txt"
+ git lfs pull --include "data/lang_bpe_500/HLG.pt"
+ git lfs pull --include "data/lang_bpe_500/HLG_modified.pt"
+
+ # Decode with H
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ --use-gpu=false \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+ # Decode with HLG
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ --hlg=./data/lang_bpe_500/HLG.pt \
+ --use-gpu=false \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+ # Decode with HLG (modified)
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ --hlg=./data/lang_bpe_500/HLG_modified.pt \
+ --use-gpu=false \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-tedlium3-conformer-ctc2 (English)
+---------------------------------------------
+
+.. code-block:: bash
+
+ # This model is trained using Tedlium3
+ #
+ # See https://github.com/k2-fsa/icefall/pull/696
+ #
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/videodanchik/icefall-asr-tedlium3-conformer-ctc2
+ cd icefall-asr-tedlium3-conformer-ctc2
+ git lfs pull --include "exp/cpu_jit.pt"
+
+ git lfs pull --include "data/lang_bpe/HLG.pt"
+ git lfs pull --include "data/lang_bpe/tokens.txt"
+
+ git lfs pull --include "test_wavs/DanBarber_2010-219.wav"
+ git lfs pull --include "test_wavs/DanielKahneman_2010-157.wav"
+ git lfs pull --include "test_wavs/RobertGupta_2010U-15.wav"
+
+ # Decode with H
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe/tokens.txt \
+ ./test_wavs/DanBarber_2010-219.wav \
+ ./test_wavs/DanielKahneman_2010-157.wav \
+ ./test_wavs/RobertGupta_2010U-15.wav
+
+ # Decode with HLG
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --hlg=./data/lang_bpe/HLG.pt \
+ --tokens=./data/lang_bpe/tokens.txt \
+ ./test_wavs/DanBarber_2010-219.wav \
+ ./test_wavs/DanielKahneman_2010-157.wav \
+ ./test_wavs/RobertGupta_2010U-15.wav
+
+icefall_asr_librispeech_conformer_ctc (English)
+-----------------------------------------------
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/13
+ #
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/pkufool/icefall_asr_librispeech_conformer_ctc
+ cd icefall_asr_librispeech_conformer_ctc
+
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe/HLG.pt"
+
+ # Decode with H
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+ # Decode with HLG
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --hlg=./data/lang_bpe/HLG.pt \
+ --tokens=./data/lang_bpe/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+.. - ``_
+
+icefall_asr_aishell_conformer_ctc (Chinese)
+-------------------------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/pkufool/icefall_asr_aishell_conformer_ctc
+ cd icefall_asr_aishell_conformer_ctc
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_char/HLG.pt"
+
+ # Decode with an H graph
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_waves/BAC009S0764W0121.wav \
+ ./test_waves/BAC009S0764W0122.wav \
+ ./test_waves/BAC009S0764W0123.wav
+
+ # Decode with an HLG graph
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ --hlg=./data/lang_char/HLG.pt \
+ ./test_waves/BAC009S0764W0121.wav \
+ ./test_waves/BAC009S0764W0122.wav \
+ ./test_waves/BAC009S0764W0123.wav
+
+
+icefall-asr-mgb2-conformer_ctc-2022-27-06 (Arabic)
+--------------------------------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/AmirHussein/icefall-asr-mgb2-conformer_ctc-2022-27-06
+ cd icefall-asr-mgb2-conformer_ctc-2022-27-06
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_5000/HLG.pt"
+ git lfs pull --include "data/lang_bpe_5000/tokens.txt"
+
+ # Decode with an H graph
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_5000/tokens.txt \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0053813:0054281.wav \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0051454:0052244.wav \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0052244:0053004.wav
+
+ # Decode with an HLG graph
+ sherpa-offline \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_5000/tokens.txt \
+ --hlg=./data/lang_bpe_5000/HLG.pt \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0053813:0054281.wav \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0051454:0052244.wav \
+ ./test_wavs/94D37D38-B203-4FC0-9F3A-538F5C174920_spk-0001_seg-0052244:0053004.wav
diff --git a/docs/source/cpp/pretrained_models/offline_ctc/index.rst b/docs/source/cpp/pretrained_models/offline_ctc/index.rst
new file mode 100644
index 000000000..09b3bc587
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_ctc/index.rst
@@ -0,0 +1,13 @@
+Offline CTC models
+==================
+
+This section list pre-trained CTC models from the following frameworks:
+
+.. toctree::
+ :maxdepth: 2
+
+ icefall
+ wenet
+ torchaudio
+ nemo
+
diff --git a/docs/source/cpp/pretrained_models/offline_ctc/nemo.rst b/docs/source/cpp/pretrained_models/offline_ctc/nemo.rst
new file mode 100644
index 000000000..1acb46b9a
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_ctc/nemo.rst
@@ -0,0 +1,315 @@
+NeMo
+====
+
+This section lists models from `NeMo`_.
+
+
+sherpa-nemo-ctc-en-citrinet-512 (English)
+-----------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-en-citrinet-512
+ cd sherpa-nemo-ctc-en-citrinet-512
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 kuangfangjun root 142M Mar 9 21:23 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-zh-citrinet-512 (Chinese)
+-----------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-zh-citrinet-512
+ cd sherpa-nemo-ctc-zh-citrinet-512
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=true \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 kuangfangjun root 153M Mar 10 15:07 model.pt
+
+.. hint::
+
+ Since the vocabulary size of this model is very large, i.e, 5207, we use
+ ``--modified=true`` to use a
+ `modified CTC topology `_
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-zh-citrinet-1024-gamma-0-25 (Chinese)
+-----------------------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-zh-citrinet-1024-gamma-0-25
+ cd sherpa-nemo-ctc-zh-citrinet-1024-gamma-0-25
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=true \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 kuangfangjun root 557M Mar 10 16:29 model.pt
+
+.. hint::
+
+ Since the vocabulary size of this model is very large, i.e, 5207, we use
+ ``--modified=true`` to use a
+ `modified CTC topology `_
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-de-citrinet-1024 (German)
+-----------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-de-citrinet-1024
+ cd sherpa-nemo-ctc-de-citrinet-1024
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 kuangfangjun root 541M Mar 10 16:55 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+
+sherpa-nemo-ctc-en-conformer-small (English)
+--------------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block::
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-en-conformer-small
+ cd sherpa-nemo-ctc-en-conformer-small
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 fangjun staff 82M Mar 10 19:55 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-en-conformer-medium (English)
+---------------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. code-block::
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-en-conformer-medium
+ cd sherpa-nemo-ctc-en-conformer-medium
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 fangjun staff 152M Mar 10 20:26 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-en-conformer-large (English)
+--------------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. hint::
+
+ The vocabulary size is 129
+
+.. code-block::
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-en-conformer-large
+ cd sherpa-nemo-ctc-en-conformer-large
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 fangjun staff 508M Mar 10 20:44 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+sherpa-nemo-ctc-de-conformer-large (German)
+-------------------------------------------
+
+This model is converted from
+
+ ``_
+
+.. hint::
+
+ The vocabulary size is 129
+
+.. code-block::
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-nemo-ctc-de-conformer-large
+ cd sherpa-nemo-ctc-de-conformer-large
+ git lfs pull --include "model.pt"
+
+ sherpa-offline \
+ --nn-model=./model.pt \
+ --tokens=./tokens.txt \
+ --use-gpu=false \
+ --modified=false \
+ --nemo-normalize=per_feature \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav
+
+.. code-block:: bash
+
+ ls -lh model.pt
+ -rw-r--r-- 1 fangjun staff 508M Mar 10 21:34 model.pt
+
+.. caution::
+
+ It is of paramount importance to specify ``--nemo-normalize=per_feature``.
+
+How to convert NeMo models to sherpa
+------------------------------------
+
+This section describes how to export `NeMo`_ pre-trained CTC models to `sherpa`_.
+
+You can find a list of pre-trained models from `NeMo`_ by visiting:
+
+ ``_.
+
+Let us take ``stt_en_conformer_ctc_small`` as an example.
+
+You can use the following code to obtain ``model.pt`` and ``tokens.txt``:
+
+.. code-block:: bash
+
+ import nemo.collections.asr as nemo_asr
+ m = nemo_asr.models.EncDecCTCModelBPE.from_pretrained('stt_en_conformer_ctc_small')
+ m.export("model.pt")
+
+ with open('tokens.txt', 'w', encoding='utf-8') as f:
+ f.write(" 0\n")
+ for i, s in enumerate(m.decoder.vocabulary):
+ f.write(f"{s} {i+1}\n")
+
+One thing to note is that the blank token has the largest token ID in ``NeMo``.
+However, it is always ``0`` in `sherpa`_. During network computation, we shift
+the last column of the ``log_prob`` tensor to the first column so that
+it matches the convention about using 0 for the blank in `sherpa`_.
+
+You can find the exported ``model.pt`` and ``tokens.txt`` by visiting
+
+ ``_
diff --git a/docs/source/cpp/pretrained_models/offline_ctc/torchaudio.rst b/docs/source/cpp/pretrained_models/offline_ctc/torchaudio.rst
new file mode 100644
index 000000000..65e7381f1
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_ctc/torchaudio.rst
@@ -0,0 +1,42 @@
+torchaudio
+==========
+
+This section lists models from `torchaudio`_.
+
+
+wav2vec2_asr_base (English)
+---------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio
+ cd wav2vec2.0-torchaudio
+
+ # Note: There are other kinds of models fine-tuned with different
+ # amount of data. We use a model that is fine-tuned with 10 minutes of data.
+
+ git lfs pull --include "wav2vec2_asr_base_10m.pt"
+
+ sherpa-offline \
+ --nn-model=wav2vec2_asr_base_10m.pt \
+ --tokens=tokens.txt \
+ --use-gpu=false \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+voxpopuli_asr_base (German)
+---------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio
+ cd wav2vec2.0-torchaudio
+ git lfs pull --include "voxpopuli_asr_base_10k_de.pt"
+
+ sherpa-offline \
+ --nn-model=voxpopuli_asr_base_10k_de.pt \
+ --tokens=tokens-de.txt \
+ --use-gpu=false \
+ ./test_wavs/20120315-0900-PLENARY-14-de_20120315.wav \
+ ./test_wavs/20170517-0900-PLENARY-16-de_20170517.wav
diff --git a/docs/source/cpp/pretrained_models/offline_ctc/wenet.rst b/docs/source/cpp/pretrained_models/offline_ctc/wenet.rst
new file mode 100644
index 000000000..ccf0bcb6a
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_ctc/wenet.rst
@@ -0,0 +1,44 @@
+WeNet
+=====
+
+This section lists models from `WeNet`_.
+
+wenet-english-model (English)
+-----------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/wenet-english-model
+ cd wenet-english-model
+ git lfs pull --include "final.zip"
+
+ sherpa-offline \
+ --normalize-samples=false \
+ --modified=true \
+ --nn-model=./final.zip \
+ --tokens=./units.txt \
+ --use-gpu=false \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+wenet-chinese-model (Chinese)
+-----------------------------
+
+.. code-block:: bash
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/wenet-chinese-model
+ cd wenet-chinese-model
+ git lfs pull --include "final.zip"
+
+ sherpa-offline \
+ --normalize-samples=false \
+ --modified=true \
+ --nn-model=./final.zip \
+ --tokens=./units.txt \
+ ./test_wavs/BAC009S0764W0121.wav \
+ ./test_wavs/BAC009S0764W0122.wav \
+ ./test_wavs/BAC009S0764W0123.wav \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
diff --git a/docs/source/cpp/pretrained_models/offline_transducer.rst b/docs/source/cpp/pretrained_models/offline_transducer.rst
new file mode 100644
index 000000000..fb8e5ffda
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/offline_transducer.rst
@@ -0,0 +1,605 @@
+.. _offline_transducer_pretrained_models:
+
+Offline transducer models
+=========================
+
+.. hint::
+
+ We use the binary ``sherpa-offline`` below for demonstration.
+ You can replace ``sherpa-offline`` with ``sherpa-offline-websocket-server``.
+
+.. hint::
+
+ Please visit ``_
+ to try the pre-trained models in your browser. You don't need to install
+ anything.
+
+icefall
+-------
+
+This section lists models trained using `icefall`_.
+
+English
+^^^^^^^
+
+
+icefall-asr-cv-corpus-13.0-2023-03-09-en-pruned-transducer-stateless7-2023-04-17
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using Common Voice 13.0 with zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/997
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/yfyeung/icefall-asr-cv-corpus-13.0-2023-03-09-en-pruned-transducer-stateless7-2023-04-17
+ cd icefall-asr-cv-corpus-13.0-2023-03-09-en-pruned-transducer-stateless7-2023-04-17
+
+ git lfs pull --include "cpu_jit-epoch-60-avg-20.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit-epoch-60-avg-20.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+.. _icefall-asr-librispeech-zipformer-2023-05-15:
+
+icefall-asr-librispeech-zipformer-2023-05-15
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1058
+ #
+ # normal-scaled model, number of model parameters: 65549011, i.e., 65.55 M
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-zipformer-2023-05-15
+ cd icefall-asr-librispeech-zipformer-2023-05-15
+
+ git lfs pull --include "exp/jit_script.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+.. _icefall-asr-librispeech-zipformer-small-2023-05-16:
+
+icefall-asr-librispeech-zipformer-small-2023-05-16
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1058
+ #
+ # small-scaled model, number of model parameters: 23285615, i.e., 23.3 M
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-zipformer-small-2023-05-16
+ cd icefall-asr-librispeech-zipformer-small-2023-05-16
+
+ git lfs pull --include "exp/jit_script.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+
+.. _icefall-asr-librispeech-zipformer-large-2023-05-16:
+
+icefall-asr-librispeech-zipformer-large-2023-05-16
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1058
+ #
+ # large-scaled model, number of model parameters: 148439574, i.e., 148.4 M
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-zipformer-large-2023-05-16
+ cd icefall-asr-librispeech-zipformer-large-2023-05-16
+
+ git lfs pull --include "exp/jit_script.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+.. _icefall-asr-multidataset-pruned_transducer_stateless7-2023-05-04:
+
+icefall-asr-multidataset-pruned_transducer_stateless7-2023-05-04
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using GigaSpeech + LibriSpeech + Common Voice 13.0 with zipformer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1010
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/yfyeung/icefall-asr-multidataset-pruned_transducer_stateless7-2023-05-04
+ cd icefall-asr-multidataset-pruned_transducer_stateless7-2023-05-04
+ git lfs pull --include "exp/cpu_jit-epoch-30-avg-4.pt"
+ cd exp
+ ln -s cpu_jit-epoch-30-avg-4.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+.. _icefall-asr-librispeech-pruned-transducer-stateless8-2022-12-02:
+
+icefall-asr-librispeech-pruned-transducer-stateless8-2022-12-02
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using GigaSpeech + LibriSpeech with zipformer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/728
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/WeijiZhuang/icefall-asr-librispeech-pruned-transducer-stateless8-2022-12-02
+ cd icefall-asr-librispeech-pruned-transducer-stateless8-2022-12-02
+ git lfs pull --include "exp/cpu_jit-torch-1.10.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ cd exp
+ rm cpu_jit.pt
+ ln -sv cpu_jit-torch-1.10.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-pruned-transducer-stateless8-2022-11-14
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using GigaSpeech + LibriSpeech with zipformer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/675
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-transducer-stateless8-2022-11-14
+ cd icefall-asr-librispeech-pruned-transducer-stateless8-2022-11-14
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-pruned-transducer-stateless7-2022-11-11
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with zipformer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/672
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-transducer-stateless7-2022-11-11
+ cd icefall-asr-librispeech-pruned-transducer-stateless7-2022-11-11
+ git lfs pull --include "exp/cpu_jit-torch-1.10.0.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+ cd exp
+ ln -s cpu_jit-torch-1.10.0.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block::
+
+ # This model is trained using LibriSpeech + GigaSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/363
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13
+ cd icefall-asr-librispeech-pruned-transducer-stateless3-2022-05-13
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+
+icefall-asr-gigaspeech-pruned-transducer-stateless2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block::
+
+ # This model is trained using GigaSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/318
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-gigaspeech-pruned-transducer-stateless2
+ cd icefall-asr-gigaspeech-pruned-transducer-stateless2
+ git lfs pull --include "exp/cpu_jit-iter-3488000-avg-15.pt"
+ git lfs pull --include "data/lang_bpe_500/bpe.model"
+
+ cd ../exp
+ ln -s cpu_jit-iter-3488000-avg-15.pt cpu_jit.pt
+ cd ..
+
+ # Since this repo does not provide tokens.txt, we generate it from bpe.model
+ # by ourselves
+ /path/to/sherpa/scripts/bpe_model_to_tokens.py ./data/lang_bpe_500/bpe.model > ./data/lang_bpe_500/tokens.txt
+
+ mkdir test_wavs
+ cd test_wavs
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1089-134686-0001.wav
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1221-135766-0001.wav
+ wget https://huggingface.co/csukuangfj/wav2vec2.0-torchaudio/resolve/main/test_wavs/1221-135766-0002.wav
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+Chinese
+^^^^^^^
+
+icefall-asr-zipformer-wenetspeech-20230615
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block::
+
+ # This model is trained using WenetSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1130
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/pkufool/icefall-asr-zipformer-wenetspeech-20230615
+
+ cd icefall-asr-zipformer-wenetspeech-20230615
+ git lfs pull --include "exp/jit_script.pt"
+ git lfs pull --include "data/lang_char/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script.pt \
+ --lg=./data/lang_char/LG.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+
+
+icefall_asr_wenetspeech_pruned_transducer_stateless2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using WenetSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/349
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall_asr_wenetspeech_pruned_transducer_stateless2
+
+ cd icefall_asr_wenetspeech_pruned_transducer_stateless2
+ git lfs pull --include "exp/cpu_jit_epoch_10_avg_2_torch_1.7.1.pt"
+ git lfs pull --include "data/lang_char/LG.pt"
+ cd exp
+ ln -s cpu_jit_epoch_10_avg_2_torch_1.7.1.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_char/LG.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+
+icefall_asr_aidatatang-200zh_pruned_transducer_stateless2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using aidatatang_200zh
+ #
+ # See https://github.com/k2-fsa/icefall/pull/355
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall_asr_aidatatang-200zh_pruned_transducer_stateless2
+ cd icefall_asr_aidatatang-200zh_pruned_transducer_stateless2
+ git lfs pull --include "exp/cpu_jit_torch.1.7.1.pt"
+
+ cd exp
+ ln -sv cpu_jit_torch.1.7.1.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/T0055G0036S0002.wav \
+ ./test_wavs/T0055G0036S0003.wav \
+ ./test_wavs/T0055G0036S0004.wav
+ done
+
+icefall-asr-alimeeting-pruned-transducer-stateless7
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using alimeeting (https://www.openslr.org/119/)
+ #
+ # See https://github.com/k2-fsa/icefall/pull/751
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/desh2608/icefall-asr-alimeeting-pruned-transducer-stateless7
+ cd icefall-asr-alimeeting-pruned-transducer-stateless7
+
+ git lfs pull --include "exp/cpu_jit.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/165.wav \
+ ./test_wavs/74.wav \
+ ./test_wavs/209.wav
+ done
+
+Chinese + English
+^^^^^^^^^^^^^^^^^
+
+icefall_asr_tal-csasr_pruned_transducer_stateless5
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using TAL_CSASR dataset from
+ # https://ai.100tal.com/dataset
+ # where each utterance contains both English and Chinese.
+ #
+ # See https://github.com/k2-fsa/icefall/pull/428
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall_asr_tal-csasr_pruned_transducer_stateless5
+ cd icefall_asr_tal-csasr_pruned_transducer_stateless5
+ git lfs pull --include "exp/cpu_jit.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/210_36476_210_8341_1_1533271973_7057520_132.wav \
+ ./test_wavs/210_36476_210_8341_1_1533271973_7057520_138.wav \
+ ./test_wavs/210_36476_210_8341_1_1533271973_7057520_145.wav \
+ ./test_wavs/210_36476_210_8341_1_1533271973_7057520_148.wav
+ done
+
+Tibetan
+^^^^^^^
+
+icefall-asr-xbmu-amdo31-pruned-transducer-stateless7-2022-12-02
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using the XBMU-AMDO31 corpus
+ #
+ # See https://github.com/k2-fsa/icefall/pull/706
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/syzym/icefall-asr-xbmu-amdo31-pruned-transducer-stateless7-2022-12-02
+ cd icefall-asr-xbmu-amdo31-pruned-transducer-stateless7-2022-12-02
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/a_0_cacm-A70_31116.wav \
+ ./test_wavs/a_0_cacm-A70_31117.wav \
+ ./test_wavs/a_0_cacm-A70_31118.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/a_0_cacm-A70_31116.wav \
+ ./test_wavs/a_0_cacm-A70_31117.wav \
+ ./test_wavs/a_0_cacm-A70_31118.wav
+
+icefall-asr-xbmu-amdo31-pruned-transducer-stateless5-2022-11-29
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using the XBMU-AMDO31 corpus
+ #
+ # See https://github.com/k2-fsa/icefall/pull/706
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/syzym/icefall-asr-xbmu-amdo31-pruned-transducer-stateless5-2022-11-29
+ cd icefall-asr-xbmu-amdo31-pruned-transducer-stateless5-2022-11-29
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+ git lfs pull --include "data/lang_bpe_500/tokens.txt"
+ git lfs pull --include "exp/cpu_jit-epoch-28-avg-23-torch-1.10.0.pt"
+ git lfs pull --include "test_wavs/a_0_cacm-A70_31116.wav"
+ git lfs pull --include "test_wavs/a_0_cacm-A70_31117.wav"
+ git lfs pull --include "test_wavs/a_0_cacm-A70_31118.wav"
+
+ cd exp
+ rm cpu_jit.pt
+ ln -sv cpu_jit-epoch-28-avg-23-torch-1.10.0.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-offline \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/a_0_cacm-A70_31116.wav \
+ ./test_wavs/a_0_cacm-A70_31117.wav \
+ ./test_wavs/a_0_cacm-A70_31118.wav
+ done
+
+ sherpa-offline \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/a_0_cacm-A70_31116.wav \
+ ./test_wavs/a_0_cacm-A70_31117.wav \
+ ./test_wavs/a_0_cacm-A70_31118.wav
diff --git a/docs/source/cpp/pretrained_models/online_transducer.rst b/docs/source/cpp/pretrained_models/online_transducer.rst
new file mode 100644
index 000000000..65a136ff6
--- /dev/null
+++ b/docs/source/cpp/pretrained_models/online_transducer.rst
@@ -0,0 +1,396 @@
+.. _online_transducer_pretrained_models:
+
+Online transducer models
+========================
+
+.. hint::
+
+ We use the binary ``sherpa-online`` below for demonstration.
+ You can replace ``sherpa-online`` with ``sherpa-online-websocket-server``
+ and ``sherpa-online-microphone``.
+
+.. hint::
+
+ At present, only streaming transducer models from `icefall`_ are supported.
+
+icefall
+-------
+
+This section lists models trained using `icefall`_.
+
+
+English
+^^^^^^^
+
+.. _icefall-asr-librispeech-streaming-zipformer-2023-05-17:
+
+icefall-asr-librispeech-streaming-zipformer-2023-05-17
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1058
+ #
+ # normal-scaled model, number of model parameters: 66110931, i.e., 66.11 M
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-streaming-zipformer-2023-05-17
+ cd icefall-asr-librispeech-streaming-zipformer-2023-05-17
+
+ git lfs pull --include "exp/jit_script_chunk_16_left_128.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script_chunk_16_left_128.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script_chunk_16_left_128.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+.. _icefall-asr-librispeech-pruned-transducer-stateless7-streaming-2022-12-29:
+
+icefall-asr-librispeech-pruned-transducer-stateless7-streaming-2022-12-29
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with streaming zipformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/787
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Zengwei/icefall-asr-librispeech-pruned-transducer-stateless7-streaming-2022-12-29
+ cd icefall-asr-librispeech-pruned-transducer-stateless7-streaming-2022-12-29
+
+ git lfs pull --include "exp/cpu_jit.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with ConvEmformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/440
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05
+ cd icefall-asr-librispeech-conv-emformer-transducer-stateless2-2022-07-05
+
+ git lfs pull --include "exp/cpu-jit-epoch-30-avg-10-torch-1.10.0.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+ cd exp
+ ln -sv cpu-jit-epoch-30-avg-10-torch-1.10.0.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+
+ ./build/bin/sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-lstm-transducer-stateless2-2022-09-03
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with LSTM transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/558
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-lstm-transducer-stateless2-2022-09-03
+ cd icefall-asr-librispeech-lstm-transducer-stateless2-2022-09-03
+
+ git lfs pull --include "exp/encoder_jit_trace-iter-468000-avg-16.pt"
+ git lfs pull --include "exp/decoder_jit_trace-iter-468000-avg-16.pt"
+ git lfs pull --include "exp/joiner_jit_trace-iter-468000-avg-16.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+
+ cd exp
+ ln -sv encoder_jit_trace-iter-468000-avg-16.pt encoder_jit_trace.pt
+ ln -sv decoder_jit_trace-iter-468000-avg-16.pt decoder_jit_trace.pt
+ ln -sv joiner_jit_trace-iter-468000-avg-16.pt joiner_jit_trace.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --encoder-model=./exp/encoder_jit_trace.pt \
+ --decoder-model=./exp/decoder_jit_trace.pt \
+ --joiner-model=./exp/joiner_jit_trace.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --encoder-model=./exp/encoder_jit_trace.pt \
+ --decoder-model=./exp/decoder_jit_trace.pt \
+ --joiner-model=./exp/joiner_jit_trace.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with Emformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/390
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01
+ cd icefall-asr-librispeech-pruned-stateless-emformer-rnnt2-2022-06-01
+
+ git lfs pull --include "exp/cpu_jit-epoch-39-avg-6-use-averaged-model-1.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+ cd exp
+ ln -sv cpu_jit-epoch-39-avg-6-use-averaged-model-1.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_wavs/1089-134686-0001.wav \
+ ./test_wavs/1221-135766-0001.wav \
+ ./test_wavs/1221-135766-0002.wav
+
+
+icefall_librispeech_streaming_pruned_transducer_stateless4_20220625
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using LibriSpeech with Conformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/440
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall_librispeech_streaming_pruned_transducer_stateless4_20220625
+ cd icefall_librispeech_streaming_pruned_transducer_stateless4_20220625
+
+ git lfs pull --include "exp/cpu_jit-epoch-25-avg-3.pt"
+ git lfs pull --include "data/lang_bpe_500/LG.pt"
+ cd exp
+ ln -sv cpu_jit-epoch-25-avg-3.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_waves/1089-134686-0001.wav \
+ ./test_waves/1221-135766-0001.wav \
+ ./test_waves/1221-135766-0002.wav
+ done
+
+ # For fast_beam_search with LG
+
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_bpe_500/LG.pt \
+ --tokens=./data/lang_bpe_500/tokens.txt \
+ ./test_waves/1089-134686-0001.wav \
+ ./test_waves/1221-135766-0001.wav \
+ ./test_waves/1221-135766-0002.wav
+
+Chinese
+^^^^^^^
+
+icefall-asr-zipformer-wenetspeech-20230615
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using WenetSpeech
+ #
+ # See https://github.com/k2-fsa/icefall/pull/1130
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/pkufool/icefall-asr-zipformer-streaming-wenetspeech-20230615
+ cd icefall-asr-zipformer-streaming-wenetspeech-20230615
+
+ git lfs pull --include exp/jit_script_chunk_16_left_128.pt
+ git lfs pull --include "data/lang_char/LG.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/jit_script_chunk_16_left_128.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+ done
+
+ # For fast_beam_search with LG
+
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/jit_script_chunk_16_left_128.pt \
+ --lg=./data/lang_char/LG.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+
+icefall_asr_wenetspeech_pruned_transducer_stateless5_streaming
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ # This model is trained using WenetSpeech with Conformer transducer
+ #
+ # See https://github.com/k2-fsa/icefall/pull/447
+ #
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/icefall_asr_wenetspeech_pruned_transducer_stateless5_streaming
+ cd icefall_asr_wenetspeech_pruned_transducer_stateless5_streaming
+
+ git lfs pull --include "exp/cpu_jit_epoch_7_avg_1_torch.1.7.1.pt"
+ git lfs pull --include "data/lang_char/LG.pt"
+ cd exp
+ ln -sv cpu_jit_epoch_7_avg_1_torch.1.7.1.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+ done
+
+ # For fast_beam_search with LG
+
+ sherpa-online \
+ --decoding-method=fast_beam_search \
+ --nn-model=./exp/cpu_jit.pt \
+ --lg=./data/lang_char/LG.pt \
+ --tokens=./data/lang_char/tokens.txt \
+ ./test_wavs/DEV_T0000000000.wav \
+ ./test_wavs/DEV_T0000000001.wav \
+ ./test_wavs/DEV_T0000000002.wav
+
+Chinese + English (all-in-one)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+pfluo/k2fsa-zipformer-chinese-english-mixed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is a `streaming zipformer model `_
+
+.. code-block:: bash
+
+ # This model supports both Chinese and English
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/k2fsa-zipformer-chinese-english-mixed
+ cd k2fsa-zipformer-chinese-english-mixed
+ git lfs pull --include "exp/cpu_jit.pt"
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char_bpe/tokens.txt \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav \
+ ./test_wavs/3.wav \
+ ./test_wavs/4.wav
+ done
+
+icefall-asr-conv-emformer-transducer-stateless2-zh
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is a `ConvEmformer model `_
+
+.. code-block:: bash
+
+ # This model supports both Chinese and English
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/ptrnull/icefall-asr-conv-emformer-transducer-stateless2-zh
+ cd icefall-asr-conv-emformer-transducer-stateless2-zh
+ git lfs pull --include "exp/cpu_jit-epoch-11-avg-1.pt"
+ cd exp
+ ln -sv cpu_jit-epoch-11-avg-1.pt cpu_jit.pt
+ cd ..
+
+ for m in greedy_search modified_beam_search fast_beam_search; do
+ sherpa-online \
+ --decoding-method=$m \
+ --nn-model=./exp/cpu_jit.pt \
+ --tokens=./data/lang_char_bpe/tokens.txt \
+ ./test_wavs/0.wav \
+ ./test_wavs/1.wav \
+ ./test_wavs/2.wav \
+ ./test_wavs/3.wav \
+ ./test_wavs/4.wav
+ done
diff --git a/docs/source/python/huggingface/index.rst b/docs/source/huggingface/index.rst
similarity index 80%
rename from docs/source/python/huggingface/index.rst
rename to docs/source/huggingface/index.rst
index 5e24baf5f..11a6f3d7c 100644
--- a/docs/source/python/huggingface/index.rst
+++ b/docs/source/huggingface/index.rst
@@ -1,10 +1,9 @@
.. _try sherpa with huggingface:
-Try sherpa with Huggingface
-===========================
+Run Next-gen Kaldi in your browser
+==================================
-This page describes how to use `sherpa`_ for automatic speech recognition
-with `Huggingface`_.
+This page describes how to try Next-gen Kaldi in your browser.
.. hint::
@@ -15,8 +14,9 @@ The server is running on CPU within a docker container provided by
`Huggingface`_ and you use a browser to interact with it. The browser
can be run on Windows, macOS, Linux, or even on your phone or iPad.
-You can either upload a file for recognition or record your speech via
-a microphone from within the browser and submit it for recognition.
+You can upload a file for recognition, record your speech via
+a microphone from within the browser and submit it for recognition, or even
+provider an URL to an audio file for speech recognition.
Now let's get started.
@@ -33,6 +33,12 @@ and you will see a page like the following screenshot:
:alt: screenshot of ``_
:target: https://huggingface.co/spaces/k2-fsa/automatic-speech-recognition
+.. hint::
+
+ If you don't have access to `Huggingface`_, please visit the following mirror:
+
+ ``_
+
You can:
1. Select a language for recognition. Currently, we provide pre-trained models
@@ -76,3 +82,9 @@ We provide the following YouTube video demonstrating how to use
``_
.. youtube:: ElN3r9dkKE4
+
+Other Huggingface spaces
+------------------------
+
+- ASR + WebAssembly + sherpa-ncnn: Please see :ref:`try sherpa ncnn wasm with huggingface`
+- TTS: Please see: ``_
diff --git a/docs/source/python/huggingface/pic/hugging-face-sherpa-2.png b/docs/source/huggingface/pic/hugging-face-sherpa-2.png
similarity index 100%
rename from docs/source/python/huggingface/pic/hugging-face-sherpa-2.png
rename to docs/source/huggingface/pic/hugging-face-sherpa-2.png
diff --git a/docs/source/python/huggingface/pic/hugging-face-sherpa-3.png b/docs/source/huggingface/pic/hugging-face-sherpa-3.png
similarity index 100%
rename from docs/source/python/huggingface/pic/hugging-face-sherpa-3.png
rename to docs/source/huggingface/pic/hugging-face-sherpa-3.png
diff --git a/docs/source/python/huggingface/pic/hugging-face-sherpa.png b/docs/source/huggingface/pic/hugging-face-sherpa.png
similarity index 100%
rename from docs/source/python/huggingface/pic/hugging-face-sherpa.png
rename to docs/source/huggingface/pic/hugging-face-sherpa.png
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 16c344131..25a408348 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -6,33 +6,37 @@
sherpa
======
-`sherpa`_ is a framework for streaming and non-streaming
-automatic speech recognition (ASR).
+.. toctree::
+ :maxdepth: 2
-CPU-bound tasks, such as neural network computation, are implemented in
-C++; while IO-bound tasks, such as socket communication, are implemented
-in Python with `asyncio`_.
+ ./intro.rst
+ ./pdf.rst
+ ./social-groups.rst
+ ./huggingface/index.rst
+ ./pretrained-models.rst
-Python is responsible for managing threads, which call into C++ extensions
-with the `global interpreter lock (GIL) `_
-released so that multiple threads can run concurrently.
-The following content describes how to install `sherpa`_ and its usage
-for both streaming ASR and offline ASR (i.e., non-streaming ASR).
+.. toctree::
+ :maxdepth: 5
+ :caption: k2-fsa/sherpa
+
+ ./sherpa/index
.. toctree::
- :maxdepth: 2
- :caption: For Python users
+ :maxdepth: 5
+ :caption: k2-fsa/sherpa-ncnn
- ./python/huggingface/index
- ./python/installation/index
- ./python/streaming_asr/index
- ./python/offline_asr/index
- ./python/faq
+ ./ncnn/index
.. toctree::
- :maxdepth: 2
- :caption: For C++ users
+ :maxdepth: 5
+ :caption: k2-fsa/sherpa-onnx
+
+ ./onnx/index
+
+.. toctree::
+ :maxdepth: 5
+ :caption: Triton
+
+ ./triton/overview
- ./cpp/installation/index
- ./cpp/offline_asr/index
diff --git a/docs/source/intro.rst b/docs/source/intro.rst
new file mode 100644
index 000000000..3c6f4a2cc
--- /dev/null
+++ b/docs/source/intro.rst
@@ -0,0 +1,88 @@
+Introduction
+============
+
+`sherpa`_ is the deployment framework of the ``Next-gen Kaldi`` project.
+
+`sherpa`_ supports deploying speech related pre-trained models on various platforms
+with various language bindings.
+
+If you are interested in how to train your own model or fine tune a pre-trained
+model, please refer to `icefall`_.
+
+At present, `sherpa`_ has the following sub-projects:
+
+ - `k2-fsa/sherpa`_
+ - `k2-fsa/sherpa-onnx`_
+ - `k2-fsa/sherpa-ncnn`_
+
+
+The differences are compared below:
+
+.. list-table::
+
+ * - ****
+ - `k2-fsa/sherpa`_
+ - `k2-fsa/sherpa-onnx`_
+ - `k2-fsa/sherpa-ncnn`_
+ * - Installation difficulty
+ - **hard**
+ - ``easy``
+ - ``easy``
+ * - NN lib
+ - `PyTorch`_
+ - `onnxruntime`_
+ - `ncnn`_
+ * - CPU Support
+ - x86, x86_64
+ - | x86, x86_64,
+ | ``arm32``, ``arm64``
+ - | x86, x86_64,
+ | ``arm32``, ``arm64``,
+ | ``**RISC-V**``
+ * - GPU Support
+ - | Yes
+ | (with ``CUDA`` for NVIDIA GPUs)
+ - Yes
+ - | Yes
+ | (with ``Vulkan`` for ARM GPUs)
+ * - OS Support
+ - | Linux, Windows,
+ | macOS
+ - | Linux, Windows,
+ | macOS, ``iOS``,
+ | ``Android``
+ - | Linux, Windows,
+ | macOS, ``iOS``,
+ | ``Android``
+ * - Support batch_size > 1
+ - Yes
+ - Yes
+ - ``No``
+ * - Provided APIs
+ - C++, Python
+ - | C, C++, Python,
+ | C#, Java, Kotlin,
+ | Swift, Go,
+ | JavaScript, Dart
+ | Pascal, Rust
+ - | C, C++, Python,
+ | C#, Kotlin,
+ | Swift, Go
+ * - Supported functions
+ - | streaming speech recognition,
+ | non-streaming speech recognition
+ - | streaming speech recognition,
+ | non-streaming speech recognition,
+ | text-to-speech,
+ | speaker diarization,
+ | speaker identification,
+ | speaker verification,
+ | spoken language identification,
+ | audio tagging,
+ | VAD,
+ | keyword spotting,
+ - | streaming speech recognition,
+ | VAD,
+
+
+We also support `Triton`_. Please see :ref:`triton_overview`.
diff --git a/docs/source/ncnn/android/build-sherpa-ncnn.rst b/docs/source/ncnn/android/build-sherpa-ncnn.rst
new file mode 100644
index 000000000..109d71686
--- /dev/null
+++ b/docs/source/ncnn/android/build-sherpa-ncnn.rst
@@ -0,0 +1,385 @@
+.. _sherpa-ncnn-install-android-studio:
+
+Build sherpa-ncnn for Android
+=============================
+
+Install Android Studio
+----------------------
+
+The first step is to download and install Android Studio.
+
+Please refer to ``_ for how to install
+Android Studio.
+
+.. hint::
+
+ Any recent version of Android Studio should work fine. Also, you can use
+ the default settings of Android Studio during installation.
+
+ For reference, we post the version we are using below:
+
+ .. image:: ./pic/android-studio-version.png
+ :alt: screenshot of my version of Android Studio
+ :width: 600
+
+
+Download sherpa-ncnn
+--------------------
+
+Next, download the source code of `sherpa-ncnn`_:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+
+
+Install NDK
+-----------
+
+Step 1, start Android Studio.
+
+ .. figure:: ./pic/start-android-studio.png
+ :alt: Start Android Studio
+ :width: 600
+
+ Step 1: Click ``Open`` to select ``sherpa-ncnn/android/SherpaNcnn``
+
+Step 2, Open ``sherpa-ncnn/android/SherpaNcnn``.
+
+ .. figure:: ./pic/open-sherpa-ncnn.png
+ :alt: Open SherpaNCNN
+ :width: 600
+
+ Step 2: Open ``SherpaNcnn``.
+
+
+Step 3, Select ``Tools -> SDK Manager``.
+
+ .. figure:: ./pic/select-sdk-manager.png
+ :alt: Select Tools -> SDK Manager
+ :width: 600
+
+ Step 3: Select ``Tools -> SDK Manager``.
+
+Step 4, ``Install NDK``.
+
+ .. figure:: ./pic/ndk-tools.png
+ :alt: Install NDK
+ :width: 600
+
+ Step 4: Install NDK.
+
+In the following, we assume ``Android SDK location`` was set to
+``/Users/fangjun/software/my-android``. You can change it accordingly below.
+
+After installing NDK, you can find it in
+
+.. code-block::
+
+ /Users/fangjun/software/my-android/ndk/22.1.7171670
+
+.. warning::
+
+ If you selected a different version of NDK, please replace ``22.1.7171670``
+ accordingly.
+
+Next, let us set the environment variable ``ANDROID_NDK`` for later use.
+
+.. code-block:: bash
+
+ export ANDROID_NDK=/Users/fangjun/software/my-android/ndk/22.1.7171670
+
+.. note::
+
+ Note from https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-android
+
+ (Important) remove the hardcoded debug flag in Android NDK to fix
+ the android-ndk issue: https://github.com/android/ndk/issues/243
+
+ 1. open ``$ANDROID_NDK/build/cmake/android.toolchain.cmake`` for ndk < r23
+ or ``$ANDROID_NDK/build/cmake/android-legacy.toolchain.cmake`` for ndk >= r23
+
+ 2. delete the line containing "-g"
+
+ .. code-block::
+
+ list(APPEND ANDROID_COMPILER_FLAGS
+ -g
+ -DANDROID
+
+.. caution::
+
+ If you don't delete the line containin ``-g`` above, the generated
+ library ``libncnn.so`` can be as large as ``21 MB`` or even larger!
+
+Build sherpa-ncnn (C++ code)
+----------------------------
+
+After installing ``NDK``, it is time to build the C++ code of `sherpa-ncnn`_.
+
+In the following, we show how to build `sherpa-ncnn`_ for the following
+Android ABIs:
+
+ - ``arm64-v8a``
+ - ``armeabi-v7a``
+ - ``x86_64``
+ - ``x86``
+
+.. caution::
+
+ You only need to select one and only one ABI. ``arm64-v8a`` is probably the
+ most common one.
+
+ If you want to test the app on an emulator, you probably need ``x86_64``.
+
+.. hint::
+
+ Building scripts for this section are for macOS and Linux. If you are
+ using Windows or if you don't want to build the shared libraries by yourself,
+ you can download pre-compiled shared libraries for this section by visiting
+
+ ``_
+
+.. hint::
+
+ We provide a colab notebook
+ |build sherpa-ncnn for android colab notebook|
+ for you to try this section step by step.
+
+ If you are using Windows or you don't want to setup your local environment
+ to build the C++ libraries, please use the above colab notebook.
+
+.. |build sherpa-ncnn for android colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-ncnn/build_sherpa_ncnn_for_android.ipynb
+
+Build for arm64-v8a
+^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-ncnn # Go to the root repo
+ ./build-android-arm64-v8a.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ $ ls -lh build-android-arm64-v8a/install/lib/lib*.so
+ -rwxr-xr-x 1 fangjun staff 848K Dec 18 16:49 build-android-arm64-v8a/install/lib/libkaldi-native-fbank-core.so
+ -rwxr-xr-x 1 fangjun staff 3.4M Dec 18 16:49 build-android-arm64-v8a/install/lib/libncnn.so
+ -rwxr-xr-x 1 fangjun staff 195K Dec 18 16:49 build-android-arm64-v8a/install/lib/libsherpa-ncnn-core.so
+ -rwxr-xr-x 1 fangjun staff 19K Dec 18 16:49 build-android-arm64-v8a/install/lib/libsherpa-ncnn-jni.so
+
+Please copy them to ``android/SherpaNcnn/app/src/main/jniLibs/arm64-v8a/``:
+
+.. code-block:: bash
+
+ $ cp build-android-arm64-v8a/install/lib/lib*.so android/SherpaNcnn/app/src/main/jniLibs/arm64-v8a/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-arm64-v8a.png
+ :alt: Generated shared libraries for arm64-v8a
+ :width: 600
+
+.. note::
+
+ If you have ``Android >= 7.0`` and want to run `sherpa-ncnn`_ on GPU, please replace
+ ``./build-android-arm64-v8a.sh`` with ``./build-android-arm64-v8a-with-vulkan.sh``
+ and replace ``build-android-arm64-v8a/install/lib/lib*.so`` with
+ ``./build-android-arm64-v8a-with-vulkan/install/lib/lib*.so``. That is all
+ you need to do and you don't need to change any code.
+
+
+ Also, you need to install Vulkan sdk. Please see
+ ``_
+ for details.
+
+
+
+Build for armeabi-v7a
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-ncnn # Go to the root repo
+ ./build-android-armv7-eabi.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ $ ls -lh build-android-armv7-eabi/install/lib/lib*.so
+ -rwxr-xr-x 1 fangjun staff 513K Dec 18 17:04 build-android-armv7-eabi/install/lib/libkaldi-native-fbank-core.so
+ -rwxr-xr-x 1 fangjun staff 1.9M Dec 18 17:04 build-android-armv7-eabi/install/lib/libncnn.so
+ -rwxr-xr-x 1 fangjun staff 163K Dec 18 17:04 build-android-armv7-eabi/install/lib/libsherpa-ncnn-core.so
+ -rwxr-xr-x 1 fangjun staff 28K Dec 18 17:04 build-android-armv7-eabi/install/lib/libsherpa-ncnn-jni.so
+
+Please copy them to ``android/SherpaNcnn/app/src/main/jniLibs/armeabi-v7a/``:
+
+.. code-block:: bash
+
+ cp build-android-armv7-eabi/install/lib/lib*.so android/SherpaNcnn/app/src/main/jniLibs/armeabi-v7a/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-armeabi-v7a.png
+ :alt: Generated shared libraries for armeabi-v7a
+ :width: 600
+
+Build for x86_64
+^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-ncnn # Go to the root repo
+ ./build-android-x86-64.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ $ ls -lh build-android-x86-64/install/lib/lib*.so
+ -rwxr-xr-x 1 fangjun staff 901K Dec 18 17:14 build-android-x86-64/install/lib/libkaldi-native-fbank-core.so
+ -rwxr-xr-x 1 fangjun staff 6.9M Dec 18 17:14 build-android-x86-64/install/lib/libncnn.so
+ -rwxr-xr-x 1 fangjun staff 208K Dec 18 17:14 build-android-x86-64/install/lib/libsherpa-ncnn-core.so
+ -rwxr-xr-x 1 fangjun staff 19K Dec 18 17:14 build-android-x86-64/install/lib/libsherpa-ncnn-jni.so
+
+Please copy them to ``android/SherpaNcnn/app/src/main/jniLibs/x86_64/``:
+
+.. code-block:: bash
+
+ cp build-android-x86-64/install/lib/lib*.so android/SherpaNcnn/app/src/main/jniLibs/x86_64/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-x86-64.png
+ :alt: Generated shared libraries for x86_64
+ :width: 600
+
+Build for x86
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-ncnn # Go to the root repo
+ ./build-android-x86.sh
+
+Download pre-trained models
+---------------------------
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for all available pre-trained
+models.
+
+In the following, we use a pre-trained model from
+``_,
+which supports both Chinese and English.
+
+.. hint::
+
+ The model is trained using `icefall`_ and the original torchscript model
+ is from ``_.
+
+Use the following command to download the pre-trained model and place it into
+``android/SherpaNcnn/app/src/main/assets/``:
+
+.. code-block:: bash
+
+ cd android/SherpaNcnn/app/src/main/assets/
+
+ sudo apt-get install git-lfs
+
+ GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-06
+ cd sherpa-ncnn-conv-emformer-transducer-2022-12-06
+ git lfs pull --include "*.bin"
+
+ # Now, remove extra files to reduce the file size of the generated apk
+ rm -rf .git test_wavs scripts/
+ rm export-for-ncnn.sh *.png README.md
+
+In the end, you should have the following files:
+
+.. code-block:: bash
+
+ $ ls -lh
+ total 525224
+ -rw-r--r-- 1 fangjun staff 5.9M Dec 18 17:40 decoder_jit_trace-pnnx.ncnn.bin
+ -rw-r--r-- 1 fangjun staff 439B Dec 18 17:39 decoder_jit_trace-pnnx.ncnn.param
+ -rw-r--r-- 1 fangjun staff 141M Dec 18 17:40 encoder_jit_trace-pnnx.ncnn.bin
+ -rw-r--r-- 1 fangjun staff 99M Dec 18 17:40 encoder_jit_trace-pnnx.ncnn.int8.bin
+ -rw-r--r-- 1 fangjun staff 78K Dec 18 17:40 encoder_jit_trace-pnnx.ncnn.int8.param
+ -rw-r--r-- 1 fangjun staff 79K Dec 18 17:39 encoder_jit_trace-pnnx.ncnn.param
+ -rw-r--r-- 1 fangjun staff 6.9M Dec 18 17:40 joiner_jit_trace-pnnx.ncnn.bin
+ -rw-r--r-- 1 fangjun staff 3.5M Dec 18 17:40 joiner_jit_trace-pnnx.ncnn.int8.bin
+ -rw-r--r-- 1 fangjun staff 498B Dec 18 17:40 joiner_jit_trace-pnnx.ncnn.int8.param
+ -rw-r--r-- 1 fangjun staff 490B Dec 18 17:39 joiner_jit_trace-pnnx.ncnn.param
+ -rw-r--r-- 1 fangjun staff 53K Dec 18 17:39 tokens.txt
+
+ $ du -h -d1 .
+ 256M .
+
+You should see the following screen shot after downloading the pre-trained model:
+
+.. figure:: ./pic/pre-trained-model-2022-12-06.png
+ :alt: Files after downloading the pre-trained model
+ :width: 600
+
+.. hint::
+
+ If you select a different pre-trained model, make sure that you also change the
+ corresponding code listed in the following screen shot:
+
+ .. figure:: ./pic/type-for-pre-trained-model-2022-12-06.png
+ :alt: Change code if you select a different model
+ :width: 600
+
+Generate APK
+------------
+
+Finally, it is time to build `sherpa-ncnn`_ to generate an APK package.
+
+Select ``Build -> Make Project``, as shown in the following screen shot.
+
+.. figure:: ./pic/build-make-project.png
+ :alt: Select ``Build -> Make Project``
+ :width: 600
+
+You can find the generated APK in ``android/SherpaNcnn/app/build/outputs/apk/debug/app-debug.apk``:
+
+.. code-block:: bash
+
+ $ ls -lh android/SherpaNcnn/app/build/outputs/apk/debug/app-debug.apk
+ -rw-r--r-- 1 fangjun staff 152M Dec 18 17:53 android/SherpaNcnn/app/build/outputs/apk/debug/app-debug.apk
+
+Congratulations! You have successfully built an APK for Android.
+
+Read below to learn more.
+
+.. _sherpa-ncnn-analyze-apk-result:
+
+Analyze the APK
+---------------
+
+.. figure:: ./pic/analyze-apk.png
+ :alt: Select ``Build -> Analyze APK ...``
+ :width: 600
+
+Select ``Build -> Analyze APK ...`` in the above screen shot, in the
+popped-up dialog select the generated APK ``app-debug.apk``,
+and you will see the following screen shot:
+
+.. figure:: ./pic/analyze-apk-result.png
+ :alt: Result of analyzing apk
+ :width: 700
+
+You can see from the above screen shot that most part of the APK
+is occupied by the pre-trained model, while the runtime, including the shared
+libraries, is only ``1.7 MB``.
+
+.. hint::
+
+ We have pre-built APKs that can be downloaded from
+ ``_
+
+ Please refer to demo videos about using the above
+ APKs: :ref:`sherpa-ncnn-android-video-demos`.
diff --git a/docs/source/ncnn/android/demo-videos.rst b/docs/source/ncnn/android/demo-videos.rst
new file mode 100644
index 000000000..4e53c0480
--- /dev/null
+++ b/docs/source/ncnn/android/demo-videos.rst
@@ -0,0 +1,54 @@
+.. _sherpa-ncnn-android-video-demos:
+
+Video demos
+===========
+
+In this page, we list some videos about using `sherpa-ncnn`_ for
+real-time speech recognition on Android.
+
+.. hint::
+
+ You can find pre-built ``APK`` packages used by the following videos at:
+
+ ``_
+
+ - CPU versions require ``Android >= 5.0``
+ - GPU versions with ``Vulkan`` require ``Android >= 7.0``
+
+.. note::
+
+ You can also find the latest APK for each release at
+
+ ``_
+
+
+
+Video 1: Chinese
+----------------
+
+.. raw:: html
+
+
+
+
+Video 2: Chinese + English
+--------------------------
+
+.. raw:: html
+
+
+
+
+Video 3: Chinese with background noise
+--------------------------------------
+
+.. raw:: html
+
+
+
+Video 4: Chinese poem with background music
+-------------------------------------------
+
+.. raw:: html
+
+
diff --git a/docs/source/ncnn/android/index.rst b/docs/source/ncnn/android/index.rst
new file mode 100644
index 000000000..107be0b9c
--- /dev/null
+++ b/docs/source/ncnn/android/index.rst
@@ -0,0 +1,19 @@
+.. _sherpa-ncnn-android:
+
+Android
+=======
+
+In this section, we describe how to build an Android app for ``real-time`` speech
+recognition with `sherpa-ncnn`_. We also provide real-time speech recognition
+video demos.
+
+.. hint::
+
+ During speech recognition, it does not need to access the Internet.
+ Everyting is processed locally on your phone.
+
+.. toctree::
+ :maxdepth: 2
+
+ demo-videos
+ build-sherpa-ncnn
diff --git a/docs/source/ncnn/android/pic/analyze-apk-result.png b/docs/source/ncnn/android/pic/analyze-apk-result.png
new file mode 100644
index 000000000..23a701036
Binary files /dev/null and b/docs/source/ncnn/android/pic/analyze-apk-result.png differ
diff --git a/docs/source/ncnn/android/pic/analyze-apk.png b/docs/source/ncnn/android/pic/analyze-apk.png
new file mode 100644
index 000000000..81d8e2edd
Binary files /dev/null and b/docs/source/ncnn/android/pic/analyze-apk.png differ
diff --git a/docs/source/ncnn/android/pic/android-studio-version.png b/docs/source/ncnn/android/pic/android-studio-version.png
new file mode 100644
index 000000000..d2f25efee
Binary files /dev/null and b/docs/source/ncnn/android/pic/android-studio-version.png differ
diff --git a/docs/source/ncnn/android/pic/build-make-project.png b/docs/source/ncnn/android/pic/build-make-project.png
new file mode 100644
index 000000000..80668fdd6
Binary files /dev/null and b/docs/source/ncnn/android/pic/build-make-project.png differ
diff --git a/docs/source/ncnn/android/pic/ndk-tools.png b/docs/source/ncnn/android/pic/ndk-tools.png
new file mode 100644
index 000000000..bd83f0a69
Binary files /dev/null and b/docs/source/ncnn/android/pic/ndk-tools.png differ
diff --git a/docs/source/ncnn/android/pic/open-sherpa-ncnn.png b/docs/source/ncnn/android/pic/open-sherpa-ncnn.png
new file mode 100644
index 000000000..5a6691118
Binary files /dev/null and b/docs/source/ncnn/android/pic/open-sherpa-ncnn.png differ
diff --git a/docs/source/ncnn/android/pic/pre-trained-model-2022-12-06.png b/docs/source/ncnn/android/pic/pre-trained-model-2022-12-06.png
new file mode 100644
index 000000000..f089f45c4
Binary files /dev/null and b/docs/source/ncnn/android/pic/pre-trained-model-2022-12-06.png differ
diff --git a/docs/source/ncnn/android/pic/select-sdk-manager.png b/docs/source/ncnn/android/pic/select-sdk-manager.png
new file mode 100644
index 000000000..76651563c
Binary files /dev/null and b/docs/source/ncnn/android/pic/select-sdk-manager.png differ
diff --git a/docs/source/ncnn/android/pic/so-libs-for-arm64-v8a.png b/docs/source/ncnn/android/pic/so-libs-for-arm64-v8a.png
new file mode 100644
index 000000000..37ba75c82
Binary files /dev/null and b/docs/source/ncnn/android/pic/so-libs-for-arm64-v8a.png differ
diff --git a/docs/source/ncnn/android/pic/so-libs-for-armeabi-v7a.png b/docs/source/ncnn/android/pic/so-libs-for-armeabi-v7a.png
new file mode 100644
index 000000000..a5a76f93d
Binary files /dev/null and b/docs/source/ncnn/android/pic/so-libs-for-armeabi-v7a.png differ
diff --git a/docs/source/ncnn/android/pic/so-libs-for-x86-64.png b/docs/source/ncnn/android/pic/so-libs-for-x86-64.png
new file mode 100644
index 000000000..a3c94b9b0
Binary files /dev/null and b/docs/source/ncnn/android/pic/so-libs-for-x86-64.png differ
diff --git a/docs/source/ncnn/android/pic/start-android-studio.png b/docs/source/ncnn/android/pic/start-android-studio.png
new file mode 100644
index 000000000..b683d3ff7
Binary files /dev/null and b/docs/source/ncnn/android/pic/start-android-studio.png differ
diff --git a/docs/source/ncnn/android/pic/type-for-pre-trained-model-2022-12-06.png b/docs/source/ncnn/android/pic/type-for-pre-trained-model-2022-12-06.png
new file mode 100644
index 000000000..e17bae3a3
Binary files /dev/null and b/docs/source/ncnn/android/pic/type-for-pre-trained-model-2022-12-06.png differ
diff --git a/docs/source/ncnn/c-api/index.rst b/docs/source/ncnn/c-api/index.rst
new file mode 100644
index 000000000..8684d3b2d
--- /dev/null
+++ b/docs/source/ncnn/c-api/index.rst
@@ -0,0 +1,162 @@
+.. _sherpa-ncnn-c-api:
+
+C API
+=====
+
+In this section, we describe how to use the C API of `sherpa-ncnn`_.
+
+Specifically, we will describe:
+
+ - How to generate required files
+ - How to use ``pkg-config`` with `sherpa-ncnn`_
+
+Generate required files
+-----------------------
+
+Before using the C API of `sherpa-ncnn`_, we need to first build required
+libraries. You can choose either to build static libraries or shared libraries.
+
+Build shared libraries
+^^^^^^^^^^^^^^^^^^^^^^
+
+Assume that we want to put library files and header files in the directory
+``/tmp/sherpa-ncnn/shared``:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build-shared
+ cd build-shared
+
+ cmake \
+ -DSHERPA_NCNN_ENABLE_C_API=ON \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=ON \
+ -DCMAKE_INSTALL_PREFIX=/tmp/sherpa-ncnn/shared \
+ ..
+
+ make -j6
+ make install
+
+You should find the following files inside ``/tmp/sherpa-ncnn/shared``:
+
+.. tabs::
+
+ .. tab:: macOS
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-ncnn/shared/
+ /tmp/sherpa-ncnn/shared/
+ ├── bin
+ │ ├── sherpa-ncnn
+ │ └── sherpa-ncnn-microphone
+ ├── include
+ │ └── sherpa-ncnn
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libkaldi-native-fbank-core.dylib
+ │ ├── libncnn.dylib
+ │ ├── libsherpa-ncnn-c-api.dylib
+ │ └── libsherpa-ncnn-core.dylib
+ └── sherpa-ncnn.pc
+
+ 5 directories, 8 files
+
+ .. tab:: Linux
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-ncnn/shared/
+ /tmp/sherpa-ncnn/shared/
+ ├── bin
+ │ ├── sherpa-ncnn
+ │ └── sherpa-ncnn-microphone
+ ├── include
+ │ └── sherpa-ncnn
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libkaldi-native-fbank-core.so
+ │ ├── libncnn.so
+ │ ├── libsherpa-ncnn-c-api.so
+ │ └── libsherpa-ncnn-core.so
+ └── sherpa-ncnn.pc
+
+ 5 directories, 8 files
+
+Build static libraries
+^^^^^^^^^^^^^^^^^^^^^^
+
+Assume that we want to put library files and header files in the directory
+``/tmp/sherpa-ncnn/static``:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build-static
+ cd build-static
+
+ cmake \
+ -DSHERPA_NCNN_ENABLE_C_API=ON \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DCMAKE_INSTALL_PREFIX=/tmp/sherpa-ncnn/static \
+ ..
+
+ make -j6
+ make install
+
+You should find the following files in ``/tmp/sherpa-ncnn/static``:
+
+.. code-block:: bash
+
+ $ tree /tmp/sherpa-ncnn/static/
+ /tmp/sherpa-ncnn/static/
+ ├── bin
+ │ ├── sherpa-ncnn
+ │ └── sherpa-ncnn-microphone
+ ├── include
+ │ └── sherpa-ncnn
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libkaldi-native-fbank-core.a
+ │ ├── libncnn.a
+ │ ├── libsherpa-ncnn-c-api.a
+ │ └── libsherpa-ncnn-core.a
+ └── sherpa-ncnn.pc
+
+ 5 directories, 8 files
+
+Build decode-file-c-api.c with generated files
+----------------------------------------------
+
+To build the following file:
+
+ ``_
+
+We can use:
+
+.. tabs::
+
+ .. tab:: static link
+
+ .. code-block:: bash
+
+ export PKG_CONFIG_PATH=/tmp/sherpa-ncnn/static:$PKG_CONFIG_PATH
+
+ cd ./c-api-examples
+ gcc -o decode-file-c-api $(pkg-config --cflags sherpa-ncnn) ./decode-file-c-api.c $(pkg-config --libs sherpa-ncnn)
+
+ .. tab:: dynamic link
+
+ .. code-block:: bash
+
+ export PKG_CONFIG_PATH=/tmp/sherpa-ncnn/shared:$PKG_CONFIG_PATH
+
+ cd ./c-api-examples
+ gcc -o decode-file-c-api $(pkg-config --cflags sherpa-ncnn) ./decode-file-c-api.c $(pkg-config --libs sherpa-ncnn)
diff --git a/docs/source/ncnn/endpoint.rst b/docs/source/ncnn/endpoint.rst
new file mode 100644
index 000000000..ef0385a8f
--- /dev/null
+++ b/docs/source/ncnn/endpoint.rst
@@ -0,0 +1,122 @@
+Endpointing
+===========
+
+We have three rules for endpoint detection. If any of them is activated,
+we assume an endpoint is detected.
+
+.. note::
+
+ We borrow the implementation from
+
+ ``_
+
+Rule 1
+------
+
+In ``Rule 1``, we count the duration of trailing silence. If it is larger than
+a user specified value, ``Rule 1`` is activated. The following is an example,
+which uses ``2.4 seconds`` as the threshold.
+
+ .. figure:: ./pic/rule1.png
+ :alt: Rule 1 for endpoint detection
+ :width: 600
+
+Two cases are given:
+
+(1) In the first case, nothing has been decoded when the duration of trailing
+ silence reaches 2.4 seconds.
+
+(2) In the second case, we first decode something before the duration of
+ trailing silence reaches 2.4 seconds.
+
+In both cases, ``Rule 1`` is activated.
+
+.. hint::
+
+ In the Python API, you can specify ``rule1_min_trailing_silence`` while
+ constructing an instance of ``sherpa_ncnn.Recognizer``.
+
+ In the C++ API, you can specify ``rule1.min_trailing_silence`` when creating
+ ``EndpointConfig``.
+
+
+Rule 2
+------
+
+In ``Rule 2``, we require that it has to first decode something
+before we count the trailing silence. In the following example, after decoding
+something, ``Rule 2`` is activated when the duration of trailing silence is
+larger than the user specified value ``1.2`` seconds.
+
+ .. figure:: ./pic/rule2.png
+ :alt: Rule 2 for endpoint detection
+ :width: 600
+
+.. hint::
+
+ In the Python API, you can specify ``rule2_min_trailing_silence`` while
+ constructing an instance of ``sherpa_ncnn.Recognizer``.
+
+ In the C++ API, you can specify ``rule2.min_trailing_silence`` when creating
+ ``EndpointConfig``.
+
+Rule 3
+------
+
+``Rule 3`` is activated when the utterance length in seconds is larger than
+a given value. In the following example, ``Rule 3`` is activated after the
+first segment reaches a given value, which is ``20`` seconds in this case.
+
+ .. figure:: ./pic/rule3.png
+ :alt: Rule 3 for endpoint detection
+ :width: 600
+
+.. hint::
+
+ In the Python API, you can specify ``rule3_min_utterance_length`` while
+ constructing an instance of ``sherpa_ncnn.Recognizer``.
+
+ In the C++ API, you can specify ``rule3.min_utterance_length`` when creating
+ ``EndpointConfig``.
+
+.. note::
+
+ If you want to deactive this rule, please provide a very large value
+ for ``rule3_min_utterance_length`` or ``rule3.min_utterance_length``.
+
+Demo
+----
+
+Multilingual (Chinese + English)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following video demonstrates using the Python API of `sherpa-ncnn`_
+for real-time speech recogntinion with endpointing.
+
+.. raw:: html
+
+
+
+
+.. hint::
+
+ The code is available at
+
+ ``_
+
+FAQs
+----
+
+How to compute duration of silence
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For each frame to be decoded, we can output either a blank or a non-blank token.
+We record the number of contiguous blanks that has been decoded so far.
+In the current default setting, each frame is ``10 ms``. Thus, we can get
+the duration of trailing silence by counting the number of contiguous trailing
+blanks.
+
+.. note::
+
+ If a model uses a subsampling factor of 4, the time resolution becomes
+ ``10 * 4 = 40 ms``.
diff --git a/docs/source/ncnn/examples/index.rst b/docs/source/ncnn/examples/index.rst
new file mode 100644
index 000000000..0c9909ada
--- /dev/null
+++ b/docs/source/ncnn/examples/index.rst
@@ -0,0 +1,14 @@
+Examples
+========
+
+In this section, we describe some usage examples of `sherpa-ncnn`_ on various
+boards.
+
+.. toctree::
+ :maxdepth: 2
+
+ ./raspberry-pi-3.rst
+ ./jetson-nano.rst
+ ./jetson-nx.rst
+ ./vision-five-2.rst
+
diff --git a/docs/source/ncnn/examples/jetson-nano.rst b/docs/source/ncnn/examples/jetson-nano.rst
new file mode 100644
index 000000000..d485b2bc8
--- /dev/null
+++ b/docs/source/ncnn/examples/jetson-nano.rst
@@ -0,0 +1,25 @@
+Jetson Nano
+===========
+
+This page posts some screenshots of running `sherpa-ncnn`_ on `Jetson Nano `_.
+
+.. hint::
+
+ You can find pre-compiled binaries used in this example at
+
+ ``_
+
+Board info
+----------
+
+ .. image:: ./pic/jetson-nano/lscpu2.jpg
+ :alt: Output of lscpu
+ :width: 600
+
+
+RTF (4 threads)
+---------------
+
+ .. image:: ./pic/jetson-nano/rtf-4-threads.jpg
+ :alt: RTF for 4 threads
+ :width: 600
diff --git a/docs/source/ncnn/examples/jetson-nx.rst b/docs/source/ncnn/examples/jetson-nx.rst
new file mode 100644
index 000000000..716fed17f
--- /dev/null
+++ b/docs/source/ncnn/examples/jetson-nx.rst
@@ -0,0 +1,38 @@
+Jetson NX
+=========
+
+This page posts some screenshots of running `sherpa-ncnn`_ on ``Jetson NX``.
+
+.. hint::
+
+ You can find pre-compiled binaries used in this example at
+
+ ``_
+
+Board info
+----------
+
+ .. image:: ./pic/jetson-nx/lscpu2.jpg
+ :alt: Output of lscpu
+ :width: 600
+
+RTF (2 threads)
+---------------
+
+ .. image:: ./pic/jetson-nx/rtf-2-threads.jpg
+ :alt: RTF for 2 threads
+ :width: 600
+
+RTF (4 threads)
+---------------
+
+ .. image:: ./pic/jetson-nx/rtf-4-threads.jpg
+ :alt: RTF for 4 threads
+ :width: 600
+
+RTF (6 threads)
+---------------
+
+ .. image:: ./pic/jetson-nx/rtf-6-threads.jpg
+ :alt: RTF for 6 threads
+ :width: 600
diff --git a/docs/source/ncnn/examples/pic/.gitignore b/docs/source/ncnn/examples/pic/.gitignore
new file mode 100644
index 000000000..b5a379de9
--- /dev/null
+++ b/docs/source/ncnn/examples/pic/.gitignore
@@ -0,0 +1 @@
+!*.jpg
diff --git a/docs/source/ncnn/examples/pic/jetson-nano/lscpu2.jpg b/docs/source/ncnn/examples/pic/jetson-nano/lscpu2.jpg
new file mode 100644
index 000000000..a310c5959
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nano/lscpu2.jpg differ
diff --git a/docs/source/ncnn/examples/pic/jetson-nano/rtf-4-threads.jpg b/docs/source/ncnn/examples/pic/jetson-nano/rtf-4-threads.jpg
new file mode 100644
index 000000000..644fc67f3
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nano/rtf-4-threads.jpg differ
diff --git a/docs/source/ncnn/examples/pic/jetson-nx/lscpu2.jpg b/docs/source/ncnn/examples/pic/jetson-nx/lscpu2.jpg
new file mode 100644
index 000000000..c16173c0e
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nx/lscpu2.jpg differ
diff --git a/docs/source/ncnn/examples/pic/jetson-nx/rtf-2-threads.jpg b/docs/source/ncnn/examples/pic/jetson-nx/rtf-2-threads.jpg
new file mode 100644
index 000000000..c359e303e
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nx/rtf-2-threads.jpg differ
diff --git a/docs/source/ncnn/examples/pic/jetson-nx/rtf-4-threads.jpg b/docs/source/ncnn/examples/pic/jetson-nx/rtf-4-threads.jpg
new file mode 100644
index 000000000..6ccf3893a
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nx/rtf-4-threads.jpg differ
diff --git a/docs/source/ncnn/examples/pic/jetson-nx/rtf-6-threads.jpg b/docs/source/ncnn/examples/pic/jetson-nx/rtf-6-threads.jpg
new file mode 100644
index 000000000..a37b80fa6
Binary files /dev/null and b/docs/source/ncnn/examples/pic/jetson-nx/rtf-6-threads.jpg differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_1.png b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_1.png
new file mode 100644
index 000000000..41eda75c4
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_1.png differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_2.png b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_2.png
new file mode 100644
index 000000000..a8b17117f
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_2.png differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_4.png b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_4.png
new file mode 100644
index 000000000..e572ebab2
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_4.png differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_5.png b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_5.png
new file mode 100644
index 000000000..9cd1970a3
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/raspberrypi_3b_shot_5.png differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-1-thread.jpg b/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-1-thread.jpg
new file mode 100644
index 000000000..518a4c712
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-1-thread.jpg differ
diff --git a/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-2-threads.jpg b/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-2-threads.jpg
new file mode 100644
index 000000000..51262906e
Binary files /dev/null and b/docs/source/ncnn/examples/pic/raspberry-pi-3/rtf-2-threads.jpg differ
diff --git a/docs/source/ncnn/examples/pic/vision-five-2/arecord.jpg b/docs/source/ncnn/examples/pic/vision-five-2/arecord.jpg
new file mode 100644
index 000000000..39b97b1a6
Binary files /dev/null and b/docs/source/ncnn/examples/pic/vision-five-2/arecord.jpg differ
diff --git a/docs/source/ncnn/examples/pic/vision-five-2/lscpu.jpg b/docs/source/ncnn/examples/pic/vision-five-2/lscpu.jpg
new file mode 100644
index 000000000..6c40b5949
Binary files /dev/null and b/docs/source/ncnn/examples/pic/vision-five-2/lscpu.jpg differ
diff --git a/docs/source/ncnn/examples/pic/vision-five-2/microphone-alsa.jpg b/docs/source/ncnn/examples/pic/vision-five-2/microphone-alsa.jpg
new file mode 100644
index 000000000..b435e4f35
Binary files /dev/null and b/docs/source/ncnn/examples/pic/vision-five-2/microphone-alsa.jpg differ
diff --git a/docs/source/ncnn/examples/pic/vision-five-2/rtf.jpg b/docs/source/ncnn/examples/pic/vision-five-2/rtf.jpg
new file mode 100644
index 000000000..7793592df
Binary files /dev/null and b/docs/source/ncnn/examples/pic/vision-five-2/rtf.jpg differ
diff --git a/docs/source/ncnn/examples/raspberry-pi-3.rst b/docs/source/ncnn/examples/raspberry-pi-3.rst
new file mode 100644
index 000000000..e515d3fb1
--- /dev/null
+++ b/docs/source/ncnn/examples/raspberry-pi-3.rst
@@ -0,0 +1,52 @@
+Raspberry Pi 3B E14
+===================
+
+This page posts some screenshots of running `sherpa-ncnn`_ on Raspberry Pi 3B E14.
+
+.. hint::
+
+ You can find pre-compiled binaries used in this example at
+
+ ``_
+
+Board info
+----------
+
+ .. image:: ./pic/raspberry-pi-3/raspberrypi_3b_shot_1.png
+ :alt: Board info
+ :width: 600
+
+OS release
+----------
+
+ .. image:: ./pic/raspberry-pi-3/raspberrypi_3b_shot_2.png
+ :alt: Output of /etc/os-release
+ :width: 600
+
+lscpu
+-----
+
+ .. image:: ./pic/raspberry-pi-3/raspberrypi_3b_shot_4.png
+ :alt: Output of lscpu
+ :width: 600
+
+cpuinfo
+-------
+
+ .. image:: ./pic/raspberry-pi-3/raspberrypi_3b_shot_5.png
+ :alt: cpuinfo
+ :width: 600
+
+RTF (1 thread)
+--------------
+
+ .. image:: ./pic/raspberry-pi-3/rtf-1-thread.jpg
+ :alt: RTF for 1 thread
+ :width: 600
+
+RTF (2 threads)
+---------------
+
+ .. image:: ./pic/raspberry-pi-3/rtf-2-threads.jpg
+ :alt: RTF for 2 threads
+ :width: 600
diff --git a/docs/source/ncnn/examples/vision-five-2.rst b/docs/source/ncnn/examples/vision-five-2.rst
new file mode 100644
index 000000000..0f95e4bbb
--- /dev/null
+++ b/docs/source/ncnn/examples/vision-five-2.rst
@@ -0,0 +1,103 @@
+VisionFive 2
+============
+
+This page describes how to run `sherpa-ncnn`_ on `VisionFive2`_, which is a
+64-bit RISC-V board with 4 CPUs.
+
+.. hint::
+
+ You can find pre-compiled binaries used in this example at
+
+ ``_
+
+.. caution::
+
+ The latest debian image from ``_ does not work since it does not support USB devices.
+
+ That is, you cannot use USB microphones on the board with the above debian image.
+
+.. note::
+
+ We have compiled ``_ and
+ the resulting ``sdcard.img`` is available at ``_.
+
+ Please use this image for testing. It supports USB microphones.
+
+ The username for this image is ``root`` and the password is ``starfive``.
+
+Board info
+----------
+
+.. image:: ./pic/vision-five-2/lscpu.jpg
+ :alt: Output of lscpu and /proc/cpuinfo
+ :height: 450
+
+RTF (4 threads)
+---------------
+
+We use :ref:`sherpa_ncnn_streaming_zipformer_small_bilingual_zh_en_2023_02_16`
+for testing. The RTF is given below:
+
+.. image:: ./pic/vision-five-2/rtf.jpg
+ :alt: RTF for 4 threads with greedy search
+ :width: 800
+
+You can see that the RTF is less than 1, which means it is able to
+perform streaming (i.e., real-time) speech recognition.
+
+The following posts the commands used for testing so that you can
+copy and paste them if you want to test it by yourself.
+
+.. code-block:: bash
+
+ ./sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/0.wav \
+ 4 \
+ greedy_search
+
+Real-time speech recognition with a microphone
+----------------------------------------------
+
+Since the board does not have microphones, we use a USB microphone for testing.
+
+.. caution::
+
+ We use the image from ``_,
+ which provides support for USB microphones.
+
+After connecting a USB microphone to the board, use the following command to check it:
+
+.. image:: ./pic/vision-five-2/arecord.jpg
+ :alt: output of arecord -l
+ :width: 600
+
+The output shows ``Card 2`` and ``device 0``, so the device name is ``hw:2,0``.
+
+The command to start the program for real-time speech recognition is
+
+.. code-block:: bash
+
+ ./sherpa-ncnn-alsa \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.bin \
+ hw:2,0 \
+ 4 \
+ greedy_search
+
+A screenshot is given below:
+
+.. image:: ./pic/vision-five-2/microphone-alsa.jpg
+ :alt: output of sherpa-ncnn-alsa
+ :width: 800
diff --git a/docs/source/ncnn/faq.rst b/docs/source/ncnn/faq.rst
new file mode 100644
index 000000000..caf0aa529
--- /dev/null
+++ b/docs/source/ncnn/faq.rst
@@ -0,0 +1,42 @@
+FAQs
+====
+
+Where to get help
+-----------------
+
+If you have any questions, please create an issue
+at ``_
+
+We also have active social groups:
+
+ - 微信公众号: 新一代 Kaldi
+ - 微信交流群:请关注新一代 Kaldi, 添加工作人员微信, 我们邀请您进群
+ - QQ 群:744602236
+
+
+No default input device found
+-----------------------------
+
+If you are using Linux and if ``sherpa-ncnn-microphone`` throws the following error:
+
+.. code-block::
+
+ Num device: 0
+ No default input device found.
+
+Please consider using ``sherpa-ncnn-alsa`` to replace ``sherpa-ncnn-microphone``.
+If you cannot find ``sherpa-ncnn-alsa`` in ``./build/bin``, please run the
+following commands:
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ sudo apt-get install alsa-utils libasound2-dev
+ cd build
+ rm CMakeCache.txt # Important, remove the cmake cache file
+ make -j
+
+After the above commands, you should see a binary file ``./build/bin/sherpa-ncnn-alsa``.
+
+
+Please follow :ref:`sherpa-ncnn-alsa` to use ``sherpa-ncnn-alsa``.
diff --git a/docs/source/ncnn/index.rst b/docs/source/ncnn/index.rst
new file mode 100644
index 000000000..e1ee6e60f
--- /dev/null
+++ b/docs/source/ncnn/index.rst
@@ -0,0 +1,36 @@
+sherpa-ncnn
+===========
+
+.. hint::
+
+ During speech recognition, it does not need to access the Internet.
+ Everyting is processed locally on your device.
+
+
+We support using `ncnn`_ to replace PyTorch for neural network computation.
+The code is put in a separate repository `sherpa-ncnn`_
+
+`sherpa-ncnn`_ is self-contained and everything can be compiled from source.
+
+Please refer to ``_
+for how to export models to `ncnn`_ format.
+
+In the following, we describe how to build `sherpa-ncnn`_ for Linux, macOS,
+Windows, embedded systems, Android, and iOS.
+
+Also, we show how to use it for speech recognition with pre-trained models.
+
+.. toctree::
+ :maxdepth: 2
+
+ ./tutorials/index
+ ./install/index
+ ./python/index
+ ./wasm/index
+ ./c-api/index
+ ./endpoint
+ ./android/index
+ ./ios/index
+ ./pretrained_models/index
+ ./examples/index
+ ./faq
diff --git a/docs/source/ncnn/install/aarch64-embedded-linux.rst b/docs/source/ncnn/install/aarch64-embedded-linux.rst
new file mode 100644
index 000000000..ea2c8e50d
--- /dev/null
+++ b/docs/source/ncnn/install/aarch64-embedded-linux.rst
@@ -0,0 +1,214 @@
+Embedded Linux (aarch64)
+========================
+
+This page describes how to build `sherpa-ncnn`_ for embedded Linux (aarch64, 64-bit)
+with cross-compiling on an x86 machine with Ubuntu OS.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. hint::
+
+ This page is for cross-compiling.
+
+.. _sherpa_ncnn_install_for_aarch64_embedded_linux:
+
+Install toolchain
+-----------------
+
+The first step is to install a toolchain for cross-compiling.
+
+.. warning::
+
+ You can use any toolchain that is suitable for your platform. The toolchain
+ we use below is just an example.
+
+Visit ``_
+to download the toolchain.
+
+We are going to download ``gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz``,
+which has been uploaded to ``_.
+
+Assume you want to install it in the folder ``$HOME/software``:
+
+.. code-block:: bash
+
+ mkdir -p $HOME/software
+ cd $HOME/software
+ wget https://huggingface.co/csukuangfj/sherpa-ncnn-toolchains/resolve/main/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
+
+ # For users from China
+ # 中国国内用户,如果访问不了 huggingface, 请使用
+ # wget https://hf-mirror.com/csukuangfj/sherpa-ncnn-toolchains/resolve/main/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
+ tar xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
+
+Next, we need to set the following environment variable:
+
+.. code-block:: bash
+
+ export PATH=$HOME/software/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
+
+To check that we have installed the cross-compiling toolchain successfully, please
+run:
+
+.. code-block:: bash
+
+ aarch64-linux-gnu-gcc --version
+
+which should print the following log:
+
+.. code-block::
+
+ aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Congratulations! You have successfully installed a toolchain for cross-compiling
+`sherpa-ncnn`_.
+
+Build sherpa-ncnn
+-----------------
+
+Finally, let us build `sherpa-ncnn`_.
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ ./build-aarch64-linux-gnu.sh
+
+After building, you will get two binaries:
+
+.. code-block:: bash
+
+ $ ls -lh build-aarch64-linux-gnu/install/bin/
+ total 10M
+ -rwxr-xr-x 1 kuangfangjun root 3.4M Jan 13 21:16 sherpa-ncnn
+ -rwxr-xr-x 1 kuangfangjun root 3.4M Jan 13 21:16 sherpa-ncnn-alsa
+
+That's it!
+
+.. hint::
+
+ - ``sherpa-ncnn`` is for decoding a single file
+ - ``sherpa-ncnn-alsa`` is for real-time speech recongition by reading
+ the microphone with `ALSA `_
+
+.. _sherpa-ncnn-alsa:
+
+sherpa-ncnn-alsa
+----------------
+
+.. caution::
+
+ We recommend that you use ``sherpa-ncnn-alsa`` on embedded systems such
+ as Raspberry pi.
+
+ You need to provide a ``device_name`` when invoking ``sherpa-ncnn-alsa``.
+ We describe below how to find the device name for your microphone.
+
+ Run the following command:
+
+ .. code-block:: bash
+
+ arecord -l
+
+ to list all avaliable microphones for recording. If it complains that
+ ``arecord: command not found``, please use ``sudo apt-get install alsa-utils``
+ to install it.
+
+ If the above command gives the following output:
+
+ .. code-block:: bash
+
+ **** List of CAPTURE Hardware Devices ****
+ card 3: UACDemoV10 [UACDemoV1.0], device 0: USB Audio [USB Audio]
+ Subdevices: 1/1
+ Subdevice #0: subdevice #0
+
+ In this case, I only have 1 microphone. It is ``card 3`` and that card
+ has only ``device 0``. To select ``card 3`` and ``device 0`` on that card,
+ we need to pass ``plughw:3,0`` to ``sherpa-ncnn-alsa``. (Note: It has the format
+ ``plughw:card_number,device_index``.)
+
+ For instance, you have to use
+
+ .. code-block:: bash
+
+ ./bin/sherpa-ncnn-alsa \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.bin \
+ "plughw:3,0"
+
+ Please change the card number and also the device index on the selected card
+ accordingly in your own situation. Otherwise, you won't be able to record
+ with your microphone.
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+.. hint::
+
+ If you want to select a pre-trained model for Raspberry that can be
+ run on real-time, we recommend you to use
+ :ref:`marcoyang_sherpa_ncnn_conv_emformer_transducer_small_2023_01_09_english`.
+
+
+Read below if you want to learn more.
+
+.. hint::
+
+ By default, all external dependencies are statically linked. That means,
+ the generated binaries are self-contained.
+
+ You can use the following commands to check that and you will find
+ they depend only on system libraries.
+
+ .. code-block:: bash
+
+ $ readelf -d build-aarch64-linux-gnu/install/bin/sherpa-ncnn
+
+ Dynamic section at offset 0x302a80 contains 30 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
+
+ $ readelf -d build-aarch64-linux-gnu/install/bin/sherpa-ncnn-alsa
+
+ Dynamic section at offset 0x34ea48 contains 31 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libasound.so.2]
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
+
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/install/arm-embedded-linux.rst b/docs/source/ncnn/install/arm-embedded-linux.rst
new file mode 100644
index 000000000..1aaac0c35
--- /dev/null
+++ b/docs/source/ncnn/install/arm-embedded-linux.rst
@@ -0,0 +1,198 @@
+.. _sherpa-ncnn-embedded-linux-arm-install:
+
+Embedded Linux (arm)
+====================
+
+This page describes how to build `sherpa-ncnn`_ for embedded Linux (arm, 32-bit)
+with cross-compiling on an x86 machine with Ubuntu OS.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. caution::
+
+ If you want to build `sherpa-ncnn`_ directly on your board, please don't
+ use this document. Refer to :ref:`install_sherpa_ncnn_on_linux` instead.
+
+.. hint::
+
+ This page is for cross-compiling.
+
+Install toolchain
+-----------------
+
+The first step is to install a toolchain for cross-compiling.
+
+.. warning::
+
+ You can use any toolchain that is suitable for your platform. The toolchain
+ we use below is just an example.
+
+Visit ``_ to download the toolchain:
+
+We are going to download ``gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz``,
+which has been uploaded to ``_.
+
+Assume you want to install it in the folder ``$HOME/software``:
+
+.. code-block:: bash
+
+ mkdir -p $HOME/software
+ cd $HOME/software
+ wget https://huggingface.co/csukuangfj/sherpa-ncnn-toolchains/resolve/main/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
+ tar xvf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
+
+Next, we need to set the following environment variable:
+
+.. code-block:: bash
+
+ export PATH=$HOME/software/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin:$PATH
+
+To check that we have installed the cross-compiling toolchain successfully, please
+run:
+
+.. code-block:: bash
+
+ arm-linux-gnueabihf-gcc --version
+
+which should print the following log:
+
+.. code-block::
+
+ arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Congratulations! You have successfully installed a toolchain for cross-compiling
+`sherpa-ncnn`_.
+
+Build sherpa-ncnn
+-----------------
+
+Finally, let us build `sherpa-ncnn`_.
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ ./build-arm-linux-gnueabihf.sh
+
+After building, you will get two binaries:
+
+.. code-block:: bash
+
+ $ ls -lh build-arm-linux-gnueabihf/install/bin/
+
+ total 6.6M
+ -rwxr-xr-x 1 kuangfangjun root 2.2M Jan 14 21:46 sherpa-ncnn
+ -rwxr-xr-x 1 kuangfangjun root 2.2M Jan 14 21:46 sherpa-ncnn-alsa
+
+That's it!
+
+.. hint::
+
+ - ``sherpa-ncnn`` is for decoding a single file
+ - ``sherpa-ncnn-alsa`` is for real-time speech recongition by reading
+ the microphone with `ALSA `_
+
+.. caution::
+
+ We recommend that you use ``sherpa-ncnn-alsa`` on embedded systems such
+ as Raspberry pi.
+
+ You need to provide a ``device_name`` when invoking ``sherpa-ncnn-alsa``.
+ We describe below how to find the device name for your microphone.
+
+ Run the following command:
+
+ .. code-block:: bash
+
+ arecord -l
+
+ to list all avaliable microphones for recording. If it complains that
+ ``arecord: command not found``, please use ``sudo apt-get install alsa-utils``
+ to install it.
+
+ If the above command gives the following output:
+
+ .. code-block:: bash
+
+ **** List of CAPTURE Hardware Devices ****
+ card 0: Audio [Axera Audio], device 0: 49ac000.i2s_mst-es8328-hifi-analog es8328-hifi-analog-0 []
+ Subdevices: 1/1
+ Subdevice #0: subdevice #0
+
+ In this case, I only have 1 microphone. It is ``card 0`` and that card
+ has only ``device 0``. To select ``card 0`` and ``device 0`` on that card,
+ we need to pass ``plughw:0,0`` to ``sherpa-ncnn-alsa``. (Note: It has the format
+ ``plughw:card_number,device_index``.)
+
+ For instance, you have to use
+
+ .. code-block:: bash
+
+ # Note: We use int8 models for encoder and joiner below.
+ ./bin/sherpa-ncnn-alsa \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.int8.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.int8.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.int8.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.int8.bin \
+ "plughw:0,0"
+
+ Please change the card number and also the device index on the selected card
+ accordingly in your own situation. Otherwise, you won't be able to record
+ with your microphone.
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+Read below if you want to learn more.
+
+.. hint::
+
+ By default, all external dependencies are statically linked. That means,
+ the generated binaries are self-contained.
+
+ You can use the following commands to check that and you will find
+ they depend only on system libraries.
+
+ .. code-block:: bash
+
+ $ readelf -d build-arm-linux-gnueabihf/install/bin/sherpa-ncnn
+
+ Dynamic section at offset 0x1c7ee8 contains 30 entries:
+ Tag Type Name/Value
+ 0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x00000001 (NEEDED) Shared library: [libm.so.6]
+ 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x00000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x00000001 (NEEDED) Shared library: [libc.so.6]
+ 0x0000000f (RPATH) Library rpath: [$ORIGIN]
+
+ $ readelf -d build-arm-linux-gnueabihf/install/bin/sherpa-ncnn-alsa
+
+ Dynamic section at offset 0x22ded8 contains 32 entries:
+ Tag Type Name/Value
+ 0x00000001 (NEEDED) Shared library: [libasound.so.2]
+ 0x00000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x00000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x00000001 (NEEDED) Shared library: [libm.so.6]
+ 0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x00000001 (NEEDED) Shared library: [libc.so.6]
+ 0x0000000f (RPATH) Library rpath: [$ORIGIN]
+
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/install/index.rst b/docs/source/ncnn/install/index.rst
new file mode 100644
index 000000000..847affa53
--- /dev/null
+++ b/docs/source/ncnn/install/index.rst
@@ -0,0 +1,25 @@
+.. _install_sherpa_ncnn:
+
+Installation
+============
+
+.. hint::
+
+ Please refer to :ref:`sherpa-ncnn-python-api` for its usage with Python.
+
+In this section, we describe how to install `sherpa-ncnn`_ for the following
+platforms:
+
+.. toctree::
+ :maxdepth: 2
+
+ videos
+ linux
+ macos
+ windows
+ arm-embedded-linux
+ aarch64-embedded-linux
+ riscv64-embedded-linux
+
+If you want to build an Android app, please refer to :ref:`sherpa-ncnn-android`.
+If you want to build an iOS app, please refer to :ref:`sherpa-ncnn-ios`.
diff --git a/docs/source/ncnn/install/linux.rst b/docs/source/ncnn/install/linux.rst
new file mode 100644
index 000000000..b804af8af
--- /dev/null
+++ b/docs/source/ncnn/install/linux.rst
@@ -0,0 +1,132 @@
+.. _install_sherpa_ncnn_on_linux:
+
+Linux
+=====
+
+This page describes how to build `sherpa-ncnn`_ on Linux.
+
+.. hint::
+
+ You can follow this section if you want to build `sherpa-ncnn`_ directly
+ on your board.
+
+.. hint::
+
+ For the Python API, please refer to :ref:`sherpa-ncnn-python-api`.
+
+All you need is to run:
+
+.. tabs::
+
+ .. tab:: x86/x86_64
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release ..
+ make -j6
+
+ .. tab:: 32-bit ARM
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_C_FLAGS="-march=armv7-a -mfloat-abi=hard -mfpu=neon" \
+ -DCMAKE_CXX_FLAGS="-march=armv7-a -mfloat-abi=hard -mfpu=neon" \
+ ..
+ make -j6
+
+ .. tab:: 64-bit ARM
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_C_FLAGS="-march=armv8-a" \
+ -DCMAKE_CXX_FLAGS="-march=armv8-a" \
+ ..
+ make -j6
+
+
+After building, you will find two executables inside the ``bin`` directory:
+
+.. code-block:: bash
+
+ $ ls -lh bin/
+ total 13M
+ -rwxr-xr-x 1 kuangfangjun root 6.5M Dec 18 11:31 sherpa-ncnn
+ -rwxr-xr-x 1 kuangfangjun root 6.5M Dec 18 11:31 sherpa-ncnn-microphone
+
+That's it!
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+Read below if you want to learn more.
+
+You can strip the binaries by
+
+.. code-block:: bash
+
+ $ strip bin/sherpa-ncnn
+ $ strip bin/sherpa-ncnn-microphone
+
+After stripping, the file size of each binary is:
+
+.. code-block:: bash
+
+ $ ls -lh bin/
+ total 12M
+ -rwxr-xr-x 1 kuangfangjun root 5.8M Dec 18 11:35 sherpa-ncnn
+ -rwxr-xr-x 1 kuangfangjun root 5.8M Dec 18 11:36 sherpa-ncnn-microphone
+
+.. hint::
+
+ By default, all external dependencies are statically linked. That means,
+ the generated binaries are self-contained.
+
+ You can use the following commands to check that and you will find
+ they depend only on system libraries.
+
+ .. code-block::
+
+ $ readelf -d bin/sherpa-ncnn
+
+ Dynamic section at offset 0x5c0650 contains 34 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libmvec.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN:]
+
+ $ readelf -d bin/sherpa-ncnn-microphone
+
+ Dynamic section at offset 0x5c45d0 contains 34 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libmvec.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN:]
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/install/macos.rst b/docs/source/ncnn/install/macos.rst
new file mode 100644
index 000000000..4a0b42a23
--- /dev/null
+++ b/docs/source/ncnn/install/macos.rst
@@ -0,0 +1,81 @@
+macOS
+=====
+
+This page describes how to build `sherpa-ncnn`_ on macOS.
+
+.. hint::
+
+ For the Python API, please refer to :ref:`sherpa-ncnn-python-api`.
+
+All you need is to run:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release ..
+ make -j6
+
+After building, you will find two executables inside the ``bin`` directory:
+
+.. code-block:: bash
+
+ $ ls -lh bin/
+ total 24232
+ -rwxr-xr-x 1 fangjun staff 5.9M Dec 18 12:39 sherpa-ncnn
+ -rwxr-xr-x 1 fangjun staff 6.0M Dec 18 12:39 sherpa-ncnn-microphone
+
+That's it!
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+Read below if you want to learn more.
+
+You can strip the binaries by
+
+.. code-block:: bash
+
+ $ strip bin/sherpa-ncnn
+ $ strip bin/sherpa-ncnn-microphone
+
+After stripping, the file size of each binary is:
+
+.. code-block:: bash
+
+ $ ls -lh bin/
+ total 23000
+ -rwxr-xr-x 1 fangjun staff 5.6M Dec 18 12:40 sherpa-ncnn
+ -rwxr-xr-x 1 fangjun staff 5.6M Dec 18 12:40 sherpa-ncnn-microphone
+
+.. hint::
+
+ By default, all external dependencies are statically linked. That means,
+ the generated binaries are self-contained.
+
+ You can use the following commands to check that and you will find
+ they depend only on system libraries.
+
+ .. code-block::
+
+ $ otool -L bin/sherpa-ncnn
+ bin/sherpa-ncnn:
+ /usr/local/opt/libomp/lib/libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
+ /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 902.1.0)
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
+
+ $ otool -L bin/sherpa-ncnn-microphone
+ bin/sherpa-ncnn-microphone:
+ /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
+ /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox (compatibility version 1.0.0, current version 1000.0.0)
+ /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit (compatibility version 1.0.0, current version 1.0.0)
+ /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1677.104.0)
+ /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1069.24.0)
+ /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
+ /usr/local/opt/libomp/lib/libomp.dylib (compatibility version 5.0.0, current version 5.0.0)
+ /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 902.1.0)
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/install/riscv64-embedded-linux.rst b/docs/source/ncnn/install/riscv64-embedded-linux.rst
new file mode 100644
index 000000000..7fdf15723
--- /dev/null
+++ b/docs/source/ncnn/install/riscv64-embedded-linux.rst
@@ -0,0 +1,146 @@
+Embedded Linux (riscv64)
+========================
+
+This page describes how to build `sherpa-ncnn`_ for embedded Linux (RISC-V, 64-bit)
+with cross-compiling on an x64 machine with Ubuntu OS.
+
+.. hint::
+
+ We provide a colab notebook
+ |build sherpa-ncnn for risc-v colab notebook|
+ for you to try this section step by step.
+
+ If you are using Windows/macOS or you don't want to setup your local environment
+ for cross-compiling, please use the above colab notebook.
+
+.. |build sherpa-ncnn for risc-v colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-ncnn/sherpa_ncnn_RISC_V.ipynb
+
+
+Install toolchain
+-----------------
+
+The first step is to install a toolchain for cross-compiling.
+
+.. code-block:: bash
+
+ sudo apt-get install gcc-riscv64-linux-gnu
+ sudo apt-get install g++-riscv64-linux-gnu
+
+To check that you have installed the toolchain successfully, please run
+
+.. code-block:: bash
+
+ $ riscv64-linux-gnu-gcc --version
+ riscv64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ $ riscv64-linux-gnu-g++ --version
+ riscv64-linux-gnu-g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Build sherpa-ncnn
+-----------------
+
+Next, let us build `sherpa-ncnn`_.
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ ./build-riscv64-linux-gnu.sh
+
+After building, you will get two binaries:
+
+.. code-block:: bash
+
+ $ ls -lh build-riscv64-linux-gnu/install/bin/
+ total 3.8M
+ -rwxr-xr-x 1 kuangfangjun root 1.9M May 23 22:12 sherpa-ncnn
+ -rwxr-xr-x 1 kuangfangjun root 1.9M May 23 22:12 sherpa-ncnn-alsa
+
+That's it!
+
+.. hint::
+
+ - ``sherpa-ncnn`` is for decoding a single file
+ - ``sherpa-ncnn-alsa`` is for real-time speech recongition by reading
+ the microphone with `ALSA `_
+
+.. _sherpa-ncnn-alsa:
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+.. hint::
+
+ If you want to select a pre-trained model for `VisionFive 2 `_
+ that can be run on real-time, we recommend you to use
+ :ref:`sherpa_ncnn_streaming_zipformer_small_bilingual_zh_en_2023_02_16`.
+
+ You can use the following command with the above model:
+
+ .. code-block:: bash
+
+ ./sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/64/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/5.wav \
+ 4 \
+ greedy_search
+
+Read below if you want to learn more.
+
+.. hint::
+
+ By default, all external dependencies are statically linked. That means,
+ the generated binaries are self-contained.
+
+ You can use the following commands to check that and you will find
+ they depend only on system libraries.
+
+ .. code-block:: bash
+
+ $ readelf -d build-riscv64-linux-gnu/install/bin/sherpa-ncnn
+
+ Dynamic section at offset 0x1d6dc0 contains 31 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [ld-linux-riscv64-lp64d.so.1]
+ 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN]
+ 0x0000000000000020 (PREINIT_ARRAY) 0x1e18e0
+ 0x0000000000000021 (PREINIT_ARRAYSZ) 0x8
+
+ $ readelf -d build-riscv64-linux-gnu/install/bin/sherpa-ncnn-alsa
+
+ Dynamic section at offset 0x1d3db0 contains 32 entries:
+ Tag Type Name/Value
+ 0x0000000000000001 (NEEDED) Shared library: [libasound.so.2]
+ 0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
+ 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
+ 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+ 0x0000000000000001 (NEEDED) Shared library: [ld-linux-riscv64-lp64d.so.1]
+ 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN]
+ 0x0000000000000020 (PREINIT_ARRAY) 0x1de8c8
+ 0x0000000000000021 (PREINIT_ARRAYSZ) 0x8
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/install/videos.rst b/docs/source/ncnn/install/videos.rst
new file mode 100644
index 000000000..4c515e02f
--- /dev/null
+++ b/docs/source/ncnn/install/videos.rst
@@ -0,0 +1,20 @@
+Installation videos
+===================
+
+This section presents some videos about how to install and use `sherpa-ncnn`_.
+
+Window (64-bit)
+---------------
+
+The following `video `_
+shows how to install and use `sherpa-ncnn`_ on 64-bit Windows.
+
+Thanks to ``_ for his contribution.
+
+.. caution::
+
+ It is in Chinese.
+
+.. raw:: html
+
+
diff --git a/docs/source/ncnn/install/windows.rst b/docs/source/ncnn/install/windows.rst
new file mode 100644
index 000000000..4e1ae27df
--- /dev/null
+++ b/docs/source/ncnn/install/windows.rst
@@ -0,0 +1,82 @@
+Windows
+=======
+
+This page describes how to build `sherpa-ncnn`_ on Windows.
+
+.. hint::
+
+ For the Python API, please refer to :ref:`sherpa-ncnn-python-api`.
+
+.. hint::
+
+ MinGW is known not to work.
+ Please install ``Visual Studio`` before you continue.
+
+64-bit Windows (x64)
+--------------------
+
+All you need is to run:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+ cmake -DCMAKE_BUILD_TYPE=Release ..
+ cmake --build . --config Release
+
+It will generate two executables inside ``./bin/Release/``:
+
+ - ``sherpa-ncnn.exe``: For decoding a single wave file.
+ - ``sherpa-ncnn-microphone.exe``: For real-time speech recognition from a microphone
+
+That's it!
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+Please create an issue at ``_
+if you have any problems.
+
+32-bit Windows (x86)
+--------------------
+
+All you need is to run:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+
+ # Please select one toolset among VS 2015, 2017, 2019, and 2022 below
+ # We use VS 2022 as an example.
+
+ # For Visual Studio 2015
+ # cmake -T v140,host=x64 -A Win32 -D CMAKE_BUILD_TYPE=Release ..
+
+ # For Visual Studio 2017
+ # cmake -T v141,host=x64 -A Win32 -D CMAKE_BUILD_TYPE=Release ..
+
+ # For Visual Studio 2019
+ # cmake -T v142,host=x64 -A Win32 -D CMAKE_BUILD_TYPE=Release ..
+
+ # For Visual Studio 2022
+ cmake -T v143,host=x64 -A Win32 -D CMAKE_BUILD_TYPE=Release ..
+
+ cmake --build . --config Release -- -m:6
+
+It will generate two executables inside ``./bin/Release/``:
+
+ - ``sherpa-ncnn.exe``: For decoding a single wave file.
+ - ``sherpa-ncnn-microphone.exe``: For real-time speech recognition from a microphone
+
+That's it!
+
+Please read :ref:`sherpa-ncnn-pre-trained-models` for usages about
+the generated binaries.
+
+Please create an issue at ``_
+if you have any problems.
diff --git a/docs/source/ncnn/ios/build-sherpa-ncnn-swift.rst b/docs/source/ncnn/ios/build-sherpa-ncnn-swift.rst
new file mode 100644
index 000000000..aea0abdf1
--- /dev/null
+++ b/docs/source/ncnn/ios/build-sherpa-ncnn-swift.rst
@@ -0,0 +1,351 @@
+Build sherpa-ncnn for iOS
+=========================
+
+This section describes how to build `sherpa-ncnn`_ for ``iPhone`` and ``iPad``.
+
+Requirement
+-----------
+
+.. warning::
+
+ The minimum deployment requires the iOS version ``>= 13.0``.
+
+
+Before we continue, please make sure the following requirements are satisfied:
+
+- macOS. It won't work on Windows or Linux.
+- Xcode. The version ``14.2 (14C18)`` is known to work. Other versions may also work.
+- CMake. CMake 3.25.1 is known to work. Other versions may also work.
+- (Optional) iPhone or iPad. This is for testing the app on your device.
+ If you don't have a device, you can still run the app within a simulator on your Mac.
+
+.. caution::
+
+ If you get the following error::
+
+ CMake Error at toolchains/ios.toolchain.cmake:544 (get_filename_component):
+ get_filename_component called with incorrect number of arguments
+ Call Stack (most recent call first):
+ /usr/local/Cellar/cmake/3.29.0/share/cmake/Modules/CMakeDetermineSystem.cmake:146 (include)
+ CMakeLists.txt:2 (project)
+
+ please run::
+
+ sudo xcode-select --install
+ sudo xcodebuild -license
+
+ And then delete the build directory ``./build-ios`` and re-build.
+
+ Please see also ``_.
+
+Download sherpa-ncnn
+--------------------
+
+First, let us download the source code of `sherpa-ncnn`_.
+
+.. note::
+
+ In the following, I will download `sherpa-ncnn`_ to
+ ``$HOME/open-source``, i.e., ``/Users/fangjun/open-source``, on my Mac.
+
+ You can put it anywhere as you like.
+
+.. code-block:: bash
+
+ mkdir -p $HOME/open-source
+ cd $HOME/open-source
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+
+Build sherpa-ncnn (in commandline, C++ Part)
+--------------------------------------------
+
+After downloading `sherpa-ncnn`_, let us build the C++ part of `sherpa-ncnn`_.
+
+.. code-block:: bash
+
+ cd $HOME/open-source/sherpa-ncnn/
+ ./build-ios.sh
+
+It will generate a directory
+``$HOME/open-source/sherpa-ncnn/build-ios``, which we have already pre-configured
+for you in Xcode.
+
+.. hint::
+
+ You don't have to look at the generated files in ``$HOME/open-source/sherpa-ncnn/build-ios``
+ to build an app. We have pre-configured it for you.
+
+ If you are eager to learn more about the generated files or want to use
+ `sherpa-ncnn`_ in your own iOS project, please have a look
+ at :ref:`sherpa_ncnn_ios_swift_for_the_more_curious`.
+
+
+Build sherpa-ncnn (in Xcode)
+----------------------------
+
+Use the following command to open `sherpa-ncnn`_ in Xcode:
+
+.. code-block:: bash
+
+ cd $HOME/open-source/sherpa-ncnn/ios-swift/SherpaNcnn
+ open SherpaNcnn.xcodeproj
+
+It will start Xcode and you will see the following screenshot:
+
+ .. figure:: ./pic/start-xcode-for-sherpa-ncnn.png
+ :alt: Screenshot after running the command ``open SherpaNcnn.xcodeproj``
+ :width: 600
+ :align: center
+
+ Screenshot after running the command ``open SherpaNcnn.xcodeproj``
+
+Please select ``Product -> Build`` to build the project. See the screenshot
+below:
+
+ .. figure:: ./pic/select-product-build.png
+ :alt: Screenshot for selecting ``Product -> Build``
+ :width: 600
+ :align: center
+
+ Screenshot for selecting ``Product -> Build``
+
+After finishing the build, you should see the following screenshot:
+
+ .. figure:: ./pic/after-finishing-build.png
+ :alt: Screenshot after finishing the build.
+ :width: 100
+ :align: center
+
+ Screenshot after finishing the build.
+
+Congratulations! You have successfully built the project. Let us run the
+project by selecting ``Product -> Run``, which is shown in the following
+screenshot:
+
+ .. figure:: ./pic/run-the-project.png
+ :alt: Screenshot for ``Product -> Run``.
+ :width: 600
+ :align: center
+
+ Screenshot for ``Product -> Run``.
+
+Please wait for a few seconds before Xcode starts the simulator.
+
+Unfortunately, it will throw the following error:
+
+ .. figure:: ./pic/error-no-model.png
+ :alt: Screenshot for the error
+ :width: 600
+ :align: center
+
+ Screenshot for the error
+
+The reason for the above error is that we have not provided the pre-trained
+model yet.
+
+The file `ViewController.swift `_
+pre-selects the pre-trained model to be :ref:`sherpa-ncnn-mixed-english-chinese-conv-emformer-model`,
+shown in the screenshot below:
+
+ .. figure:: ./pic/pre-trained-model-1.png
+ :alt: Screenshot for the pre-selected pre-trained model
+ :width: 600
+ :align: center
+
+ Screenshot for the pre-selected pre-trained model
+
+Let us add the pre-trained model :ref:`sherpa-ncnn-mixed-english-chinese-conv-emformer-model`
+to Xcode. Please follow :ref:`sherpa-ncnn-mixed-english-chinese-conv-emformer-model`
+to download it from `huggingface `_.
+You can download it to any directory as you like.
+
+Please right click the project ``SherpaNcnn`` and select ``Add Files to "SherpaNcnn"...``
+in the popup menu, as is shown in the screenshot below:
+
+ .. figure:: ./pic/step-to-add-pre-trained-model-1.png
+ :alt: Screenshot for adding files to SherpaNcnn
+ :width: 600
+ :align: center
+
+ Screenshot for adding files to SherpaNcnn
+
+In the popup dialog, switch to the folder where you just downloaded the pre-trained
+model.
+
+In the screenshot below, it is the
+folder ``/Users/fangjun/open-source/icefall-models/sherpa-ncnn-conv-emformer-transducer-2022-12-06``:
+
+ .. figure:: ./pic/step-to-add-pre-trained-model-2.png
+ :alt: Screenshot for navigating to the folder containing the downloaded pre-trained
+ :width: 600
+ :align: center
+
+ Screenshot for navigating to the folder containing the downloaded pre-trained
+
+Select required files and click the button ``Add``:
+
+ .. figure:: ./pic/step-to-add-pre-trained-model-3.png
+ :alt: Screenshot for selecting required files
+ :width: 600
+ :align: center
+
+ Screenshot for selecting required files
+
+After adding pre-trained model files to Xcode, you should see the following
+screenshot:
+
+ .. figure:: ./pic/step-to-add-pre-trained-model-4.png
+ :alt: Screenshot after add pre-trained model files
+ :width: 600
+ :align: center
+
+ Screenshot after add pre-trained model files
+
+At this point, you should be able to select the menu ``Product -> Run``
+to run the project and you should finally see the following screenshot:
+
+ .. figure:: ./pic/run.png
+ :alt: Screenshot for a successful run.
+ :width: 600
+ :align: center
+
+ Screenshot for a successful run.
+
+Click the button to start recording! A screenshot is given below:
+
+ .. figure:: ./pic/run-2.png
+ :alt: Screenshot for recording and recognition.
+ :width: 600
+ :align: center
+
+ Screenshot for recording and recognition.
+
+Congratulations! You have finally succeeded in running `sherpa-ncnn`_ with iOS,
+though it is in a simulator.
+
+Please read below if you want to run `sherpa-ncnn`_ on your iPhone or iPad.
+
+Run sherpa-ncnn on your iPhone/iPad
+-----------------------------------
+
+First, please make sure the iOS version of your iPhone/iPad is ``>= 13.0``.
+
+Click the menu ``Xcode -> Settings...``, as is shown in the following screenshot:
+
+ .. figure:: ./pic/xcode-settings.png
+ :alt: Screenshot for ``Xcode -> Settings...``
+ :width: 600
+ :align: center
+
+ Screenshot for ``Xcode -> Settings...``
+
+In the popup dialog, please select ``Account`` and click ``+`` to add
+your Apple ID, as is shown in the following ``screenshots``.
+
+ .. figure:: ./pic/add-an-account.png
+ :alt: Screenshot for selecting ``Account`` and click ``+``.
+ :width: 600
+ :align: center
+
+ Screenshot for selecting ``Account`` and click ``+``.
+
+ .. figure:: ./pic/add-an-account-2.png
+ :alt: Screenshot for selecting ``Apple ID`` and click ``Continue``
+ :width: 600
+ :align: center
+
+ Screenshot for selecting ``Apple ID`` and click ``Continue``
+
+ .. figure:: ./pic/add-an-account-3.png
+ :alt: Screenshot for adding your Apple ID and click ``Next``
+ :width: 600
+ :align: center
+
+ Screenshot for adding your Apple ID and click ``Next``
+
+ .. figure:: ./pic/add-an-account-4.png
+ :alt: Screenshot for entering your password and click ``Next``
+ :width: 600
+ :align: center
+
+ Screenshot for entering your password and click ``Next``
+
+ .. figure:: ./pic/add-an-account-5.png
+ :alt: Screenshot after adding your Apple ID
+ :width: 600
+ :align: center
+
+ Screenshot after adding your Apple ID
+
+After adding your Apple ID, please connect your iPhone or iPad to your Mac
+and select your device in Xcode. The following screenshot is an example
+to select my iPhone.
+
+ .. figure:: ./pic/select-device.png
+ :alt: Screenshot for selecting your device
+ :width: 600
+ :align: center
+
+ Screenshot for selecting your device
+
+Now your Xcode should look like below after selecting a device:
+
+ .. figure:: ./pic/select-device-2.png
+ :alt: Screenshot after selecting your device
+ :width: 600
+ :align: center
+
+ Screenshot after selecting your device
+
+Please select ``Product -> Run`` again to run `sherpa-ncnn`_ on your selected
+device, as is shown in the following screenshot:
+
+ .. figure:: ./pic/run-3.png
+ :alt: Screenshot for selecting ``Product -> Run``
+ :width: 600
+ :align: center
+
+ Screenshot for selecting ``Product -> Run``
+
+After a successful build, check your iPhone/iPad and you should see the following
+screenshot:
+
+ .. figure:: ./pic/run-4.jpg
+ :alt: Screenshot for running sherpa-ncnn on your device
+ :width: 300
+ :align: center
+
+ Screenshot for running sherpa-ncnn on your device
+
+To fix that, please select ``Settings -> General -> Device Management``
+on your device
+
+ .. figure:: ./pic/run-5.jpg
+ :alt: Screenshot for selecting `Settings -> General -> Device Management` on your device
+ :width: 300
+ :align: center
+
+ Screenshot for selecting `Settings -> General -> Device Management` on your device
+
+Please click ``Apple Development: csukuangfj...`` and click ``Trust "Apple Development: csukuangfj@g..."``
+in the subsequent dialog, as is shown below:
+
+ .. figure:: ./pic/run-6.jpg
+ :alt: Screenshot for "Trust "Apple Development: csukuangfj@g...""
+ :width: 300
+ :align: center
+
+ Screenshot for "Trust "Apple Development: csukuangfj@g...""
+
+At this point, you should be able to run the app on your device. The following is a screenshot
+about running it on my iPhone:
+
+ .. figure:: ./pic/run-7.jpg
+ :alt: Screenshot for running `sherpa-ncnn`_ on iPhone
+ :width: 300
+ :align: center
+
+ Screenshot for running `sherpa-ncnn`_ on iPhone
+
+
+Congratulations! You have successfully run `sherpa-ncnn`_ on your device!
diff --git a/docs/source/ncnn/ios/demo-videos.rst b/docs/source/ncnn/ios/demo-videos.rst
new file mode 100644
index 000000000..9577ad159
--- /dev/null
+++ b/docs/source/ncnn/ios/demo-videos.rst
@@ -0,0 +1,22 @@
+.. _sherpa-ncnn-ios-video-demos:
+
+Video demos
+===========
+
+In this page, we list some videos about using `sherpa-ncnn`_ for
+real-time speech recognition on ``iPhone`` and ``iPad``.
+
+
+Video 1: Chinese + English on iPhone 14 Pro (simulator)
+-------------------------------------------------------
+
+.. raw:: html
+
+
+
+Video 2: Chinese + English on iPad 11 Pro (simulator)
+-----------------------------------------------------
+
+.. raw:: html
+
+
diff --git a/docs/source/ncnn/ios/for-the-more-curious-swift.rst b/docs/source/ncnn/ios/for-the-more-curious-swift.rst
new file mode 100644
index 000000000..e2c63e2f9
--- /dev/null
+++ b/docs/source/ncnn/ios/for-the-more-curious-swift.rst
@@ -0,0 +1,245 @@
+.. _sherpa_ncnn_ios_swift_for_the_more_curious:
+
+For the more curious
+====================
+
+This section is for those who want to learn more about how to use
+`sherpa-ncnn`_ in an iOS project.
+
+Files generated by running ./build-ios.sh
+-----------------------------------------
+
+After running:
+
+.. code-block:: bash
+
+ ./build-ios.sh
+
+You may be curious about the generated files.
+
+.. hint::
+
+ Please have a look at ``./build-ios.sh`` so that you know what it does for you.
+
+The above command generates files inside the directory ``./build-ios``:
+
+.. code-block:: bash
+
+ sherpa-ncnn fangjun$ ls -lh build-ios
+ total 1912
+ drwxr-xr-x 6 fangjun staff 192B Feb 26 16:48 build
+ drwxr-xr-x 4 fangjun staff 128B Feb 26 16:46 install
+ drwxr-xr-x 15 fangjun staff 480B Feb 14 18:09 openmp-11.0.0.src
+ -rw-r--r-- 1 fangjun staff 952K Dec 8 2021 openmp-11.0.0.src.tar.xz
+ drwxr-xr-x 6 fangjun staff 192B Feb 26 16:44 openmp.xcframework
+ drwxr-xr-x 6 fangjun staff 192B Feb 26 16:48 sherpa-ncnn.xcframework
+
+What is interesting here is the two framework folders ``openmp.xcframework``
+and ``sherpa-ncnn.xcframework``.
+All other folders can be safely removed. We only need the two framework folders.
+
+
+In the following, we describe the content in these two framework folders.
+
+openmp.xcframework
+~~~~~~~~~~~~~~~~~~
+
+.. code-block::
+
+ $ tree build-ios/openmp.xcframework/
+ build-ios/openmp.xcframework/
+ ├── Headers
+ │ └── omp.h
+ ├── Info.plist
+ ├── ios-arm64
+ │ └── libomp.a
+ └── ios-arm64_x86_64-simulator
+ └── libomp.a
+
+ 3 directories, 4 files
+
+**Explanation**:
+
+ - ``omp.h``: The header file, which is used by `ncnn`_
+ - ``Info.plist``: A file that is dedicated for framework on macOS/iOS
+ - ``ios-arm64/libopm.a``: A static library for iOS device, e.g., for iPhone
+ - ``ios-arm64_x86_64-simulator/libomp.a``: A static library for iOS
+ simulators, including simulators for Intel chips and Apple Silicon (e.g., M1)
+
+.. code-block:: bash
+
+ sherpa-ncnn fangjun$ file build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a
+ build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random library] [arm64:current ar archive random library]
+ build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a (for architecture x86_64): current ar archive random library
+ build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a (for architecture arm64): current ar archive random library
+
+ sherpa-ncnn fangjun$ lipo -info build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a
+ Architectures in the fat file: build-ios/openmp.xcframework/ios-arm64_x86_64-simulator/libomp.a are: x86_64 arm64
+
+ sherpa-ncnn fangjun$ file build-ios/openmp.xcframework/ios-arm64/libomp.a
+ build-ios/openmp.xcframework/ios-arm64/libomp.a: current ar archive random library
+
+ sherpa-ncnn fangjun$ lipo -info build-ios/openmp.xcframework/ios-arm64/libomp.a
+ Non-fat file: build-ios/openmp.xcframework/ios-arm64/libomp.a is architecture: arm64
+
+sherpa-ncnn.xcframework
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ sherpa-ncnn fangjun$ tree build-ios/sherpa-ncnn.xcframework/
+ build-ios/sherpa-ncnn.xcframework/
+ ├── Headers
+ │ └── sherpa-ncnn
+ │ └── c-api
+ │ └── c-api.h
+ ├── Info.plist
+ ├── ios-arm64
+ │ └── sherpa-ncnn.a
+ └── ios-arm64_x86_64-simulator
+ └── sherpa-ncnn.a
+
+ 5 directories, 4 files
+
+**Explanation**:
+
+ - ``c-api.h``: The header file, which is copied from
+ ``_
+ - ``Info.plist``: A file that is dedicated for framework on macOS/iOS
+ - ``ios-arm64/sherpa-ncnn.a``: A static library for iOS, e.g., iPhone
+ - ``ios-arm64_x86_64-simulator/sherpa-ncnn.a``: A static library for
+ simulators, including simulators for Intel chips and Apple Silicon (e.g., M1)
+
+.. code-block:: bash
+
+ sherpa-ncnn fangjun$ file build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a
+ build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive] [arm64]
+ build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a (for architecture x86_64): current ar archive
+ build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a (for architecture arm64): current ar archive
+
+ sherpa-ncnn fangjun$ lipo -info build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a
+ Architectures in the fat file: build-ios/sherpa-ncnn.xcframework/ios-arm64_x86_64-simulator/sherpa-ncnn.a are: x86_64 arm64
+
+ sherpa-ncnn fangjun$ file build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a
+ build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a: current ar archive
+
+ sherpa-ncnn fangjun$ lipo -info build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a
+ Non-fat file: build-ios/sherpa-ncnn.xcframework/ios-arm64/sherpa-ncnn.a is architecture: arm64
+
+How to use files generated by ./build-ios.sh in Xcode
+-----------------------------------------------------
+
+In this section, we describe how to use ``openmp.xcframework`` and
+``sherpa-ncnn.xcframework`` in Xcode.
+
+The underlying implementation of `sherpa-ncnn`_ is in C++. It also provides
+`C API `_.
+
+To use ``C API`` in Xcode with `Swift `_, we have to
+write a `bridging header `_.
+
+We provide a bridging header for you: `SherpaNcnn-Bridging-Header.h `_. All you need is to add this file to your iOS project
+and click ``Build Settings -> Swift Compiler - General`` and set ``Objective-C Bridging Header``
+to ``${PROJECT_DIR}/../../swift-api-examples/SherpaNcnn-Bridging-Header.h``. See
+the screenshot below for reference:
+
+ .. figure:: ./pic/set-bridging-header.png
+ :alt: Screenshot for setting the bridging header
+ :width: 600
+ :align: center
+
+ Screenshot for setting the bridging header
+
+We list the content of the bridging header below for reference:
+
+.. code-block:: swift
+
+ #ifndef SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_
+ #define SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_
+
+ #import "sherpa-ncnn/c-api/c-api.h"
+
+ #endif // SWIFT_API_EXAMPLES_SHERPANCNN_BRIDGING_HEADER_H_
+
+After adding the bridging header to your iOS project, Xcode will complain
+it cannot find ``sherpa-ncnn/c-api/c-api.h``. The fix is to add the path
+``build-ios/sherpa-ncnn.xcframework/Headers`` to ``Header Search Paths`` by changing
+``Build Settings -> Search Paths -> Header Search Paths``, as is shown in the
+following screenshot:
+
+ .. figure:: ./pic/header-search-path.png
+ :alt: Screenshot for setting the header search paths
+ :width: 600
+ :align: center
+
+ Screenshot for setting the header search paths
+
+.. hint::
+
+ Instead of using an absolute path, we use
+ ``${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/``
+
+ For instance, my `sherpa-ncnn`_ is downloaded to
+ ``/Users/fangjun/open-source/sherpa-ncnn`` and the path to ``sherpa-ncnn.xcframework``
+ is ``/Users/fangjun/open-source/sherpa-ncnn/build-ios/sherpa-ncnn.xcframework``.
+
+ The value of ``PROJECT_DIR`` is
+ ``/Users/fangjun/open-source/sherpa-ncnn/ios-swift/SherpaNcnn``, so
+ we can use ``${PROJECT_DIR}/../../build-ios/sherpa-ncnn.xcframework/Headers/``.
+
+ Also note that ``PROJECT_DIR`` is a pre-defined variable in Xcode.
+
+Please also add `SherpaNcnn.swift `_
+to your iOS project, which is a utility to make it easier to access functions from the bridging header.
+
+The next thing is to add ``openmp.xcframework`` and ``sherpa-ncnn.xcframework``
+as dependencies to you iOS project. Select ``Build Phases -> Link Binary with Libraries``
+and then click ``+`` to add ``sherpa-ncnn.xcframework`` and ``openmp.xcframework``.
+See the screenshot below for reference:
+
+ .. figure:: ./pic/add-framework-to-your-project.png
+ :alt: Screenshot for adding a framework to your project
+ :width: 600
+ :align: center
+
+ Screenshot for adding a framework to your project
+
+.. hint::
+
+ After clicking ``+``, please select ``Add Other... -> Add Files..``, and then
+ add the path to ``sherpa-ncnn.xcframework``.
+
+ Repeat the step for ``openmp.xcframework``.
+
+ See the screenshot below for reference:
+
+ .. figure:: ./pic/add-other.png
+ :alt: Screenshot for adding a framework
+ :width: 300
+ :align: center
+
+ Screenshot for adding a framework
+
+One more thing you need to do after adding the framework is to setup the framework
+search path. Click ``Build Settings -> Search Paths -> Framework Search Paths``
+and add the path to ``build-ios/``. See the screenshot below:
+
+ .. figure:: ./pic/set-framework-search-path.png
+ :alt: Screenshot for setting framework search paths
+ :width: 600
+ :align: center
+
+ Screenshot for setting framework search paths
+
+If you encounter link errors about the C++ standard library, please add
+``-lc++`` to link against ``libc++`` by clicking ``Build Settings -> Linking -> Other Linker Flags``
+and adding ``-lc++``. See the screenshot below for reference:
+
+ .. figure:: ./pic/link-libc++.png
+ :alt: Screenshot for adding ``-lc++`` to linker flags
+ :width: 600
+ :align: center
+
+ Screenshot for adding ``-lc++`` to linker flags
+
+That is all you need to add `sherpa-ncnn`_ to your iOS project.
diff --git a/docs/source/ncnn/ios/index.rst b/docs/source/ncnn/ios/index.rst
new file mode 100644
index 000000000..b46c34a63
--- /dev/null
+++ b/docs/source/ncnn/ios/index.rst
@@ -0,0 +1,22 @@
+.. _sherpa-ncnn-ios:
+
+iOS
+===
+
+In this section, we describe how to build an iOS app for ``real-time`` speech
+recognition with `sherpa-ncnn`_ and run it within a simulator on your Mac,
+run it on you iPhone or iPad.
+
+We also provide video demos for real-time speech recognition.
+
+.. hint::
+
+ During speech recognition, it does not need to access the Internet.
+ Everyting is processed locally on your iPhone or iPad.
+
+.. toctree::
+ :maxdepth: 3
+
+ demo-videos
+ build-sherpa-ncnn-swift
+ for-the-more-curious-swift
diff --git a/docs/source/ncnn/ios/pic/add-an-account-2.png b/docs/source/ncnn/ios/pic/add-an-account-2.png
new file mode 100644
index 000000000..55fec26a7
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-an-account-2.png differ
diff --git a/docs/source/ncnn/ios/pic/add-an-account-3.png b/docs/source/ncnn/ios/pic/add-an-account-3.png
new file mode 100644
index 000000000..f8b0a5f49
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-an-account-3.png differ
diff --git a/docs/source/ncnn/ios/pic/add-an-account-4.png b/docs/source/ncnn/ios/pic/add-an-account-4.png
new file mode 100644
index 000000000..2181f535e
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-an-account-4.png differ
diff --git a/docs/source/ncnn/ios/pic/add-an-account-5.png b/docs/source/ncnn/ios/pic/add-an-account-5.png
new file mode 100644
index 000000000..43595ed90
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-an-account-5.png differ
diff --git a/docs/source/ncnn/ios/pic/add-an-account.png b/docs/source/ncnn/ios/pic/add-an-account.png
new file mode 100644
index 000000000..2ae37a54a
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-an-account.png differ
diff --git a/docs/source/ncnn/ios/pic/add-framework-to-your-project.png b/docs/source/ncnn/ios/pic/add-framework-to-your-project.png
new file mode 100644
index 000000000..c0ed3e70c
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-framework-to-your-project.png differ
diff --git a/docs/source/ncnn/ios/pic/add-other.png b/docs/source/ncnn/ios/pic/add-other.png
new file mode 100644
index 000000000..fed3f8adb
Binary files /dev/null and b/docs/source/ncnn/ios/pic/add-other.png differ
diff --git a/docs/source/ncnn/ios/pic/after-finishing-build.png b/docs/source/ncnn/ios/pic/after-finishing-build.png
new file mode 100644
index 000000000..7b8ed2379
Binary files /dev/null and b/docs/source/ncnn/ios/pic/after-finishing-build.png differ
diff --git a/docs/source/ncnn/ios/pic/error-no-model.png b/docs/source/ncnn/ios/pic/error-no-model.png
new file mode 100644
index 000000000..7c233f26a
Binary files /dev/null and b/docs/source/ncnn/ios/pic/error-no-model.png differ
diff --git a/docs/source/ncnn/ios/pic/header-search-path.png b/docs/source/ncnn/ios/pic/header-search-path.png
new file mode 100644
index 000000000..e2a9ca7fb
Binary files /dev/null and b/docs/source/ncnn/ios/pic/header-search-path.png differ
diff --git a/docs/source/ncnn/ios/pic/link-libc++.png b/docs/source/ncnn/ios/pic/link-libc++.png
new file mode 100644
index 000000000..de7d1f2b4
Binary files /dev/null and b/docs/source/ncnn/ios/pic/link-libc++.png differ
diff --git a/docs/source/ncnn/ios/pic/pre-trained-model-1.png b/docs/source/ncnn/ios/pic/pre-trained-model-1.png
new file mode 100644
index 000000000..1544830a2
Binary files /dev/null and b/docs/source/ncnn/ios/pic/pre-trained-model-1.png differ
diff --git a/docs/source/ncnn/ios/pic/run-2.png b/docs/source/ncnn/ios/pic/run-2.png
new file mode 100644
index 000000000..2853cfc6e
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-2.png differ
diff --git a/docs/source/ncnn/ios/pic/run-3.png b/docs/source/ncnn/ios/pic/run-3.png
new file mode 100644
index 000000000..5a5ce5b57
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-3.png differ
diff --git a/docs/source/ncnn/ios/pic/run-4.jpg b/docs/source/ncnn/ios/pic/run-4.jpg
new file mode 100644
index 000000000..1574a1ddd
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-4.jpg differ
diff --git a/docs/source/ncnn/ios/pic/run-5.jpg b/docs/source/ncnn/ios/pic/run-5.jpg
new file mode 100644
index 000000000..8461a0d7c
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-5.jpg differ
diff --git a/docs/source/ncnn/ios/pic/run-6.jpg b/docs/source/ncnn/ios/pic/run-6.jpg
new file mode 100644
index 000000000..9cfd4a33c
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-6.jpg differ
diff --git a/docs/source/ncnn/ios/pic/run-7.jpg b/docs/source/ncnn/ios/pic/run-7.jpg
new file mode 100644
index 000000000..c522f097b
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-7.jpg differ
diff --git a/docs/source/ncnn/ios/pic/run-the-project.png b/docs/source/ncnn/ios/pic/run-the-project.png
new file mode 100644
index 000000000..e5c6bb42b
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run-the-project.png differ
diff --git a/docs/source/ncnn/ios/pic/run.png b/docs/source/ncnn/ios/pic/run.png
new file mode 100644
index 000000000..350b6db8a
Binary files /dev/null and b/docs/source/ncnn/ios/pic/run.png differ
diff --git a/docs/source/ncnn/ios/pic/select-device-2.png b/docs/source/ncnn/ios/pic/select-device-2.png
new file mode 100644
index 000000000..0b7b5add2
Binary files /dev/null and b/docs/source/ncnn/ios/pic/select-device-2.png differ
diff --git a/docs/source/ncnn/ios/pic/select-device.png b/docs/source/ncnn/ios/pic/select-device.png
new file mode 100644
index 000000000..c2acbe6d8
Binary files /dev/null and b/docs/source/ncnn/ios/pic/select-device.png differ
diff --git a/docs/source/ncnn/ios/pic/select-product-build.png b/docs/source/ncnn/ios/pic/select-product-build.png
new file mode 100644
index 000000000..3ad430fe1
Binary files /dev/null and b/docs/source/ncnn/ios/pic/select-product-build.png differ
diff --git a/docs/source/ncnn/ios/pic/set-bridging-header.png b/docs/source/ncnn/ios/pic/set-bridging-header.png
new file mode 100644
index 000000000..7cb23c7b8
Binary files /dev/null and b/docs/source/ncnn/ios/pic/set-bridging-header.png differ
diff --git a/docs/source/ncnn/ios/pic/set-framework-search-path.png b/docs/source/ncnn/ios/pic/set-framework-search-path.png
new file mode 100644
index 000000000..5ffe3ccdb
Binary files /dev/null and b/docs/source/ncnn/ios/pic/set-framework-search-path.png differ
diff --git a/docs/source/ncnn/ios/pic/start-xcode-for-sherpa-ncnn.png b/docs/source/ncnn/ios/pic/start-xcode-for-sherpa-ncnn.png
new file mode 100644
index 000000000..fe87282a2
Binary files /dev/null and b/docs/source/ncnn/ios/pic/start-xcode-for-sherpa-ncnn.png differ
diff --git a/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-1.png b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-1.png
new file mode 100644
index 000000000..196dde51e
Binary files /dev/null and b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-1.png differ
diff --git a/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-2.png b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-2.png
new file mode 100644
index 000000000..8fbab6a13
Binary files /dev/null and b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-2.png differ
diff --git a/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-3.png b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-3.png
new file mode 100644
index 000000000..b8d584f70
Binary files /dev/null and b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-3.png differ
diff --git a/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-4.png b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-4.png
new file mode 100644
index 000000000..7cd845a0a
Binary files /dev/null and b/docs/source/ncnn/ios/pic/step-to-add-pre-trained-model-4.png differ
diff --git a/docs/source/ncnn/ios/pic/xcode-settings.png b/docs/source/ncnn/ios/pic/xcode-settings.png
new file mode 100644
index 000000000..dfb6e7f98
Binary files /dev/null and b/docs/source/ncnn/ios/pic/xcode-settings.png differ
diff --git a/docs/source/ncnn/pic/rule1.png b/docs/source/ncnn/pic/rule1.png
new file mode 100644
index 000000000..9273d3699
Binary files /dev/null and b/docs/source/ncnn/pic/rule1.png differ
diff --git a/docs/source/ncnn/pic/rule2.png b/docs/source/ncnn/pic/rule2.png
new file mode 100644
index 000000000..d606e0881
Binary files /dev/null and b/docs/source/ncnn/pic/rule2.png differ
diff --git a/docs/source/ncnn/pic/rule3.png b/docs/source/ncnn/pic/rule3.png
new file mode 100644
index 000000000..01a5735a4
Binary files /dev/null and b/docs/source/ncnn/pic/rule3.png differ
diff --git a/docs/source/ncnn/pretrained_models/code-lstm/2022-09-05.txt b/docs/source/ncnn/pretrained_models/code-lstm/2022-09-05.txt
new file mode 100644
index 000000000..5d4ca92c4
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-lstm/2022-09-05.txt
@@ -0,0 +1,16 @@
+ModelConfig(encoder_param="./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-2022-09-05/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-2022-09-05/test_wavs/1089-134686-0001.wav
+wav duration (s): 6.625
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-2022-09-05/test_wavs/1089-134686-0001.wav
+ AFTER EARLY NIGHTFALL THE YELLOW LAMPS WOULD LIGHT UP HERE AND THERE THE SQUALID QUARTER OF THE BROTHELS
+ModelConfig(encoder_param="./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-2022-09-05/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-2022-09-05/test_wavs/1089-134686-0001.wav
+wav duration (s): 6.625
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-2022-09-05/test_wavs/1089-134686-0001.wav
+ AFTER EARLY NIGHTFALL THE YELLOW LAMPS WOULD LIGHT UP HERE AND THERE THE SQUALID QUARTER OF THE BROTHELS
diff --git a/docs/source/ncnn/pretrained_models/code-lstm/2022-09-30.txt b/docs/source/ncnn/pretrained_models/code-lstm/2022-09-30.txt
new file mode 100644
index 000000000..3424e742f
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-lstm/2022-09-30.txt
@@ -0,0 +1,16 @@
+ModelConfig(encoder_param="./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-2022-09-30/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-2022-09-30/test_wavs/0.wav
+wav duration (s): 5.61462
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-2022-09-30/test_wavs/0.wav
+对我做了介绍那么我想说的是呢大家如果对我的研究感兴趣
+ModelConfig(encoder_param="./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-2022-09-30/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-2022-09-30/test_wavs/0.wav
+wav duration (s): 5.61462
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-2022-09-30/test_wavs/0.wav
+对我做了介绍那么我想说的是呢大家如果对我的研究感兴趣
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13-sherpa-ncnn.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13-sherpa-ncnn.txt
new file mode 100644
index 000000000..ce0b11cae
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13-sherpa-ncnn.txt
@@ -0,0 +1,20 @@
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/1.wav
+wav duration (s): 5.1
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/1.wav
+这是第一种第二种叫呃与 ALWAYS ALWAYS什么意思啊
+Elapsed seconds: 0.598 s
+Real time factor (RTF): 0.598 / 5.100 = 0.117
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/1.wav
+wav duration (s): 5.1
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/1.wav
+这是第一种第二种叫呃与 ALWAYS ALWAYS什么意思啊
+Elapsed seconds: 0.943 s
+Real time factor (RTF): 0.943 / 5.100 = 0.185
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-en-2023-02-13-sherpa-ncnn.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-en-2023-02-13-sherpa-ncnn.txt
new file mode 100644
index 000000000..7d23077aa
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-en-2023-02-13-sherpa-ncnn.txt
@@ -0,0 +1,20 @@
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/test_wavs/1221-135766-0002.wav
+wav duration (s): 4.825
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/test_wavs/1221-135766-0002.wav
+ YET THESE THOUGHTS AFFECTED HESTER PRYNNE LESS WITH HOPE THAN APPREHENSION
+Elapsed seconds: 0.569 s
+Real time factor (RTF): 0.569 / 4.825 = 0.118
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-en-2023-02-13/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/test_wavs/1221-135766-0002.wav
+wav duration (s): 4.825
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/test_wavs/1221-135766-0002.wav
+ YET THESE THOUGHTS AFFECTED HESTER PRYNNE LESS WITH HOPE THAN APPREHENSION
+Elapsed seconds: 0.554 s
+Real time factor (RTF): 0.554 / 4.825 = 0.115
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-fr-2023-04-14.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-fr-2023-04-14.txt
new file mode 100644
index 000000000..7adaf2ba4
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-fr-2023-04-14.txt
@@ -0,0 +1,20 @@
+RecognizerConfig(feat_config=FeatureExtractorConfig(sampling_rate=16000, feature_dim=80), model_config=ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2), decoder_config=DecoderConfig(method="greedy_search", num_active_paths=4), endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)), enable_endpoint=False)
+wav filename: ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav
+wav duration (s): 7.128
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav
+text: CE SITE CONTIENT QUATRE TOMBEAUX DE LA DYNASTIE ASHÉMÉNIDE ET SEPT DES SASSANDIDES
+timestamps: 0.96 1.44 1.52 1.76 1.96 2.08 2.28 2.56 2.64 2.76 2.8 2.96 3.04 3.2 3.28 3.4 3.48 3.72 3.8 4 4.16 4.24 4.32 4.44 4.6 4.68 4.92 5.2 5.52 5.84 6.04 6.12 6.24 6.56 6.68
+Elapsed seconds: 1.082 s
+Real time factor (RTF): 1.082 / 7.128 = 0.152
+RecognizerConfig(feat_config=FeatureExtractorConfig(sampling_rate=16000, feature_dim=80), model_config=ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2), decoder_config=DecoderConfig(method="modified_beam_search", num_active_paths=4), endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)), enable_endpoint=False)
+wav filename: ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav
+wav duration (s): 7.128
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav
+text: CE SITE CONTIENT QUATRE TOMBEAUX DE LA DYNASTIE ASHÉMÉNIDE ET SEPT DES SASSANDIDES
+timestamps: 0.96 1.44 1.52 1.76 1.96 2.08 2.28 2.56 2.64 2.76 2.8 2.96 3.04 3.2 3.28 3.4 3.48 3.72 3.8 4 4.16 4.24 4.32 4.44 4.6 4.68 4.92 5.2 5.52 5.84 6.04 6.12 6.24 6.56 6.68
+Elapsed seconds: 0.812 s
+Real time factor (RTF): 0.812 / 7.128 = 0.114
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-20M-en-2023-02-19.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-20M-en-2023-02-19.txt
new file mode 100644
index 000000000..ab69ef4b7
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-20M-en-2023-02-19.txt
@@ -0,0 +1,12 @@
+Disable fp16 for Zipformer encoder
+Don't Use GPU. has_gpu: 0, config.use_vulkan_compute: 1
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/test_wavs/0.wav
+wav duration (s): 6.625
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/test_wavs/0.wav
+ AFTER EARLY NIGHTFALL THE YELLOW LAMPS WOULD LIGHT UP HERE AND THERE THE SQUALID QUARTER OF THE BRAFFLELS
+Elapsed seconds: 0.472 s
+Real time factor (RTF): 0.472 / 6.625 = 0.071
\ No newline at end of file
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.txt
new file mode 100644
index 000000000..05ff5b03e
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.txt
@@ -0,0 +1,16 @@
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="greedy_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav
+wav duration (s): 5.1
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav
+这是第一种第二种叫呃与 ALWAYS什么意思啊
+ModelConfig(encoder_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.bin", tokens="./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt", encoder num_threads=2, decoder num_threads=2, joiner num_threads=2)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav
+wav duration (s): 5.1
+Started!
+Done!
+Recognition result for ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav
+这是第一种第二种叫呃与 ALWAYS什么意思啊
diff --git a/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-zh-small-14M-2023-02-23.txt b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-zh-small-14M-2023-02-23.txt
new file mode 100644
index 000000000..f6101d43b
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/code-zipformer/sherpa-ncnn-streaming-zipformer-zh-small-14M-2023-02-23.txt
@@ -0,0 +1,38 @@
+Disable fp16 for Zipformer encoder
+Don't Use GPU. has_gpu: 0, config.use_vulkan_compute: 1
+ModelConfig(encoder_param="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.bin", tokens="data/lang_char/tokens.txt", encoder num_threads=4, decoder num_threads=4, joiner num_threads=4)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./test_wavs_zh/0.wav
+wav duration (s): 5.6115
+Started!
+Done!
+Recognition result for ./test_wavs_zh/0.wav
+对我做了介绍那么我想说的是大家如果对我的研究感兴趣
+Elapsed seconds: 0.678 s
+Real time factor (RTF): 0.678 / 5.611 = 0.121
+
+Disable fp16 for Zipformer encoder
+Don't Use GPU. has_gpu: 0, config.use_vulkan_compute: 1
+ModelConfig(encoder_param="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.bin", tokens="data/lang_char/tokens.txt", encoder num_threads=4, decoder num_threads=4, joiner num_threads=4)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./test_wavs_zh/1.wav
+wav duration (s): 5.15306
+Started!
+Done!
+Recognition result for ./test_wavs_zh/1.wav
+重点想谈三个问题首先就是这一轮全球金融动的表现
+Elapsed seconds: 0.676 s
+Real time factor (RTF): 0.676 / 5.153 = 0.131
+
+Disable fp16 for Zipformer encoder
+Don't Use GPU. has_gpu: 0, config.use_vulkan_compute: 1
+ModelConfig(encoder_param="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.param", encoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/encoder_jit_trace-pnnx.ncnn.bin", decoder_param="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.param", decoder_bin="pruned_transducer_stateless7_streaming/exp-small-L/decoder_jit_trace-pnnx.ncnn.bin", joiner_param="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.param", joiner_bin="pruned_transducer_stateless7_streaming/exp-small-L/joiner_jit_trace-pnnx.ncnn.bin", tokens="data/lang_char/tokens.txt", encoder num_threads=4, decoder num_threads=4, joiner num_threads=4)
+DecoderConfig(method="modified_beam_search", num_active_paths=4, enable_endpoint=False, endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.4, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)))
+wav filename: ./test_wavs_zh/2.wav
+wav duration (s): 4.52431
+Started!
+Done!
+Recognition result for ./test_wavs_zh/2.wav
+深入地分析这一次全球金融动荡背后的根源
+Elapsed seconds: 0.592 s
+Real time factor (RTF): 0.592 / 4.524 = 0.131
\ No newline at end of file
diff --git a/docs/source/ncnn/pretrained_models/conv-emformer-transducer-models.rst b/docs/source/ncnn/pretrained_models/conv-emformer-transducer-models.rst
new file mode 100644
index 000000000..6b0443a41
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/conv-emformer-transducer-models.rst
@@ -0,0 +1,437 @@
+Conv-Emformer-transducer-based Models
+=====================================
+
+.. hint::
+
+ Please refer to :ref:`install_sherpa_ncnn` to install `sherpa-ncnn`_
+ before you read this section.
+
+.. _marcoyang_sherpa_ncnn_conv_emformer_transducer_small_2023_01_09_english:
+
+marcoyang/sherpa-ncnn-conv-emformer-transducer-small-2023-01-09 (English)
+-------------------------------------------------------------------------
+
+This model is a small version of `conv-emformer-transducer `_
+trained in `icefall`_.
+
+It only has ``8.8 million parameters`` and can be deployed on ``embedded devices``
+for real-time speech recognition. You can find the models in ``fp16`` and ``int8`` format
+at ``_.
+
+This model is trained using `LibriSpeech`_ and thus it supports only English.
+
+In the following, we show you how to download it and
+deploy it with `sherpa-ncnn`_ on an embedded device, whose CPU is
+`RV1126 `_
+(Quad core ARM Cortex-A7)
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-conv-emformer-transducer-small-2023-01-09.tar.bz2
+ tar xvf sherpa-ncnn-conv-emformer-transducer-small-2023-01-09.tar.bz2
+
+.. note::
+
+ Please refer to :ref:`sherpa-ncnn-embedded-linux-arm-install` for how to
+ compile `sherpa-ncnn`_ for a 32-bit ARM platform. In the following, we
+ test the pre-trained model on an embedded device, whose CPU is
+ `RV1126 `_
+ (Quad core ARM Cortex-A7).
+
+Decode a single wave file with ./build/bin/sherpa-ncnn
+::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/test_wavs/1089-134686-0001.wav \
+
+The outputs are shown below. The CPU used for decoding is RV1126 (Quad core ARM Cortex-A7).
+
+.. figure:: ./pic/2023-01-09-fp32-decoding.png
+ :alt: Decoding time and decoding result of float32 model
+ :width: 800
+
+.. note::
+
+ The default option uses 4 threads and ``greedy_search`` for decoding.
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Decode a single wave file with ./build/bin/sherpa-ncnn (with int8 quantization)
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. note::
+
+ We also support int8 quantization to compresss the model and speed up inference.
+ Currently, only encoder and joiner are quantized.
+
+To decode the int8-quantized model, use the following command:
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.int8.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/encoder_jit_trace-pnnx.ncnn.int8.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.int8.param \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/joiner_jit_trace-pnnx.ncnn.int8.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-small-2023-01-09/test_wavs/1089-134686-0001.wav \
+
+The outputs are shown below. The CPU used for decoding is RV1126 (Quad core ARM Cortex-A7).
+
+.. figure:: ./pic/2023-01-09-int8-decoding.png
+ :alt: Decoding time and decoding result of int8 model
+ :width: 800
+
+Compared to the original model in ``fp16`` format,
+the decoding speed is significantly improved. The decoding time is changed from
+``3.26 s`` to ``2.44 s``.
+
+.. note::
+
+ When the model's weights are quantized to ``float16``, it is converted
+ to ``float32`` during computation.
+
+ When the model's weights are quantized to ``int8``, it is using ``int8``
+ during computation.
+
+.. hint::
+
+ Even if we use only 1 thread for the ``int8`` model, the resulting real
+ time factor (RTF) is still less than ``1``.
+
+.. _sherpa-ncnn-mixed-english-chinese-conv-emformer-model:
+
+csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-06 (Chinese + English)
+------------------------------------------------------------------------------
+
+This model is converted from ``_,
+which supports both Chinese and English.
+
+.. hint::
+
+ If you want to train your own model that is able to support both Chinese and
+ English, please refer to our training code:
+
+ ``_
+
+ You can also try the pre-trained models in your browser without installing anything
+ by visiting:
+
+ ``_
+
+In the following, we describe how to download and use it with `sherpa-ncnn`_.
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-conv-emformer-transducer-2022-12-06.tar.bz2
+ tar xvf sherpa-ncnn-conv-emformer-transducer-2022-12-06.tar.bz2
+
+Decode a single wave file with ./build/bin/sherpa-ncnn
+::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/0.wav \
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone with build/bin/sherpa-ncnn-microphone
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn-microphone.exe`` for Windows.
+
+It will print something like below:
+
+.. code-block::
+
+ Number of threads: 4
+ num devices: 4
+ Use default device: 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Started
+
+Speak and it will show you the recognition result in real-time.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-08 (Chinese)
+--------------------------------------------------------------------
+
+.. hint::
+
+ This is a very small model that can be run in real-time on embedded sytems.
+
+This model is trained using `WenetSpeech`_ dataset and it supports only Chinese.
+
+In the following, we describe how to download and use it with `sherpa-ncnn`_.
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-conv-emformer-transducer-2022-12-08.tar.bz2
+ tar xvf sherpa-ncnn-conv-emformer-transducer-2022-12-08.tar.bz2
+
+Decode a single wave file with ./build/bin/sherpa-ncnn
+::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/test_wavs/0.wav
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone with build/bin/sherpa-ncnn-microphone
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-08/joiner_jit_trace-pnnx.ncnn.bin
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn-microphone.exe`` for Windows.
+
+It will print something like below:
+
+.. code-block::
+
+ Number of threads: 4
+ num devices: 4
+ Use default device: 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Started
+
+Speak and it will show you the recognition result in real-time.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-04 (English)
+--------------------------------------------------------------------
+
+This model is trained using `GigaSpeech`_ and `LibriSpeech`_. It supports only English.
+
+In the following, we describe how to download and use it with `sherpa-ncnn`_.
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-conv-emformer-transducer-2022-12-04.tar.bz2
+ tar xvf sherpa-ncnn-conv-emformer-transducer-2022-12-04.tar.bz2
+
+Decode a single wave file with ./build/bin/sherpa-ncnn
+::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/test_wavs/1089-134686-0001.wav
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone with build/bin/sherpa-ncnn-microphone
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/tokens.txt \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-conv-emformer-transducer-2022-12-04/joiner_jit_trace-pnnx.ncnn.param
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn-microphone.exe`` for Windows.
+
+It will print something like below:
+
+.. code-block::
+
+ Number of threads: 4
+ num devices: 4
+ Use default device: 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Started
+
+Speak and it will show you the recognition result in real-time.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
diff --git a/docs/source/ncnn/pretrained_models/index.rst b/docs/source/ncnn/pretrained_models/index.rst
new file mode 100644
index 000000000..303d4a87b
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/index.rst
@@ -0,0 +1,20 @@
+.. _sherpa-ncnn-pre-trained-models:
+
+Pre-trained models
+==================
+
+In this section, we describe how to download and use all
+available pre-trained models.
+
+.. hint::
+
+ Please install `git-lfs `_ before you continue.
+
+
+.. toctree::
+ :maxdepth: 3
+
+ small-models.rst
+ zipformer-transucer-models.rst
+ lstm-transducer-models
+ conv-emformer-transducer-models
diff --git a/docs/source/ncnn/pretrained_models/lstm-transducer-models.rst b/docs/source/ncnn/pretrained_models/lstm-transducer-models.rst
new file mode 100644
index 000000000..fa2ee6fd0
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/lstm-transducer-models.rst
@@ -0,0 +1,279 @@
+LSTM-transducer-based Models
+=============================
+
+.. hint::
+
+ Please refer to :ref:`install_sherpa_ncnn` to install `sherpa-ncnn`_
+ before you read this section.
+
+.. _marcoyang_sherpa_ncnn_lstm_transducer_small_2023_02_13_bilingual:
+
+marcoyang/sherpa-ncnn-lstm-transducer-small-2023-02-13 (Bilingual, Chinese + English)
+--------------------------------------------------------------------------------------
+
+This model is a small version of `lstm-transducer `_
+trained in `icefall`_.
+
+It only has ``13.3 million parameters`` and can be deployed on ``embedded devices``
+for real-time speech recognition. You can find the models in ``fp16`` format
+at ``_.
+
+The model is trained on a bi-lingual dataset ``tal_csasr`` (Chinese + English), so it can be used
+for both Chinese and English.
+
+In the following, we show you how to download it and
+deploy it with `sherpa-ncnn`_.
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-lstm-transducer-small-2023-02-13.tar.bz2
+ tar xvf sherpa-ncnn-lstm-transducer-small-2023-02-13.tar.bz2
+
+.. note::
+
+ Please refer to :ref:`sherpa-ncnn-embedded-linux-arm-install` for how to
+ compile `sherpa-ncnn`_ for a 32-bit ARM platform.
+
+Decode a single wave file with ./build/bin/sherpa-ncnn
+::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/tokens.txt \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-lstm-transducer-small-2023-02-13/test_wavs/0.wav
+
+.. note::
+
+ The default option uses 4 threads and ``greedy_search`` for decoding.
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+csukuangfj/sherpa-ncnn-2022-09-05 (English)
+-------------------------------------------
+
+This is a model trained using the `GigaSpeech`_ and the `LibriSpeech`_ dataset.
+
+Please see ``_ for how the model
+is trained.
+
+You can find the training code at
+
+``_
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-2022-09-05.tar.bz2
+ tar xvf sherpa-ncnn-2022-09-05.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-2022-09-05/tokens.txt \
+ ./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-05/test_wavs/1089-134686-0001.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-lstm/2022-09-05.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-2022-09-05/tokens.txt \
+ ./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-05/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn-microphone.exe`` for Windows.
+
+It will print something like below:
+
+.. code-block::
+
+ Number of threads: 4
+ num devices: 4
+ Use default device: 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Started
+
+Speak and it will show you the recognition result in real-time.
+
+You can find a demo below:
+
+.. youtube:: m6ynSxycpX0
+ :width: 120%
+
+csukuangfj/sherpa-ncnn-2022-09-30 (Chinese)
+-------------------------------------------
+
+This is a model trained using the `WenetSpeech`_ dataset.
+
+Please see ``_ for how the model
+is trained.
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-2022-09-30.tar.bz2
+ tar xvf sherpa-ncnn-2022-09-30.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-2022-09-30/tokens.txt \
+ ./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-30/test_wavs/0.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-lstm/2022-09-30.txt
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-2022-09-30/tokens.txt \
+ ./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-2022-09-30/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn-microphone.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+You can find a demo below:
+
+.. youtube:: bbQfoRT75oM
+ :width: 120%
diff --git a/docs/source/ncnn/pretrained_models/pic/2023-01-09-fp32-decoding.png b/docs/source/ncnn/pretrained_models/pic/2023-01-09-fp32-decoding.png
new file mode 100644
index 000000000..f9882b718
Binary files /dev/null and b/docs/source/ncnn/pretrained_models/pic/2023-01-09-fp32-decoding.png differ
diff --git a/docs/source/ncnn/pretrained_models/pic/2023-01-09-int8-decoding.png b/docs/source/ncnn/pretrained_models/pic/2023-01-09-int8-decoding.png
new file mode 100644
index 000000000..504a02463
Binary files /dev/null and b/docs/source/ncnn/pretrained_models/pic/2023-01-09-int8-decoding.png differ
diff --git a/docs/source/ncnn/pretrained_models/small-models.rst b/docs/source/ncnn/pretrained_models/small-models.rst
new file mode 100644
index 000000000..220bd2b8b
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/small-models.rst
@@ -0,0 +1,20 @@
+Small models
+============
+
+In this section, we list models with fewer parameters that are suitable for
+resource constrained embedded systems.
+
+.. hint::
+
+ If you are using Raspberry Pi 4, this section is not so helpful for you
+ since all models in `sherpa-ncnn`_ are able to run in real-time on it.
+
+ This page is especially useful for systems with less resource than
+ Raspberry Pi 4.
+
+
+- :ref:`marcoyang_sherpa_ncnn_streaming_zipformer_small_14M_2023_02_23_chinese`
+- :ref:`marcoyang_sherpa_ncnn_streaming_zipformer_small_20M_2023_02_17_english`
+- :ref:`marcoyang_sherpa_ncnn_conv_emformer_transducer_small_2023_01_09_english`
+- :ref:`sherpa_ncnn_streaming_zipformer_small_bilingual_zh_en_2023_02_16`
+- :ref:`marcoyang_sherpa_ncnn_lstm_transducer_small_2023_02_13_bilingual`
diff --git a/docs/source/ncnn/pretrained_models/zipformer-transucer-models.rst b/docs/source/ncnn/pretrained_models/zipformer-transucer-models.rst
new file mode 100644
index 000000000..1f0d7e6a1
--- /dev/null
+++ b/docs/source/ncnn/pretrained_models/zipformer-transucer-models.rst
@@ -0,0 +1,573 @@
+Zipformer-transducer-based Models
+=================================
+
+.. hint::
+
+ Please refer to :ref:`install_sherpa_ncnn` to install `sherpa-ncnn`_
+ before you read this section.
+
+.. _marcoyang_sherpa_ncnn_streaming_zipformer_small_14M_2023_02_23_chinese:
+
+marcoyang/sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23 (Chinese)
+---------------------------------------------------------------------
+
+This model is a streaming Zipformer model which has around 14 millon parameters. It is trained on the `WenetSpeech`_ corpus
+so it supports only Chinese.
+
+You can find the training code at ``_
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/test_wavs/0.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-zh-small-14M-2023-02-23.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
+
+.. _marcoyang_sherpa_ncnn_streaming_zipformer_small_20M_2023_02_17_english:
+
+marcoyang/sherpa-ncnn-streaming-zipformer-20M-2023-02-17 (English)
+------------------------------------------------------------------
+
+This model is a streaming Zipformer model converted from
+
+``_
+
+which has around 20 millon parameters. It is trained on the `LibriSpeech`_ corpus so it supports only English.
+The word-error-rates(%) on ``test-clean`` is 3.88.
+
+You can find the training code at ``_
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-20M-2023-02-17.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-20M-2023-02-17.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/test_wavs/0.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-small-20M-en-2023-02-19.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-20M-2023-02-17/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
+
+csukuangfj/sherpa-ncnn-streaming-zipformer-en-2023-02-13 (English)
+------------------------------------------------------------------
+
+This model is converted from
+
+``_
+
+which supports only English as it is trained on the `LibriSpeech`_ corpus.
+
+You can find the training code at
+
+``_
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-en-2023-02-13.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-en-2023-02-13.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/test_wavs/1221-135766-0002.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-en-2023-02-13-sherpa-ncnn.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
+
+.. _sherpa_ncnn_streaming_zipformer_bilingual_zh_en_2023_02_13:
+
+csukuangfj/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13 (Bilingual, Chinese + English)
+----------------------------------------------------------------------------------------------------
+
+This model is converted from
+
+``_
+
+which supports both Chinese and English. The model is contributed by the community
+and is trained on tens of thousands of some internal dataset.
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/test_wavs/1.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13-sherpa-ncnn.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+.. caution::
+
+ If you use Windows and get encoding issues, please run:
+
+ .. code-block:: bash
+
+ CHCP 65001
+
+ in your commandline.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
+
+
+.. _sherpa_ncnn_streaming_zipformer_small_bilingual_zh_en_2023_02_16:
+
+csukuangfj/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16 (Bilingual, Chinese + English)
+----------------------------------------------------------------------------------------------------------
+
+This model is converted from
+
+``_
+
+which supports both Chinese and English. The model is contributed by the community
+and is trained on tens of thousands of some internal dataset.
+
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+.. note::
+
+ Unlike :ref:`sherpa_ncnn_streaming_zipformer_bilingual_zh_en_2023_02_13`, this
+ model is much smaller.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.tar.bz2
+
+Decode a single wave file
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. hint::
+
+ It supports decoding only wave files with a single channel and the sampling rate
+ should be 16 kHz.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/joiner_jit_trace-pnnx.ncnn.bin \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
+
+A faster model of sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We provide a second version of the model that is exported with
+``--decode-chunk-len=96`` instead of ``32``.
+
+.. hint::
+
+ Please see the model export script at
+
+ ``_
+
+ if you are interested.
+
+
+.. note::
+
+ You can also find a third version with folder ``64``.
+
+The advantage of using this model is that it runs much faster, while the downside
+is that you will see some delay before you see the recognition result after you speak.
+
+To decode a file, please use:
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/96/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-small-bilingual-zh-en-2023-02-16/test_wavs/1.wav \
+ 2 \
+ $method
+ done
+
+.. _sherpa_ncnn_streaming_zipformer_fr_2023_04_14:
+
+shaojieli/sherpa-ncnn-streaming-zipformer-fr-2023-04-14
+-------------------------------------------------------
+
+This model is converted from
+
+``_
+
+which supports only French as it is trained on the `CommonVoice`_ corpus.
+In the following, we describe how to download it and use it with `sherpa-ncnn`_.
+
+Download the model
+~~~~~~~~~~~~~~~~~~
+
+
+Please use the following commands to download it.
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+
+ wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-fr-2023-04-14.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-fr-2023-04-14.tar.bz2
+
+To decode a file, please use:
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ for method in greedy_search modified_beam_search; do
+ ./build/bin/sherpa-ncnn \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav \
+ 2 \
+ $method
+ done
+
+You should see the following output:
+
+.. literalinclude:: ./code-zipformer/sherpa-ncnn-streaming-zipformer-fr-2023-04-14.txt
+
+.. note::
+
+ Please use ``./build/bin/Release/sherpa-ncnn.exe`` for Windows.
+
+Real-time speech recognition from a microphone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ cd /path/to/sherpa-ncnn
+ ./build/bin/sherpa-ncnn-microphone \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/tokens.txt \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/encoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/decoder_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.param \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/joiner_jit_trace-pnnx.ncnn.bin \
+ ./sherpa-ncnn-streaming-zipformer-fr-2023-04-14/test_wavs/common_voice_fr_19364697.wav \
+ 2 \
+ greedy_search
+
+.. hint::
+
+ If your system is Linux (including embedded Linux), you can also use
+ :ref:`sherpa-ncnn-alsa` to do real-time speech recognition with your
+ microphone if ``sherpa-ncnn-microphone`` does not work for you.
diff --git a/docs/source/ncnn/python/code/decode-file.py b/docs/source/ncnn/python/code/decode-file.py
new file mode 100755
index 000000000..62a8e565b
--- /dev/null
+++ b/docs/source/ncnn/python/code/decode-file.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+"""
+This file demonstrates how to use sherpa-ncnn Python API to recognize
+a single file.
+
+Please refer to
+https://k2-fsa.github.io/sherpa/ncnn/index.html
+to install sherpa-ncnn and to download the pre-trained models
+used in this file.
+"""
+
+import wave
+
+import numpy as np
+import sherpa_ncnn
+
+
+def main():
+ recognizer = sherpa_ncnn.Recognizer(
+ tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
+ encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param",
+ encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin",
+ decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
+ decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
+ joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param",
+ joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin",
+ num_threads=4,
+ )
+
+ filename = (
+ "./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/1.wav"
+ )
+ with wave.open(filename) as f:
+ assert f.getframerate() == recognizer.sample_rate, (
+ f.getframerate(),
+ recognizer.sample_rate,
+ )
+ assert f.getnchannels() == 1, f.getnchannels()
+ assert f.getsampwidth() == 2, f.getsampwidth() # it is in bytes
+ num_samples = f.getnframes()
+ samples = f.readframes(num_samples)
+ samples_int16 = np.frombuffer(samples, dtype=np.int16)
+ samples_float32 = samples_int16.astype(np.float32)
+
+ samples_float32 = samples_float32 / 32768
+
+ recognizer.accept_waveform(recognizer.sample_rate, samples_float32)
+
+ tail_paddings = np.zeros(
+ int(recognizer.sample_rate * 0.5), dtype=np.float32
+ )
+ recognizer.accept_waveform(recognizer.sample_rate, tail_paddings)
+
+ recognizer.input_finished()
+
+ print(recognizer.text)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/docs/source/ncnn/python/code/speech-recognition-from-microphone.py b/docs/source/ncnn/python/code/speech-recognition-from-microphone.py
new file mode 100755
index 000000000..922a06987
--- /dev/null
+++ b/docs/source/ncnn/python/code/speech-recognition-from-microphone.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+# Real-time speech recognition from a microphone with sherpa-ncnn Python API
+#
+# Please refer to
+# https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
+# to download pre-trained models
+
+import sys
+
+try:
+ import sounddevice as sd
+except ImportError as e:
+ print("Please install sounddevice first. You can use")
+ print()
+ print(" pip install sounddevice")
+ print()
+ print("to install it")
+ sys.exit(-1)
+
+import sherpa_ncnn
+
+
+def create_recognizer():
+ # Please replace the model files if needed.
+ # See https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
+ # for download links.
+ recognizer = sherpa_ncnn.Recognizer(
+ tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
+ encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.param",
+ encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.bin",
+ decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
+ decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
+ joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.param",
+ joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.bin",
+ num_threads=4,
+ )
+ return recognizer
+
+
+def main():
+ print("Started! Please speak")
+ recognizer = create_recognizer()
+ sample_rate = recognizer.sample_rate
+ samples_per_read = int(0.1 * sample_rate) # 0.1 second = 100 ms
+ last_result = ""
+ with sd.InputStream(
+ channels=1, dtype="float32", samplerate=sample_rate
+ ) as s:
+ while True:
+ samples, _ = s.read(samples_per_read) # a blocking read
+ samples = samples.reshape(-1)
+ recognizer.accept_waveform(sample_rate, samples)
+ result = recognizer.text
+ if last_result != result:
+ last_result = result
+ print(result)
+
+
+if __name__ == "__main__":
+ devices = sd.query_devices()
+ print(devices)
+ default_input_device_idx = sd.default.device[0]
+ print(f'Use default device: {devices[default_input_device_idx]["name"]}')
+
+ try:
+ main()
+ except KeyboardInterrupt:
+ print("\nCaught Ctrl + C. Exiting")
diff --git a/docs/source/ncnn/python/index.rst b/docs/source/ncnn/python/index.rst
new file mode 100644
index 000000000..95b75d357
--- /dev/null
+++ b/docs/source/ncnn/python/index.rst
@@ -0,0 +1,360 @@
+.. _sherpa-ncnn-python-api:
+
+Python API
+==========
+
+.. hint::
+
+ It is known to work for ``Python >= 3.6`` on Linux, macOS, and Windows.
+
+In this section, we describe
+
+ 1. How to install the Python package `sherpa-ncnn`_
+ 2. How to use `sherpa-ncnn`_ Python API for real-time speech recognition with
+ a microphone
+ 3. How to use `sherpa-ncnn`_ Python API to recognize a single file
+
+Installation
+------------
+
+You can use ``1`` of the ``4`` methods below to install the Python package `sherpa-ncnn`_:
+
+Method 1
+^^^^^^^^
+
+.. hint::
+
+ This method supports ``x86_64``, ``arm64`` (e.g., Mac M1, 64-bit Raspberry Pi),
+ and ``arm32`` (e.g., 32-bit Raspberry Pi).
+
+.. code-block:: bash
+
+ pip install sherpa-ncnn
+
+
+If you use ``Method 1``, it will install pre-compiled libraries.
+The ``disadvantage`` is that it may ``not be optimized`` for your platform,
+while the ``advantage`` is that you don't need to install ``cmake`` or a
+C++ compiler.
+
+For the following methods, you have to first install:
+
+- ``cmake``, which can be installed using ``pip install cmake``
+- A C++ compiler, e.g., GCC on Linux and macOS, Visual Studio on Windows
+
+Method 2
+^^^^^^^^
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ python3 setup.py install
+
+Method 3
+^^^^^^^^
+
+.. code-block:: bash
+
+ pip install git+https://github.com/k2-fsa/sherpa-ncnn
+
+
+Method 4 (For developers and embedded boards)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. tabs::
+
+ .. tab:: x86/x86_64
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+
+ cmake \
+ -D SHERPA_NCNN_ENABLE_PYTHON=ON \
+ -D SHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+ -D BUILD_SHARED_LIBS=ON \
+ ..
+
+ make -j6
+
+ export PYTHONPATH=$PWD/lib:$PWD/../sherpa-ncnn/python:$PYTHONPATH
+
+ .. tab:: 32-bit ARM
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+
+ cmake \
+ -D SHERPA_NCNN_ENABLE_PYTHON=ON \
+ -D SHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+ -D BUILD_SHARED_LIBS=ON \
+ -DCMAKE_C_FLAGS="-march=armv7-a -mfloat-abi=hard -mfpu=neon" \
+ -DCMAKE_CXX_FLAGS="-march=armv7-a -mfloat-abi=hard -mfpu=neon" \
+ ..
+
+ make -j6
+
+ export PYTHONPATH=$PWD/lib:$PWD/../sherpa-ncnn/python:$PYTHONPATH
+
+ .. tab:: 64-bit ARM
+
+ .. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+ mkdir build
+ cd build
+
+ cmake \
+ -D SHERPA_NCNN_ENABLE_PYTHON=ON \
+ -D SHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+ -D BUILD_SHARED_LIBS=ON \
+ -DCMAKE_C_FLAGS="-march=armv8-a" \
+ -DCMAKE_CXX_FLAGS="-march=armv8-a" \
+ ..
+
+ make -j6
+
+ export PYTHONPATH=$PWD/lib:$PWD/../sherpa-ncnn/python:$PYTHONPATH
+
+Let us check whether `sherpa-ncnn`_ was installed successfully:
+
+.. code-block:: bash
+
+ python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__file__)"
+ python3 -c "import _sherpa_ncnn; print(_sherpa_ncnn.__file__)"
+
+They should print the location of ``sherpa_ncnn`` and ``_sherpa_ncnn``.
+
+.. hint::
+
+ If you use ``Method 1``, ``Method 2``, and ``Method 3``, you can also use
+
+ .. code-block:: bash
+
+ python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__version__)"
+
+ It should print the version of `sherpa-ncnn`_, e.g., ``1.1``.
+
+
+Next, we describe how to use `sherpa-ncnn`_ Python API for speech recognition:
+
+ - (1) Real-time speech recognition with a microphone
+ - (2) Recognize a file
+
+Real-time recognition with a microphone
+---------------------------------------
+
+The following Python code shows how to use `sherpa-ncnn`_ Python API for
+real-time speech recognition with a microphone.
+
+.. hint::
+
+ We use `sounddevice `_
+ for recording. Please run ``pip install sounddevice`` before you run the
+ code below.
+
+.. note::
+
+ You can download the code from
+
+ ``_
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 9-67
+ :caption: Real-time speech recognition with a microphone using `sherpa-ncnn`_ Python API
+
+**Code explanation**:
+
+1. Import the required packages
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 11-21
+
+Two packages are imported:
+
+ - `sounddevice `_, for recording with a microphone
+ - `sherpa-ncnn`_, for real-time speech recognition
+
+2. Create the recognizer
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 24-38,40-43
+
+We use the model :ref:`sherpa-ncnn-mixed-english-chinese-conv-emformer-model`
+as an example, which is able to recognize both English and Chinese.
+You can replace it with other pre-trained models.
+
+Please refer to :ref:`sherpa-ncnn-pre-trained-models` for more models.
+
+.. hint::
+
+ The above example uses a ``float16`` encoder and joiner. You can also use
+ the following code to switch to ``8-bit`` (i.e., ``int8``) quantized encoder
+ and joiner.
+
+ .. code-block:: python
+
+ recognizer = sherpa_ncnn.Recognizer(
+ tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
+ encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.param",
+ encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.bin",
+ decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
+ decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
+ joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.param",
+ joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.bin",
+ num_threads=4,
+ )
+
+3. Start recording
+^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 44,47
+
+**Note that**:
+
+ - We set channel to 1 since the model supports only a single channel
+ - We use dtype ``float32`` so that the resulting audio samples are normalized
+ to the range ``[-1, 1]``.
+ - The sampling rate has to be ``recognizer.sample_rate``, which is 16 kHz for
+ all models at present.
+
+4. Read audio samples from the microphone
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 45,49-50
+
+**Note that**:
+
+ - It reads ``100 ms`` of audio samples at a time. You can choose a larger
+ value, e.g., ``200 ms``.
+ - No queue or callback is used. Instead, we use a blocking read here.
+ - The ``samples`` array is reshaped to a ``1-D`` array
+
+5. Invoke the recognizer with audio samples
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 51
+
+**Note that**:
+
+ - ``samples`` has to be a 1-D tensor and should be normalized to the range
+ ``[-1, 1]``.
+ - Upon accepting the audio samples, the recognizer starts the decoding
+ automatically. There is no separate call for decoding.
+
+6. Get the recognition result
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: ./code/speech-recognition-from-microphone.py
+ :language: python
+ :lines: 52-55
+
+We use ``recognizer.text`` to get the recognition result. To avoid
+unnecessary output, we compare whether there is new result in ``recognizer.text``
+and don't print to the console if there is nothing new recognized.
+
+That's it!
+
+Summary
+^^^^^^^
+
+In summary, you need to:
+
+ 1. Create the recognizer
+ 2. Start recording
+ 3. Read audio samples
+ 4. Call ``recognizer.accept_waveform(sample_rate, samples)``
+ 5. Call ``recognizer.text`` to get the recognition result
+
+The following is a YouTube video for demonstration.
+
+.. youtube:: 74SxVueROok
+ :width: 120%
+
+
+.. hint::
+
+ If you don't have access to YouTube, please see the following video from bilibili:
+
+ .. raw:: html
+
+
+
+
+.. note::
+
+ ``_ supports endpoint detection.
+
+ Please see the following video for its usage:
+
+ .. raw:: html
+
+
+
+
+Recognize a file
+----------------
+
+The following Python code shows how to use `sherpa-ncnn`_ Python API to
+recognize a wave file.
+
+.. caution::
+
+ The sampling rate of the wave file has to be 16 kHz. Also, it should
+ contain only a single channel and samples should be 16-bit (i.e., int16)
+ encoded.
+
+.. note::
+
+ You can download the code from
+
+ ``_
+
+.. literalinclude:: ./code/decode-file.py
+ :language: python
+ :lines: 13-61
+ :caption: Decode a file with `sherpa-ncnn`_ Python API
+
+We use the model :ref:`sherpa-ncnn-mixed-english-chinese-conv-emformer-model`
+as an example, which is able to recognize both English and Chinese.
+You can replace it with other pre-trained models.
+
+Please refer to :ref:`sherpa-ncnn-pre-trained-models` for more models.
+
+.. hint::
+
+ The above example uses a ``float16`` encoder and joiner. You can also use
+ the following code to switch to ``8-bit`` (i.e., ``int8``) quantized encoder
+ and joiner.
+
+ .. code-block:: python
+
+ recognizer = sherpa_ncnn.Recognizer(
+ tokens="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/tokens.txt",
+ encoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.param",
+ encoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/encoder_jit_trace-pnnx.ncnn.int8.bin",
+ decoder_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.param",
+ decoder_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/decoder_jit_trace-pnnx.ncnn.bin",
+ joiner_param="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.param",
+ joiner_bin="./sherpa-ncnn-conv-emformer-transducer-2022-12-06/joiner_jit_trace-pnnx.ncnn.int8.bin",
+ num_threads=4,
+ )
diff --git a/docs/source/ncnn/tutorials/cn.rst b/docs/source/ncnn/tutorials/cn.rst
new file mode 100644
index 000000000..3dcebc969
--- /dev/null
+++ b/docs/source/ncnn/tutorials/cn.rst
@@ -0,0 +1,65 @@
+中文资料 (Chinese tutorials)
+============================
+
+Sherpa-ncnn (Windows電腦抓取麥克風聲音即時轉錄文字)
+---------------------------------------------------
+
+详细地址为 ``_.
+
+注: 用的是繁体字.
+
+
+2024 Android整合SherpaNcnn实现离线语音识别(支持中文,手把手带你从编译动态库开始)
+-----------------------------------------------------------------------------------------------------
+
+详细地址为 ``_
+
+描述了如何在 Android 上使用 `sherpa-ncnn`_.
+
+
+2024 在Unity环境下,借助sherpa-ncnn框架,实现实时并准确的中英双语语音识别功能
+-----------------------------------------------------------------------------
+
+详细地址为 ``_
+
+使用 unity.
+
+2024-02-22【RV1126】移植sherpa实时语音识别和TTS文字转语音功能
+-------------------------------------------------------------
+
+详细地址为 ``_.
+
+介绍了如何交叉编译 `sherpa-ncnn`_ 并在正点原子的rv1126开发板上测试实时的本地语音识别。
+
+.. note::
+
+ 上述博客中,虽然标题有 TTS, 但是 `sherpa-ncnn`_ 目前只支持 ASR。请使用 `sherpa-onnx`_
+ 去运行 TTS。
+
+2023-12-31 离线语音识别 sherpa-ncnn 尝鲜体验
+--------------------------------------------
+
+详细地址为 ``_.
+
+介绍了如何在 Ubuntu (x64) 以及树莓派4B 上安装和使用。
+
+.. note::
+
+ 上述博客中,树莓派4B 安装了32位的操作系统。我们建议安装 64 位的操作系统。
+
+
+2023-04-26【RV1126】移植kaldi实时语音识别
+-----------------------------------------
+
+详细地址为 ``_.
+
+描述了如何交叉编译 `sherpa-ncnn`_ 以及如何在 RV1126 开发板上部署。
+
+写的非常详细!
+
+2023-02-19 离线语音识别库sherpa-ncnn安装和简单测试笔记
+------------------------------------------------------------
+
+详细地址为 ``_.
+
+使用了树莓派3B+ 和 Windows 进行测试。
diff --git a/docs/source/ncnn/tutorials/index.rst b/docs/source/ncnn/tutorials/index.rst
new file mode 100644
index 000000000..68a4b8278
--- /dev/null
+++ b/docs/source/ncnn/tutorials/index.rst
@@ -0,0 +1,14 @@
+Tutorials
+=========
+
+This page contains links to tutorials written by our users.
+
+.. caution::
+
+ The tutorials are not necessarily written in English.
+
+
+.. toctree::
+ :maxdepth: 2
+
+ ./cn.rst
diff --git a/docs/source/ncnn/wasm/build.rst b/docs/source/ncnn/wasm/build.rst
new file mode 100644
index 000000000..75539873a
--- /dev/null
+++ b/docs/source/ncnn/wasm/build.rst
@@ -0,0 +1,86 @@
+Build
+=====
+
+After installing `emscripten`_, we can build `sherpa-ncnn`_ for `WebAssembly`_ now.
+
+Please use the following command to build it:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-ncnn
+ cd sherpa-ncnn
+
+ cd wasm/assets
+ wget -q https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
+ tar xvf sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
+ mv -v sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/*pnnx.ncnn.param .
+ mv -v sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/*pnnx.ncnn.bin .
+ mv -v sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt .
+ rm -rf sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13
+ rm -v sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
+ cd ../..
+
+ ./build-wasm-simd.sh
+
+.. hint::
+
+ You can visit ``_
+ to download a different model.
+
+After building, you should see the following output:
+
+.. code-block:: bash
+
+ Install the project...
+ -- Install configuration: "Release"
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/lib/libkaldi-native-fbank-core.a
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/lib/libncnn.a
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/./sherpa-ncnn.pc
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/lib/libsherpa-ncnn-core.a
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/lib/libsherpa-ncnn-c-api.a
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/include/sherpa-ncnn/c-api/c-api.h
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/sherpa-ncnn-wasm-main.js
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/sherpa-ncnn.js
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/app.js
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/index.html
+ -- Up-to-date: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/sherpa-ncnn-wasm-main.js
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/sherpa-ncnn-wasm-main.wasm
+ -- Installing: /Users/fangjun/open-source/sherpa-ncnn/build-wasm-simd/install/bin/wasm/sherpa-ncnn-wasm-main.data
+ + ls -lh install/bin/wasm
+ total 280152
+ -rw-r--r-- 1 fangjun staff 9.0K Feb 6 15:42 app.js
+ -rw-r--r-- 1 fangjun staff 936B Feb 6 15:42 index.html
+ -rw-r--r-- 1 fangjun staff 135M Feb 6 17:06 sherpa-ncnn-wasm-main.data
+ -rw-r--r-- 1 fangjun staff 79K Feb 6 17:06 sherpa-ncnn-wasm-main.js
+ -rw-r--r-- 1 fangjun staff 1.7M Feb 6 17:06 sherpa-ncnn-wasm-main.wasm
+ -rw-r--r-- 1 fangjun staff 6.9K Feb 6 15:42 sherpa-ncnn.js
+
+Now you can use the following command to run it:
+
+.. code-block:: bash
+
+ cd build-wasm-simd/install/bin/wasm/
+ python3 -m http.server 6006
+
+Start your browser and visit ``_; you should see the following
+page:
+
+.. figure:: ./pic/wasm-sherpa-ncnn-1.png
+ :alt: start page of wasm
+ :width: 800
+
+Now click start and speak! You should see the recognition results in the text box.
+
+.. warning::
+
+ We are using a bilingual model (Chinese + English) in the above example, which means
+ you can only speak Chinese or English in this case.
+
+A screenshot is given below:
+
+.. figure:: ./pic/wasm-sherpa-ncnn-2.png
+ :alt: recognition result
+ :width: 800
+
+Congratulations! You have successfully run real-time speech recognition with `WebAssembly`_
+in your browser.
diff --git a/docs/source/ncnn/wasm/hf-spaces.rst b/docs/source/ncnn/wasm/hf-spaces.rst
new file mode 100644
index 000000000..7525232e1
--- /dev/null
+++ b/docs/source/ncnn/wasm/hf-spaces.rst
@@ -0,0 +1,49 @@
+.. _try sherpa ncnn wasm with huggingface:
+
+Huggingface Spaces (WebAssembly)
+================================
+
+We provide two `Huggingface`_ spaces so that you can try real-time
+speech recognition with `WebAssembly`_ in your browser.
+
+English only
+------------
+
+``_
+
+.. hint::
+
+ If you don't have access to `Huggingface`_, please visit the following mirror:
+
+ ``_
+
+.. figure:: ./pic/wasm-hf-en.png
+ :alt: start page of wasm
+ :width: 800
+ :target: https://huggingface.co/spaces/k2-fsa/web-assembly-asr-sherpa-ncnn-en
+
+.. note::
+
+ The script for building this space can be found at
+ ``_
+
+Chinese + English
+-----------------
+
+``_
+
+.. hint::
+
+ If you don't have access to `Huggingface`_, please visit the following mirror:
+
+ ``_
+
+.. figure:: ./pic/wasm-hf-zh-en.png
+ :alt: start page of wasm
+ :width: 800
+ :target: https://huggingface.co/spaces/k2-fsa/web-assembly-asr-sherpa-ncnn-zh-en
+
+.. note::
+
+ The script for building this space can be found at
+ ``_
diff --git a/docs/source/ncnn/wasm/index.rst b/docs/source/ncnn/wasm/index.rst
new file mode 100644
index 000000000..532d78e35
--- /dev/null
+++ b/docs/source/ncnn/wasm/index.rst
@@ -0,0 +1,15 @@
+WebAssembly
+===========
+
+In this section, we describe how to build `sherpa-ncnn`_ for `WebAssembly`_
+so that you can run real-time speech recognition with `WebAssembly`_.
+
+Please follow the steps below to build and run `sherpa-ncnn`_ for `WebAssembly`_.
+
+.. toctree::
+ :maxdepth: 3
+
+ ./install-emscripten.rst
+ ./build.rst
+ ./prebuilt.rst
+ ./hf-spaces.rst
diff --git a/docs/source/ncnn/wasm/install-emscripten.rst b/docs/source/ncnn/wasm/install-emscripten.rst
new file mode 100644
index 000000000..3fdbc0b4f
--- /dev/null
+++ b/docs/source/ncnn/wasm/install-emscripten.rst
@@ -0,0 +1,40 @@
+Install Emscripten
+==================
+
+We need to compile the C/C++ files in `sherpa-ncnn`_ with the help of
+`emscripten`_.
+
+Please refer to ``_
+for detailed installation instructions.
+
+The following is an example to show you how to install it on Linux/macOS.
+
+.. code-block:: bash
+
+ git clone https://github.com/emscripten-core/emsdk.git
+ cd emsdk
+ git pull
+ ./emsdk install latest
+ ./emsdk activate latest
+ source ./emsdk_env.sh
+
+To check that you have installed `emscripten`_ successfully, please run:
+
+.. code-block:: bash
+
+ emcc -v
+
+The above command should print something like below:
+
+.. code-block::
+
+ emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.48 (e967e20b4727956a30592165a3c1cde5c67fa0a8)
+ shared:INFO: (Emscripten: Running sanity checks)
+ (py38) fangjuns-MacBook-Pro:open-source fangjun$ emcc -v
+ emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.48 (e967e20b4727956a30592165a3c1cde5c67fa0a8)
+ clang version 18.0.0 (https://github.com/llvm/llvm-project a54545ba6514802178cf7cf1c1dd9f7efbf3cde7)
+ Target: wasm32-unknown-emscripten
+ Thread model: posix
+ InstalledDir: /Users/fangjun/open-source/emsdk/upstream/bin
+
+Congratulations! You have successfully installed `emscripten`_.
diff --git a/docs/source/ncnn/wasm/pic/wasm-hf-en.png b/docs/source/ncnn/wasm/pic/wasm-hf-en.png
new file mode 100644
index 000000000..725281fc6
Binary files /dev/null and b/docs/source/ncnn/wasm/pic/wasm-hf-en.png differ
diff --git a/docs/source/ncnn/wasm/pic/wasm-hf-zh-en.png b/docs/source/ncnn/wasm/pic/wasm-hf-zh-en.png
new file mode 100644
index 000000000..e0ce14bb9
Binary files /dev/null and b/docs/source/ncnn/wasm/pic/wasm-hf-zh-en.png differ
diff --git a/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-1.png b/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-1.png
new file mode 100644
index 000000000..66450817a
Binary files /dev/null and b/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-1.png differ
diff --git a/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-2.png b/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-2.png
new file mode 100644
index 000000000..6bd4f644b
Binary files /dev/null and b/docs/source/ncnn/wasm/pic/wasm-sherpa-ncnn-2.png differ
diff --git a/docs/source/ncnn/wasm/prebuilt.rst b/docs/source/ncnn/wasm/prebuilt.rst
new file mode 100644
index 000000000..fea8954d6
--- /dev/null
+++ b/docs/source/ncnn/wasm/prebuilt.rst
@@ -0,0 +1,54 @@
+Use pre-built WebAssembly library
+=================================
+
+In this section, we describe how to use the pre-built `WebAssembly`_ library
+of `sherpa-ncnn`_ for real-time speech recognition.
+
+.. note::
+
+ Note that the pre-built library used in this section
+ uses a bilingual model (Chinese + English),
+ which is from :ref:`sherpa_ncnn_streaming_zipformer_bilingual_zh_en_2023_02_13`.
+
+Download
+--------
+
+Please use the following command to download the pre-built library for version
+``v2.1.7``, which is the latest release as of 2024.02.06.
+
+.. hint::
+
+ Please always use the latest release. You can visit
+ ``_ to find the latest release.
+
+.. code-block::
+
+ wget -q https://github.com/k2-fsa/sherpa-ncnn/releases/download/v2.1.7/sherpa-ncnn-wasm-simd-v2.1.7.tar.bz2
+ tar xvf sherpa-ncnn-wasm-simd-v2.1.7.tar.bz2
+ rm sherpa-ncnn-wasm-simd-v2.1.7.tar.bz2
+ cd sherpa-ncnn-wasm-simd-v2.1.7
+
+ python3 -m http.server 6006
+
+Start your browser and visit ``_; you should see the following
+page:
+
+.. figure:: ./pic/wasm-sherpa-ncnn-1.png
+ :alt: start page of wasm
+ :width: 800
+
+Now click start and speak! You should see the recognition results in the text box.
+
+.. warning::
+
+ We are using a bilingual model (Chinese + English) in the above example, which means
+ you can only speak Chinese or English in this case.
+
+A screenshot is given below:
+
+.. figure:: ./pic/wasm-sherpa-ncnn-2.png
+ :alt: recognition result
+ :width: 800
+
+Congratulations! You have successfully run real-time speech recognition with `WebAssembly`_
+in your browser.
diff --git a/docs/source/onnx/FireRedAsr/code/2025-02-16.txt b/docs/source/onnx/FireRedAsr/code/2025-02-16.txt
new file mode 100644
index 000000000..6df9e7044
--- /dev/null
+++ b/docs/source/onnx/FireRedAsr/code/2025-02-16.txt
@@ -0,0 +1,14 @@
+/star-fj/fangjun/open-source/sherpa-onnx/sherpa-onnx/csrc/parse-options.cc:Read:375 ./build/bin/sherpa-onnx-offline --tokens=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/tokens.txt --fire-red-asr-encoder=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/encoder.int8.onnx --fire-red-asr-decoder=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/decoder.int8.onnx --num-threads=1 ./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/test_wavs/0.wav
+
+OfflineRecognizerConfig(feat_config=FeatureExtractorConfig(sampling_rate=16000, feature_dim=80, low_freq=20, high_freq=-400, dither=0), model_config=OfflineModelConfig(transducer=OfflineTransducerModelConfig(encoder_filename="", decoder_filename="", joiner_filename=""), paraformer=OfflineParaformerModelConfig(model=""), nemo_ctc=OfflineNemoEncDecCtcModelConfig(model=""), whisper=OfflineWhisperModelConfig(encoder="", decoder="", language="", task="transcribe", tail_paddings=-1), fire_red_asr=OfflineFireRedAsrModelConfig(encoder="./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/encoder.int8.onnx", decoder="./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/decoder.int8.onnx"), tdnn=OfflineTdnnModelConfig(model=""), zipformer_ctc=OfflineZipformerCtcModelConfig(model=""), wenet_ctc=OfflineWenetCtcModelConfig(model=""), sense_voice=OfflineSenseVoiceModelConfig(model="", language="auto", use_itn=False), moonshine=OfflineMoonshineModelConfig(preprocessor="", encoder="", uncached_decoder="", cached_decoder=""), telespeech_ctc="", tokens="./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/tokens.txt", num_threads=1, debug=False, provider="cpu", model_type="", modeling_unit="cjkchar", bpe_vocab=""), lm_config=OfflineLMConfig(model="", scale=0.5), ctc_fst_decoder_config=OfflineCtcFstDecoderConfig(graph="", max_active=3000), decoding_method="greedy_search", max_active_paths=4, hotwords_file="", hotwords_score=1.5, blank_penalty=0, rule_fsts="", rule_fars="")
+Creating recognizer ...
+Started
+Done!
+
+./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/test_wavs/0.wav
+{"lang": "", "emotion": "", "event": "", "text": "昨天是 MONDAY TODAY IS礼拜二 THE DAY AFTER TOMORROW是星期三", "timestamps": [], "tokens":["昨", "天", "是", " MO", "ND", "AY", " TO", "D", "AY", " IS", "礼", "拜", "二", " THE", " DAY", " AFTER", " TO", "M", "OR", "ROW", "是", "星", "期", "三"], "words": []}
+----
+num threads: 1
+decoding method: greedy_search
+Elapsed seconds: 19.555 s
+Real time factor (RTF): 19.555 / 10.053 = 1.945
diff --git a/docs/source/onnx/FireRedAsr/huggingface-space.rst b/docs/source/onnx/FireRedAsr/huggingface-space.rst
new file mode 100644
index 000000000..f3a12b3d9
--- /dev/null
+++ b/docs/source/onnx/FireRedAsr/huggingface-space.rst
@@ -0,0 +1,20 @@
+Huggingface space
+=================
+
+You can try `FireRedAsr`_ with `sherpa-onnx`_ with the following huggingface space
+
+ ``_
+
+
+.. hint::
+
+ You don't need to install anything. All you need is a browser.
+
+ You can even run it on your phone or tablet.
+
+.. figure:: ./pic/fire-red-asr-hf-space.jpg
+ :alt: screenshot of hf space for FireRedAsr
+ :align: center
+ :width: 600
+
+ Try `FireRedAsr`_ in our Huggingface space with `sherpa-onnx`_
diff --git a/docs/source/onnx/FireRedAsr/index.rst b/docs/source/onnx/FireRedAsr/index.rst
new file mode 100644
index 000000000..4146f66ee
--- /dev/null
+++ b/docs/source/onnx/FireRedAsr/index.rst
@@ -0,0 +1,41 @@
+FireRedAsr
+==========
+
+This section describes how to use models from ``_.
+
+Note that this model supports Chinese and English.
+
+.. hint::
+
+ 该模型支持普通话、及一些方言(四川话、河南话、天津话等).
+
+We have converted `FireRedASR`_ to onnx and provided APIs for the following programming languages
+
+ - 1. C++
+ - 2. C
+ - 3. Python
+ - 4. C#
+ - 5. Go
+ - 6. Kotlin
+ - 7. Java
+ - 8. JavaScript (Support `WebAssembly`_ and `Node`_)
+ - 9. Swift
+ - 10. `Dart`_ (Support `Flutter`_)
+ - 11. Object Pascal
+
+Note that you can use `FireRedASR`_ with `sherpa-onnx`_ on the following platforms:
+
+ - Linux (x64, aarch64, arm, riscv64)
+ - macOS (x64, arm64)
+ - Windows (x64, x86, arm64)
+ - Android (arm64-v8a, armv7-eabi, x86, x86_64)
+ - iOS (arm64)
+
+In the following, we describe how to download pre-trained `FireRedASR`_ models
+and use them in `sherpa-onnx`_.
+
+.. toctree::
+ :maxdepth: 5
+
+ ./huggingface-space.rst
+ ./pretrained.rst
diff --git a/docs/source/onnx/FireRedAsr/pic/fire-red-asr-hf-space.jpg b/docs/source/onnx/FireRedAsr/pic/fire-red-asr-hf-space.jpg
new file mode 100644
index 000000000..bee78e2fc
Binary files /dev/null and b/docs/source/onnx/FireRedAsr/pic/fire-red-asr-hf-space.jpg differ
diff --git a/docs/source/onnx/FireRedAsr/pretrained.rst b/docs/source/onnx/FireRedAsr/pretrained.rst
new file mode 100644
index 000000000..6e250d32b
--- /dev/null
+++ b/docs/source/onnx/FireRedAsr/pretrained.rst
@@ -0,0 +1,66 @@
+Pre-trained Models
+==================
+
+This page describes how to download pre-trained `FireRedAsr`_ models.
+
+sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16 (Chinese + English, 普通话、四川话、河南话等)
+------------------------------------------------------------------------------------------------
+
+This model is converted from ``_
+
+It supports the following 2 languages:
+
+ - Chinese (普通话, 四川话、天津话、河南话等方言)
+ - English
+
+In the following, we describe how to download it.
+
+Download
+^^^^^^^^
+
+Please use the following commands to download it::
+
+ cd /path/to/sherpa-onnx
+
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16.tar.bz2
+ tar xvf sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16.tar.bz2
+ rm sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16.tar.bz2
+
+After downloading, you should find the following files::
+
+ ls -lh sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/
+ total 1.7G
+ -rw-r--r-- 1 kuangfangjun root 188 Feb 16 16:22 README.md
+ -rw-r--r-- 1 kuangfangjun root 425M Feb 16 16:21 decoder.int8.onnx
+ -rw-r--r-- 1 kuangfangjun root 1.3G Feb 16 16:21 encoder.int8.onnx
+ drwxr-xr-x 10 kuangfangjun root 0 Feb 16 16:26 test_wavs
+ -rw-r--r-- 1 kuangfangjun root 70K Feb 16 16:21 tokens.txt
+
+ ls -lh sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/test_wavs/
+ total 1.9M
+ -rw-r--r-- 1 kuangfangjun root 315K Feb 16 16:24 0.wav
+ -rw-r--r-- 1 kuangfangjun root 160K Feb 16 16:24 1.wav
+ -rw-r--r-- 1 kuangfangjun root 147K Feb 16 16:24 2.wav
+ -rw-r--r-- 1 kuangfangjun root 245K Feb 16 16:25 3-sichuan.wav
+ -rw-r--r-- 1 kuangfangjun root 276K Feb 16 16:24 3.wav
+ -rw-r--r-- 1 kuangfangjun root 245K Feb 16 16:25 4-tianjin.wav
+ -rw-r--r-- 1 kuangfangjun root 250K Feb 16 16:26 5-henan.wav
+ -rw-r--r-- 1 kuangfangjun root 276K Feb 16 16:24 8k.wav
+
+Decode a file
+^^^^^^^^^^^^^
+
+Please use the following command to decode a wave file:
+
+.. code-block:: bash
+
+ ./build/bin/sherpa-onnx-offline \
+ --tokens=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/tokens.txt \
+ --fire-red-asr-encoder=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/encoder.int8.onnx \
+ --fire-red-asr-decoder=./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/decoder.int8.onnx \
+ --num-threads=1 \
+ ./sherpa-onnx-fire-red-asr-large-zh_en-2025-02-16/test_wavs/0.wav
+
+You should see the following output:
+
+.. literalinclude:: ./code/2025-02-16.txt
diff --git a/docs/source/onnx/android/build-sherpa-onnx.rst b/docs/source/onnx/android/build-sherpa-onnx.rst
new file mode 100644
index 000000000..c4caea3fa
--- /dev/null
+++ b/docs/source/onnx/android/build-sherpa-onnx.rst
@@ -0,0 +1,442 @@
+.. _sherpa-onnx-install-android-studio:
+
+Build sherpa-onnx for Android
+=============================
+
+You can use this section for both ``speech-to-text`` (STT, ASR)
+and ``text-to-speech`` (TTS).
+
+.. hint::
+
+ The build scripts mentioned in this section run on both Linux and macOS.
+
+ If you are using Windows or if you don't want to build the shared libraries,
+ you can download pre-built shared libraries by visiting the release page
+ ``_
+
+ For instance, for the relase ``v1.10.19``, you can visit
+ ``_
+ and download the file ``sherpa-onnx-v1.10.19-android.tar.bz2``
+ using the following command:
+
+ .. code-block:: bash
+
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/v1.10.19/sherpa-onnx-v1.10.19-android.tar.bz2
+
+ Please always use the latest release.
+
+.. hint::
+
+ This section is originally written for speech-to-text. However, it is
+ also applicable to other folders in ``_.
+
+ For instance, you can replace ``SherpaOnnx`` in this section with
+
+ - ``SherpaOnnx2Pass``
+ - ``SherpaOnnxTts`` (this is for text-to-speech)
+ - ``SherpaOnnxTtsEngine`` (this is for text-to-speech)
+ - ``SherpaOnnxVad``
+ - ``SherpaOnnxVadAsr``
+ - ``SherpaOnnxSpeakerIdentification``
+ - ``SherpaOnnxSpeakerDiarization``
+ - ``SherpaOnnxAudioTagging``
+ - ``SherpaOnnxAudioTaggingWearOs``
+
+
+Install Android Studio
+----------------------
+
+The first step is to download and install Android Studio.
+
+Please refer to ``_ for how to install
+Android Studio.
+
+.. hint::
+
+ Any recent version of Android Studio should work fine. Also, you can use
+ the default settings of Android Studio during installation.
+
+ For reference, we post the version we are using below:
+
+ .. image:: ./pic/android-studio-version.png
+ :align: center
+ :alt: screenshot of my version of Android Studio
+ :width: 600
+
+
+Download sherpa-onnx
+--------------------
+
+Next, download the source code of `sherpa-onnx`_:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+
+Install NDK
+-----------
+
+Step 1, start Android Studio.
+
+ .. figure:: ./pic/start-android-studio.png
+ :alt: Start Android Studio
+ :width: 600
+
+ Step 1: Click ``Open`` to select ``sherpa-onnx/android/SherpaOnnx``
+
+Step 2, Open ``sherpa-onnx/android/SherpaOnnx``.
+
+ .. figure:: ./pic/open-sherpa-onnx.png
+ :alt: Open SherpaOnnx
+ :width: 600
+
+ Step 2: Open ``SherpaOnnx``.
+
+
+Step 3, Select ``Tools -> SDK Manager``.
+
+ .. figure:: ./pic/select-sdk-manager.png
+ :alt: Select Tools -> SDK Manager
+ :width: 600
+
+ Step 3: Select ``Tools -> SDK Manager``.
+
+Step 4, ``Install NDK``.
+
+ .. figure:: ./pic/ndk-tools.png
+ :alt: Install NDK
+ :width: 600
+
+ Step 4: Install NDK.
+
+In the following, we assume ``Android SDK location`` was set to
+``/Users/fangjun/software/my-android``. You can change it accordingly below.
+
+After installing NDK, you can find it in
+
+.. code-block::
+
+ /Users/fangjun/software/my-android/ndk/22.1.7171670
+
+.. warning::
+
+ If you selected a different version of NDK, please replace ``22.1.7171670``
+ accordingly.
+
+Next, let us set the environment variable ``ANDROID_NDK`` for later use.
+
+.. code-block:: bash
+
+ export ANDROID_NDK=/Users/fangjun/software/my-android/ndk/22.1.7171670
+
+.. note::
+
+ Note from https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-android
+
+ (Important) remove the hardcoded debug flag in Android NDK to fix
+ the android-ndk issue: https://github.com/android/ndk/issues/243
+
+ 1. open ``$ANDROID_NDK/build/cmake/android.toolchain.cmake`` for ndk < r23
+ or ``$ANDROID_NDK/build/cmake/android-legacy.toolchain.cmake`` for ndk >= r23
+
+ 2. delete the line containing "-g"
+
+ .. code-block::
+
+ list(APPEND ANDROID_COMPILER_FLAGS
+ -g
+ -DANDROID
+
+Build sherpa-onnx (C++ code)
+----------------------------
+
+After installing ``NDK``, it is time to build the C++ code of `sherpa-onnx`_.
+
+In the following, we show how to build `sherpa-onnx`_ for the following
+Android ABIs:
+
+ - ``arm64-v8a``
+ - ``armv7-eabi``
+ - ``x86_64``
+ - ``x86``
+
+.. caution::
+
+ You only need to select one and only one ABI. ``arm64-v8a`` is probably the
+ most common one.
+
+ If you want to test the app on an emulator, you probably need ``x86_64``.
+
+.. hint::
+
+ Building scripts for this section are for macOS and Linux. If you are
+ using Windows or if you don't want to build the shared libraries by yourself,
+ you can download pre-compiled shared libraries for this section by visiting
+
+ ``_
+
+.. hint::
+
+ We provide a colab notebook
+ |build sherpa-onnx for android colab notebook|
+ for you to try this section step by step.
+
+ If you are using Windows or you don't want to setup your local environment
+ to build the C++ libraries, please use the above colab notebook.
+
+.. |build sherpa-onnx for android colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-onnx/build_sherpa_onnx_for_android.ipynb
+
+Build for arm64-v8a
+^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-onnx # Go to the root repo
+ ./build-android-arm64-v8a.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ ls -lh build-android-arm64-v8a/install/lib/
+
+ -rw-r--r-- 1 fangjun staff 15M Jul 28 12:54 libonnxruntime.so
+ -rwxr-xr-x 1 fangjun staff 3.7M Jul 28 12:54 libsherpa-onnx-jni.so
+
+Please copy them to ``android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/``:
+
+.. code-block:: bash
+
+ cp build-android-arm64-v8a/install/lib/lib*.so android/SherpaOnnx/app/src/main/jniLibs/arm64-v8a/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-arm64-v8a.jpg
+ :align: center
+ :alt: Generated shared libraries for arm64-v8a
+ :width: 600
+
+Build for armv7-eabi
+^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-onnx # Go to the root repo
+ ./build-android-armv7-eabi.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ ls -lh build-android-armv7-eabi/install/lib
+
+ -rw-r--r-- 1 fangjun staff 10M Jul 28 13:18 libonnxruntime.so
+ -rwxr-xr-x 1 fangjun staff 2.1M Jul 28 13:18 libsherpa-onnx-jni.so
+
+Please copy them to ``android/SherpaOnnx/app/src/main/jniLibs/armeabi-v7a``:
+
+.. code-block:: bash
+
+ cp build-android-armv7-eabi/install/lib/lib*.so android/SherpaOnnx/app/src/main/jniLibs/armeabi-v7a/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-armv7a-eabi.jpg
+ :align: center
+ :alt: Generated shared libraries for armv7-eabi
+ :width: 600
+
+Build for x86_64
+^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-onnx # Go to the root repo
+ ./build-android-x86-64.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ ls -lh build-android-x86-64/install/lib/
+
+ -rw-r--r-- 1 fangjun staff 17M Jul 28 13:26 libonnxruntime.so
+ -rwxr-xr-x 1 fangjun staff 4.0M Jul 28 13:26 libsherpa-onnx-jni.so
+
+Please copy them to ``android/SherpaOnnx/app/src/main/jniLibs/x86_64/``:
+
+.. code-block:: bash
+
+ cp build-android-x86-64/install/lib/lib*.so android/SherpaOnnx/app/src/main/jniLibs/x86_64/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-x86-64.jpg
+ :align: center
+ :alt: Generated shared libraries for x86_64
+ :width: 600
+
+Build for x86
+^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ cd sherpa-onnx # Go to the root repo
+ ./build-android-x86.sh
+
+After building, you will find the following shared libraries:
+
+.. code-block:: bash
+
+ ls -lh build-android-x86/install/lib/
+
+ -rw-r--r-- 1 fangjun staff 17M Jul 28 13:28 libonnxruntime.so
+ -rwxr-xr-x 1 fangjun staff 3.9M Jul 28 13:28 libsherpa-onnx-jni.so
+
+Please copy them to ``android/SherpaOnnx/app/src/main/jniLibs/x86/``:
+
+.. code-block:: bash
+
+ cp build-android-x86/install/lib/lib*.so android/SherpaOnnx/app/src/main/jniLibs/x86/
+
+You should see the following screen shot after running the above copy ``cp`` command.
+
+.. figure:: ./pic/so-libs-for-x86.jpg
+ :align: center
+ :alt: Generated shared libraries for x86
+ :width: 600
+
+Download pre-trained models
+---------------------------
+
+Please read :ref:`sherpa-onnx-pre-trained-models` for all available pre-trained
+models.
+
+In the following, we use a pre-trained model :ref:`sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20`,
+which supports both Chinese and English.
+
+.. hint::
+
+ The model is trained using `icefall`_ and the original torchscript model
+ is from ``_.
+
+Use the following command to download the pre-trained model and place it into
+``android/SherpaOnnx/app/src/main/assets/``:
+
+.. code-block:: bash
+
+ cd android/SherpaOnnx/app/src/main/assets/
+
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
+
+ tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
+ rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
+
+ cd sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
+
+ # Now, remove extra files to reduce the file size of the generated apk
+ rm -rf test_wavs
+ rm -f *.sh README.md
+ rm -f bpe.model
+
+ rm -f encoder-epoch-99-avg-1.int8.onnx
+ rm -f joiner-epoch-99-avg-1.int8.onnx
+ rm -f decoder-epoch-99-avg-1.int8.onnx
+ rm -f bpe.vocab
+
+In the end, you should have the following files:
+
+.. code-block:: bash
+
+ ls -lh
+
+ -rw-r--r--@ 1 fangjun staff 13M Jul 28 13:51 decoder-epoch-99-avg-1.onnx
+ -rw-r--r--@ 1 fangjun staff 315M Jul 28 13:51 encoder-epoch-99-avg-1.onnx
+ -rw-r--r--@ 1 fangjun staff 12M Jul 28 13:51 joiner-epoch-99-avg-1.onnx
+ -rw-r--r--@ 1 fangjun staff 55K Nov 21 2023 tokens.txt
+
+You should see the following screen shot after downloading the pre-trained model:
+
+.. figure:: ./pic/pre-trained-model-2023-02-20.png
+ :alt: Files after downloading the pre-trained model
+ :align: center
+ :width: 600
+
+.. hint::
+
+ If you select a different pre-trained model, make sure that you also change the
+ corresponding code listed in the following screen shot:
+
+ .. figure:: ./pic/type-for-pre-trained-model-2023-02-20.png
+ :alt: Change code if you select a different model
+ :width: 600
+
+Generate APK
+------------
+
+Finally, it is time to build `sherpa-onnx`_ to generate an APK package.
+
+Select ``Build -> Make Project``, as shown in the following screen shot.
+
+.. figure:: ./pic/build-make-project.png
+ :align: center
+ :alt: Select ``Build -> Make Project``
+ :width: 600
+
+You can find the generated APK in ``android/SherpaOnnx/app/build/outputs/apk/debug/app-debug.apk``:
+
+.. code-block:: bash
+
+ ls -lh android/SherpaOnnx/app/build/outputs/apk/debug/app-debug.apk
+
+ -rw-r--r--@ 1 fangjun staff 329M Jul 28 13:56 android/SherpaOnnx/app/build/outputs/apk/debug/app-debug.apk
+
+Congratulations! You have successfully built an APK for Android.
+
+Read below to learn more.
+
+Analyze the APK
+---------------
+
+.. figure:: ./pic/analyze-apk.png
+ :align: center
+ :alt: Select ``Build -> Analyze APK ...``
+ :width: 600
+
+Select ``Build -> Analyze APK ...`` in the above screen shot, in the
+popped-up dialog select the generated APK ``app-debug.apk``,
+and you will see the following screen shot:
+
+.. figure:: ./pic/analyze-apk-result.jpg
+ :align: center
+ :alt: Result of analyzing apk
+ :width: 700
+
+You can see from the above screen shot that most part of the APK
+is occupied by the pre-trained model, while the runtime, including the shared
+libraries, is only ``7.2 MB``.
+
+.. caution::
+
+ You can see that ``libonnxruntime.so`` alone occupies ``5.8MB`` out of ``7.2MB``.
+
+ We use a so-called ``Full build`` instead of ``Mobile build``, so the file
+ size of the library is somewhat a bit larger.
+
+ ``libonnxruntime.so`` is donwloaded from
+
+ ``_
+
+ Please refer to ``_ for a
+ custom build to reduce the file size of ``libonnxruntime.so``.
+
+ Note that we are constantly updating the version of ``onnxruntime``. By
+ the time you are reading this section, we may be using the latest version
+ of ``onnxruntime``.
+
+.. hint::
+
+ We recommend you to use `sherpa-ncnn`_. Please see
+ :ref:`sherpa-ncnn-analyze-apk-result` for `sherpa-ncnn`_. The total runtime of
+ `sherpa-ncnn`_ is only ``1.6 MB``, which is much smaller than `sherpa-onnx`_.
diff --git a/docs/source/onnx/android/index.rst b/docs/source/onnx/android/index.rst
new file mode 100644
index 000000000..9cdd9b1ff
--- /dev/null
+++ b/docs/source/onnx/android/index.rst
@@ -0,0 +1,18 @@
+.. _sherpa-onnx-android:
+
+Android
+=======
+
+
+In this section, we describe how to build an Android app with `sherpa-onnx`_.
+
+.. hint::
+
+ For real-time speech recognition, it does not need to access the Internet.
+ Everyting is processed locally on your phone.
+
+.. toctree::
+ :maxdepth: 2
+
+ ./prebuilt-apk.rst
+ build-sherpa-onnx
diff --git a/docs/source/onnx/android/pic/analyze-apk-result.jpg b/docs/source/onnx/android/pic/analyze-apk-result.jpg
new file mode 100644
index 000000000..d3be13109
Binary files /dev/null and b/docs/source/onnx/android/pic/analyze-apk-result.jpg differ
diff --git a/docs/source/onnx/android/pic/analyze-apk.png b/docs/source/onnx/android/pic/analyze-apk.png
new file mode 100644
index 000000000..681ed52fd
Binary files /dev/null and b/docs/source/onnx/android/pic/analyze-apk.png differ
diff --git a/docs/source/onnx/android/pic/android-studio-version.png b/docs/source/onnx/android/pic/android-studio-version.png
new file mode 100644
index 000000000..e682e4754
Binary files /dev/null and b/docs/source/onnx/android/pic/android-studio-version.png differ
diff --git a/docs/source/onnx/android/pic/build-make-project.png b/docs/source/onnx/android/pic/build-make-project.png
new file mode 100644
index 000000000..4072e0f2b
Binary files /dev/null and b/docs/source/onnx/android/pic/build-make-project.png differ
diff --git a/docs/source/onnx/android/pic/ndk-tools.png b/docs/source/onnx/android/pic/ndk-tools.png
new file mode 120000
index 000000000..d6ac3961f
--- /dev/null
+++ b/docs/source/onnx/android/pic/ndk-tools.png
@@ -0,0 +1 @@
+../../../ncnn/android/pic/ndk-tools.png
\ No newline at end of file
diff --git a/docs/source/onnx/android/pic/open-sherpa-onnx.png b/docs/source/onnx/android/pic/open-sherpa-onnx.png
new file mode 100644
index 000000000..881208e15
Binary files /dev/null and b/docs/source/onnx/android/pic/open-sherpa-onnx.png differ
diff --git a/docs/source/onnx/android/pic/pre-trained-model-2023-02-20.png b/docs/source/onnx/android/pic/pre-trained-model-2023-02-20.png
new file mode 100644
index 000000000..b17c79497
Binary files /dev/null and b/docs/source/onnx/android/pic/pre-trained-model-2023-02-20.png differ
diff --git a/docs/source/onnx/android/pic/select-sdk-manager.png b/docs/source/onnx/android/pic/select-sdk-manager.png
new file mode 100644
index 000000000..0707b53f8
Binary files /dev/null and b/docs/source/onnx/android/pic/select-sdk-manager.png differ
diff --git a/docs/source/onnx/android/pic/so-libs-for-arm64-v8a.jpg b/docs/source/onnx/android/pic/so-libs-for-arm64-v8a.jpg
new file mode 100644
index 000000000..fb34f0c98
Binary files /dev/null and b/docs/source/onnx/android/pic/so-libs-for-arm64-v8a.jpg differ
diff --git a/docs/source/onnx/android/pic/so-libs-for-armv7a-eabi.jpg b/docs/source/onnx/android/pic/so-libs-for-armv7a-eabi.jpg
new file mode 100644
index 000000000..a82bf1264
Binary files /dev/null and b/docs/source/onnx/android/pic/so-libs-for-armv7a-eabi.jpg differ
diff --git a/docs/source/onnx/android/pic/so-libs-for-x86-64.jpg b/docs/source/onnx/android/pic/so-libs-for-x86-64.jpg
new file mode 100644
index 000000000..9600e4da4
Binary files /dev/null and b/docs/source/onnx/android/pic/so-libs-for-x86-64.jpg differ
diff --git a/docs/source/onnx/android/pic/so-libs-for-x86.jpg b/docs/source/onnx/android/pic/so-libs-for-x86.jpg
new file mode 100644
index 000000000..bd34203cc
Binary files /dev/null and b/docs/source/onnx/android/pic/so-libs-for-x86.jpg differ
diff --git a/docs/source/onnx/android/pic/start-android-studio.png b/docs/source/onnx/android/pic/start-android-studio.png
new file mode 100644
index 000000000..1a42e13e8
Binary files /dev/null and b/docs/source/onnx/android/pic/start-android-studio.png differ
diff --git a/docs/source/onnx/android/pic/type-for-pre-trained-model-2023-02-20.png b/docs/source/onnx/android/pic/type-for-pre-trained-model-2023-02-20.png
new file mode 100644
index 000000000..514e86146
Binary files /dev/null and b/docs/source/onnx/android/pic/type-for-pre-trained-model-2023-02-20.png differ
diff --git a/docs/source/onnx/android/prebuilt-apk.rst b/docs/source/onnx/android/prebuilt-apk.rst
new file mode 100644
index 000000000..df03d3f6e
--- /dev/null
+++ b/docs/source/onnx/android/prebuilt-apk.rst
@@ -0,0 +1,47 @@
+Pre-built APKs
+==============
+
+Links for pre-built APKs can be found in the following table:
+
+.. hint::
+
+ It runs locally, without internet connection.
+
+.. list-table::
+
+ * - ****
+ - 中国用户
+ - URL
+ * - Streaming speech recognition
+ - `点这里 `_
+ - ``_
+ * - Text-to-speech engine
+ - `点这里 `_
+ - ``_
+ * - Text-to-speech
+ - `点这里 `_
+ - ``_
+ * - Voice activity detection (VAD)
+ - `点这里 `_
+ - ``_
+ * - VAD + non-streaming speech recognition
+ - `点这里 `_
+ - ``_
+ * - Two-pass speech recognition
+ - `点这里 `_
+ - ``_
+ * - Audio tagging
+ - `点这里 `_
+ - ``_
+ * - Audio tagging (WearOS)
+ - `点这里 `_
+ - ``_
+ * - Speaker identification
+ - `点这里 `_
+ - ``_
+ * - Spoken language identification
+ - `点这里 `_
+ - ``_
+ * - Keyword spotting
+ - `点这里 `_
+ - ``_
diff --git a/docs/source/onnx/audio-tagging/android.rst b/docs/source/onnx/audio-tagging/android.rst
new file mode 100644
index 000000000..8f72e7346
--- /dev/null
+++ b/docs/source/onnx/audio-tagging/android.rst
@@ -0,0 +1,13 @@
+.. _audio-tagging-android:
+
+Android
+=======
+
+You can find Android APKs for each model at the following page
+
+ ``_
+
+Please follow :ref:`sherpa-onnx-android` to build Android APKs from source.
+
+If you want to run audio tagging on your WearOS watches, please see
+:ref:`audio-tagging-wearos`.
diff --git a/docs/source/onnx/audio-tagging/index.rst b/docs/source/onnx/audio-tagging/index.rst
new file mode 100644
index 000000000..f0eadbc34
--- /dev/null
+++ b/docs/source/onnx/audio-tagging/index.rst
@@ -0,0 +1,13 @@
+Audio tagging
+=============
+
+This section introduces the models that `sherpa-onnx`_ supports for audio
+tagging, which aims to recognize sound events within an audio clip without
+its temporal localization.
+
+.. toctree::
+ :maxdepth: 5
+
+ ./pretrained_models.rst
+ ./android.rst
+ ./wearos.rst
diff --git a/docs/source/onnx/audio-tagging/pretrained_models.rst b/docs/source/onnx/audio-tagging/pretrained_models.rst
new file mode 100644
index 000000000..56471f202
--- /dev/null
+++ b/docs/source/onnx/audio-tagging/pretrained_models.rst
@@ -0,0 +1,571 @@
+Pre-trained models
+==================
+
+This section lists pre-trained models for audio tagging.
+
+You can find all models at the following URL:
+
+ ``_
+
+sherpa-onnx-zipformer-small-audio-tagging-2024-04-15
+----------------------------------------------------
+
+This model is trained by ``_
+using the dataset `audioset`_.
+
+In the following, we describe how to download and use it with `sherpa-onnx`_.
+
+Download the model
+^^^^^^^^^^^^^^^^^^
+
+Please use the following commands to download it::
+
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/audio-tagging-models/sherpa-onnx-zipformer-small-audio-tagging-2024-04-15.tar.bz2
+
+ tar xvf sherpa-onnx-zipformer-small-audio-tagging-2024-04-15.tar.bz2
+ rm sherpa-onnx-zipformer-small-audio-tagging-2024-04-15.tar.bz2
+
+You will find the following files after unzipping::
+
+ -rw-r--r-- 1 fangjun staff 243B Apr 15 16:14 README.md
+ -rw-r--r-- 1 fangjun staff 14K Apr 15 16:14 class_labels_indices.csv
+ -rw-r--r-- 1 fangjun staff 26M Apr 15 16:14 model.int8.onnx
+ -rw-r--r-- 1 fangjun staff 88M Apr 15 16:14 model.onnx
+ drwxr-xr-x 15 fangjun staff 480B Apr 15 16:14 test_wavs
+
+C++ binary examples
+^^^^^^^^^^^^^^^^^^^
+
+.. hint::
+
+ You can find the binary executable file ``sherpa-onnx-offline-audio-tagging``
+ after installing `sherpa-onnx`_ either from source or using ``pip install sherpa-onnx``_.
+
+Cat
+:::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
1.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/1.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Animal", index=72, prob=0.947886)
+ 1: AudioEvent(name="Cat", index=81, prob=0.938876)
+ 2: AudioEvent(name="Domestic animals, pets", index=73, prob=0.931975)
+ 3: AudioEvent(name="Caterwaul", index=85, prob=0.178876)
+ 4: AudioEvent(name="Meow", index=83, prob=0.176177)
+ Num threads: 1
+ Wave duration: 10.000
+ Elapsed seconds: 0.297 s
+ Real time factor (RTF): 0.297 / 10.000 = 0.030
+
+.. hint::
+
+ By default, it outputs the top 5 events. The first event has the
+ largest probability.
+
+Whistle
+:::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
2.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/2.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Whistling", index=40, prob=0.804928)
+ 1: AudioEvent(name="Music", index=137, prob=0.27548)
+ 2: AudioEvent(name="Piano", index=153, prob=0.135418)
+ 3: AudioEvent(name="Keyboard (musical)", index=152, prob=0.0580414)
+ 4: AudioEvent(name="Musical instrument", index=138, prob=0.0400399)
+ Num threads: 1
+ Wave duration: 10.000
+ Elapsed seconds: 0.289 s
+ Real time factor (RTF): 0.289 / 10.000 = 0.029
+
+Music
+:::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
3.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/3.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Music", index=137, prob=0.79673)
+ 1: AudioEvent(name="A capella", index=255, prob=0.765521)
+ 2: AudioEvent(name="Singing", index=27, prob=0.473899)
+ 3: AudioEvent(name="Vocal music", index=254, prob=0.459337)
+ 4: AudioEvent(name="Choir", index=28, prob=0.458174)
+ Num threads: 1
+ Wave duration: 10.000
+ Elapsed seconds: 0.279 s
+ Real time factor (RTF): 0.279 / 10.000 = 0.028
+
+Laughter
+::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
4.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/4.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Laughter", index=16, prob=0.929239)
+ 1: AudioEvent(name="Snicker", index=19, prob=0.321969)
+ 2: AudioEvent(name="Giggle", index=18, prob=0.149667)
+ 3: AudioEvent(name="Inside, small room", index=506, prob=0.119332)
+ 4: AudioEvent(name="Belly laugh", index=20, prob=0.100728)
+ Num threads: 1
+ Wave duration: 10.000
+ Elapsed seconds: 0.314 s
+ Real time factor (RTF): 0.314 / 10.000 = 0.031
+
+Finger snapping
+:::::::::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
5.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/5.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Finger snapping", index=62, prob=0.690543)
+ 1: AudioEvent(name="Slap, smack", index=467, prob=0.452133)
+ 2: AudioEvent(name="Clapping", index=63, prob=0.179213)
+ 3: AudioEvent(name="Sound effect", index=504, prob=0.101151)
+ 4: AudioEvent(name="Whack, thwack", index=468, prob=0.0294559)
+ Num threads: 1
+ Wave duration: 8.284
+ Elapsed seconds: 0.225 s
+ Real time factor (RTF): 0.225 / 8.284 = 0.027
+
+Baby cry
+::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
6.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/6.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Baby cry, infant cry", index=23, prob=0.912273)
+ 1: AudioEvent(name="Crying, sobbing", index=22, prob=0.670927)
+ 2: AudioEvent(name="Whimper", index=24, prob=0.187221)
+ 3: AudioEvent(name="Inside, small room", index=506, prob=0.0314955)
+ 4: AudioEvent(name="Sound effect", index=504, prob=0.0118726)
+ Num threads: 1
+ Wave duration: 8.719
+ Elapsed seconds: 0.232 s
+ Real time factor (RTF): 0.232 / 8.719 = 0.027
+
+Smoke alarm
+:::::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
7.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/7.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Smoke detector, smoke alarm", index=399, prob=0.781478)
+ 1: AudioEvent(name="Beep, bleep", index=481, prob=0.641056)
+ 2: AudioEvent(name="Buzzer", index=398, prob=0.218576)
+ 3: AudioEvent(name="Fire alarm", index=400, prob=0.140145)
+ 4: AudioEvent(name="Alarm", index=388, prob=0.012525)
+ Num threads: 1
+ Wave duration: 2.819
+ Elapsed seconds: 0.080 s
+ Real time factor (RTF): 0.080 / 2.819 = 0.028
+
+Siren
+:::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
8.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/8.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Siren", index=396, prob=0.877108)
+ 1: AudioEvent(name="Civil defense siren", index=397, prob=0.732789)
+ 2: AudioEvent(name="Vehicle", index=300, prob=0.0113797)
+ 3: AudioEvent(name="Inside, small room", index=506, prob=0.00537381)
+ 4: AudioEvent(name="Outside, urban or manmade", index=509, prob=0.00261939)
+ Num threads: 1
+ Wave duration: 7.721
+ Elapsed seconds: 0.220 s
+ Real time factor (RTF): 0.220 / 7.721 = 0.028
+
+Stream water
+::::::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
10.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/10.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Stream", index=292, prob=0.247785)
+ 1: AudioEvent(name="Water", index=288, prob=0.231587)
+ 2: AudioEvent(name="Gurgling", index=297, prob=0.170981)
+ 3: AudioEvent(name="Trickle, dribble", index=450, prob=0.108859)
+ 4: AudioEvent(name="Liquid", index=444, prob=0.0693812)
+ Num threads: 1
+ Wave duration: 7.837
+ Elapsed seconds: 0.212 s
+ Real time factor (RTF): 0.212 / 7.837 = 0.027
+
+Meow
+::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
11.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/11.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Meow", index=83, prob=0.814944)
+ 1: AudioEvent(name="Cat", index=81, prob=0.698858)
+ 2: AudioEvent(name="Domestic animals, pets", index=73, prob=0.564516)
+ 3: AudioEvent(name="Animal", index=72, prob=0.535303)
+ 4: AudioEvent(name="Music", index=137, prob=0.105332)
+ Num threads: 1
+ Wave duration: 11.483
+ Elapsed seconds: 0.361 s
+ Real time factor (RTF): 0.361 / 11.483 = 0.031
+
+Dog bark
+::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
12.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/12.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Animal", index=72, prob=0.688237)
+ 1: AudioEvent(name="Dog", index=74, prob=0.637803)
+ 2: AudioEvent(name="Bark", index=75, prob=0.608597)
+ 3: AudioEvent(name="Bow-wow", index=78, prob=0.515501)
+ 4: AudioEvent(name="Domestic animals, pets", index=73, prob=0.495074)
+ Num threads: 1
+ Wave duration: 8.974
+ Elapsed seconds: 0.261 s
+ Real time factor (RTF): 0.261 / 8.974 = 0.029
+
+Oink (pig)
+::::::::::
+
+For the following test wave,
+
+.. raw:: html
+
+
+
+
Wave filename
+
Wave
+
+
+
13.wav
+
+
+
+
+
+
+the command::
+
+ ./bin/sherpa-onnx-offline-audio-tagging \
+ --zipformer-model=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/model.int8.onnx \
+ --labels=./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/class_labels_indices.csv \
+ ./sherpa-onnx-zipformer-small-audio-tagging-2024-04-15/test_wavs/13.wav
+
+prints the following::
+
+ 0: AudioEvent(name="Oink", index=94, prob=0.888416)
+ 1: AudioEvent(name="Pig", index=93, prob=0.164295)
+ 2: AudioEvent(name="Animal", index=72, prob=0.160802)
+ 3: AudioEvent(name="Speech", index=0, prob=0.0276513)
+ 4: AudioEvent(name="Snort", index=46, prob=0.0201952)
+ Num threads: 1
+ Wave duration: 9.067
+ Elapsed seconds: 0.261 s
+ Real time factor (RTF): 0.261 / 9.067 = 0.029
+
+Python API examples
+^^^^^^^^^^^^^^^^^^^
+
+Please see
+
+ ``_
+
+Huggingface space
+^^^^^^^^^^^^^^^^^
+
+You can try audio tagging with `sherpa-onnx`_ from within you browser by visiting the following URL:
+
+ ``_
+
+.. note::
+
+ For Chinese users, please use
+
+ ``_
diff --git a/docs/source/onnx/audio-tagging/wearos.rst b/docs/source/onnx/audio-tagging/wearos.rst
new file mode 100644
index 000000000..690adeb7f
--- /dev/null
+++ b/docs/source/onnx/audio-tagging/wearos.rst
@@ -0,0 +1,13 @@
+.. _audio-tagging-wearos:
+
+WearOS
+======
+
+You can find APKs for WearOS of each model at the following page
+
+ ``_
+
+Please follow :ref:`sherpa-onnx-android` to build APKs for WearOS from source.
+
+If you want to run audio tagging on your Android phones, please see
+:ref:`audio-tagging-android`.
diff --git a/docs/source/onnx/c-api/index.rst b/docs/source/onnx/c-api/index.rst
new file mode 100644
index 000000000..553681120
--- /dev/null
+++ b/docs/source/onnx/c-api/index.rst
@@ -0,0 +1,315 @@
+.. _sherpa-onnx-c-api:
+
+C API
+=====
+
+In this section, we describe how to use the C API of `sherpa-onnx`_.
+
+
+Specifically, we will describe:
+
+ - How to generate required files
+ - How to use ``pkg-config`` with `sherpa-onnx`_
+
+You can find the implementation at
+
+ - ``_
+ - ``_
+
+Generate required files
+-----------------------
+
+Before using the C API of `sherpa-onnx`_, we need to first build required
+libraries. You can choose either to build static libraries or shared libraries.
+
+Build shared libraries
+^^^^^^^^^^^^^^^^^^^^^^
+
+Assume that we want to put library files and header files in the directory
+``/tmp/sherpa-onnx/shared``:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx
+ mkdir build-shared
+ cd build-shared
+
+ cmake \
+ -DSHERPA_ONNX_ENABLE_C_API=ON \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=ON \
+ -DCMAKE_INSTALL_PREFIX=/tmp/sherpa-onnx/shared \
+ ..
+
+ make -j6
+ make install
+
+You should find the following files inside ``/tmp/sherpa-onnx/shared``:
+
+.. tabs::
+
+ .. tab:: macOS
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-onnx/shared/
+
+ /tmp/sherpa-onnx/shared
+ ├── bin
+ │ ├── sherpa-onnx
+ │ ├── sherpa-onnx-keyword-spotter
+ │ ├── sherpa-onnx-keyword-spotter-microphone
+ │ ├── sherpa-onnx-microphone
+ │ ├── sherpa-onnx-microphone-offline
+ │ ├── sherpa-onnx-microphone-offline-audio-tagging
+ │ ├── sherpa-onnx-microphone-offline-speaker-identification
+ │ ├── sherpa-onnx-offline
+ │ ├── sherpa-onnx-offline-audio-tagging
+ │ ├── sherpa-onnx-offline-language-identification
+ │ ├── sherpa-onnx-offline-parallel
+ │ ├── sherpa-onnx-offline-punctuation
+ │ ├── sherpa-onnx-offline-tts
+ │ ├── sherpa-onnx-offline-tts-play
+ │ ├── sherpa-onnx-offline-websocket-server
+ │ ├── sherpa-onnx-online-punctuation
+ │ ├── sherpa-onnx-online-websocket-client
+ │ ├── sherpa-onnx-online-websocket-server
+ │ ├── sherpa-onnx-vad-microphone
+ │ └── sherpa-onnx-vad-microphone-offline-asr
+ ├── include
+ │ └── sherpa-onnx
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libonnxruntime.1.17.1.dylib
+ │ ├── libonnxruntime.dylib -> libonnxruntime.1.17.1.dylib
+ │ └── libsherpa-onnx-c-api.dylib
+ └── sherpa-onnx.pc
+
+ 5 directories, 25 files
+
+ .. tab:: Linux
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-onnx/shared/
+
+ /tmp/sherpa-onnx/shared
+ ├── bin
+ │ ├── sherpa-onnx
+ │ ├── sherpa-onnx-alsa
+ │ ├── sherpa-onnx-alsa-offline
+ │ ├── sherpa-onnx-alsa-offline-audio-tagging
+ │ ├── sherpa-onnx-alsa-offline-speaker-identification
+ │ ├── sherpa-onnx-keyword-spotter
+ │ ├── sherpa-onnx-keyword-spotter-alsa
+ │ ├── sherpa-onnx-offline
+ │ ├── sherpa-onnx-offline-audio-tagging
+ │ ├── sherpa-onnx-offline-language-identification
+ │ ├── sherpa-onnx-offline-parallel
+ │ ├── sherpa-onnx-offline-punctuation
+ │ ├── sherpa-onnx-offline-tts
+ │ ├── sherpa-onnx-offline-tts-play-alsa
+ │ ├── sherpa-onnx-offline-websocket-server
+ │ ├── sherpa-onnx-online-punctuation
+ │ ├── sherpa-onnx-online-websocket-client
+ │ ├── sherpa-onnx-online-websocket-server
+ │ └── sherpa-onnx-vad-alsa
+ ├── include
+ │ └── sherpa-onnx
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libonnxruntime.so
+ │ └── libsherpa-onnx-c-api.so
+ └── sherpa-onnx.pc
+
+ 6 directories, 23 files
+
+
+Build static libraries
+^^^^^^^^^^^^^^^^^^^^^^
+
+Assume that we want to put library files and header files in the directory
+``/tmp/sherpa-onnx/static``:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx
+ mkdir build-static
+ cd build-static
+
+ cmake \
+ -DSHERPA_ONNX_ENABLE_C_API=ON \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DCMAKE_INSTALL_PREFIX=/tmp/sherpa-onnx/static \
+ ..
+
+ make -j6
+ make install
+
+You should find the following files in ``/tmp/sherpa-onnx/static``:
+
+.. tabs::
+
+ .. tab:: macOS
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-onnx/static/
+
+ /tmp/sherpa-onnx/static
+ ├── bin
+ │ ├── sherpa-onnx
+ │ ├── sherpa-onnx-keyword-spotter
+ │ ├── sherpa-onnx-keyword-spotter-microphone
+ │ ├── sherpa-onnx-microphone
+ │ ├── sherpa-onnx-microphone-offline
+ │ ├── sherpa-onnx-microphone-offline-audio-tagging
+ │ ├── sherpa-onnx-microphone-offline-speaker-identification
+ │ ├── sherpa-onnx-offline
+ │ ├── sherpa-onnx-offline-audio-tagging
+ │ ├── sherpa-onnx-offline-language-identification
+ │ ├── sherpa-onnx-offline-parallel
+ │ ├── sherpa-onnx-offline-punctuation
+ │ ├── sherpa-onnx-offline-tts
+ │ ├── sherpa-onnx-offline-tts-play
+ │ ├── sherpa-onnx-offline-websocket-server
+ │ ├── sherpa-onnx-online-punctuation
+ │ ├── sherpa-onnx-online-websocket-client
+ │ ├── sherpa-onnx-online-websocket-server
+ │ ├── sherpa-onnx-vad-microphone
+ │ └── sherpa-onnx-vad-microphone-offline-asr
+ ├── include
+ │ └── sherpa-onnx
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libespeak-ng.a
+ │ ├── libkaldi-decoder-core.a
+ │ ├── libkaldi-native-fbank-core.a
+ │ ├── libonnxruntime.a
+ │ ├── libpiper_phonemize.a
+ │ ├── libsherpa-onnx-c-api.a
+ │ ├── libsherpa-onnx-core.a
+ │ ├── libsherpa-onnx-fst.a
+ │ ├── libsherpa-onnx-fstfar.a
+ │ ├── libsherpa-onnx-kaldifst-core.a
+ │ ├── libsherpa-onnx-portaudio_static.a
+ │ ├── libssentencepiece_core.a
+ │ └── libucd.a
+ └── sherpa-onnx.pc
+
+ 5 directories, 35 files
+
+ .. tab:: Linux
+
+ .. code-block:: bash
+
+ $ tree /tmp/sherpa-onnx/static/
+
+ /tmp/sherpa-onnx/static
+ ├── bin
+ │ ├── sherpa-onnx
+ │ ├── sherpa-onnx-alsa
+ │ ├── sherpa-onnx-alsa-offline
+ │ ├── sherpa-onnx-alsa-offline-audio-tagging
+ │ ├── sherpa-onnx-alsa-offline-speaker-identification
+ │ ├── sherpa-onnx-keyword-spotter
+ │ ├── sherpa-onnx-keyword-spotter-alsa
+ │ ├── sherpa-onnx-keyword-spotter-microphone
+ │ ├── sherpa-onnx-microphone
+ │ ├── sherpa-onnx-microphone-offline
+ │ ├── sherpa-onnx-microphone-offline-audio-tagging
+ │ ├── sherpa-onnx-microphone-offline-speaker-identification
+ │ ├── sherpa-onnx-offline
+ │ ├── sherpa-onnx-offline-audio-tagging
+ │ ├── sherpa-onnx-offline-language-identification
+ │ ├── sherpa-onnx-offline-parallel
+ │ ├── sherpa-onnx-offline-punctuation
+ │ ├── sherpa-onnx-offline-tts
+ │ ├── sherpa-onnx-offline-tts-play
+ │ ├── sherpa-onnx-offline-tts-play-alsa
+ │ ├── sherpa-onnx-offline-websocket-server
+ │ ├── sherpa-onnx-online-punctuation
+ │ ├── sherpa-onnx-online-websocket-client
+ │ ├── sherpa-onnx-online-websocket-server
+ │ ├── sherpa-onnx-vad-alsa
+ │ ├── sherpa-onnx-vad-microphone
+ │ └── sherpa-onnx-vad-microphone-offline-asr
+ ├── include
+ │ └── sherpa-onnx
+ │ └── c-api
+ │ └── c-api.h
+ ├── lib
+ │ ├── libespeak-ng.a
+ │ ├── libkaldi-decoder-core.a
+ │ ├── libkaldi-native-fbank-core.a
+ │ ├── libonnxruntime.a
+ │ ├── libpiper_phonemize.a
+ │ ├── libsherpa-onnx-c-api.a
+ │ ├── libsherpa-onnx-core.a
+ │ ├── libsherpa-onnx-fst.a
+ │ ├── libsherpa-onnx-fstfar.a
+ │ ├── libsherpa-onnx-kaldifst-core.a
+ │ ├── libsherpa-onnx-portaudio_static.a
+ │ ├── libssentencepiece_core.a
+ │ └── libucd.a
+ └── sherpa-onnx.pc
+
+ 6 directories, 42 files
+
+
+Build decode-file-c-api.c with generated files
+----------------------------------------------
+
+To build the following file:
+
+ ``_
+
+We can use:
+
+.. tabs::
+
+ .. tab:: static link
+
+ .. code-block:: bash
+
+ export PKG_CONFIG_PATH=/tmp/sherpa-onnx/static:$PKG_CONFIG_PATH
+
+ cd ./c-api-examples
+ gcc -o decode-file-c-api $(pkg-config --cflags sherpa-onnx) ./decode-file-c-api.c $(pkg-config --libs sherpa-onnx)
+
+ ./decode-file-c-api --help
+
+ .. tab:: dynamic link
+
+ .. code-block:: bash
+
+ export PKG_CONFIG_PATH=/tmp/sherpa-onnx/shared:$PKG_CONFIG_PATH
+
+ cd ./c-api-examples
+ gcc -o decode-file-c-api $(pkg-config --cflags sherpa-onnx) ./decode-file-c-api.c $(pkg-config --libs sherpa-onnx)
+
+ ./decode-file-c-api --help
+
+.. warning::
+
+ The order of linking the libraries matters. Please see
+
+ - Static link without TTS: ``_
+ - Static link with TTS: ``_
+ - Dynamic link: ``_
+
+colab
+-----
+
+We provide a colab notebook
+|Sherpa-onnx c api example colab notebook|
+for you to try the C API of `sherpa-onnx`_.
+
+.. |Sherpa-onnx c api example colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-onnx/sherpa_onnx_c_api_example.ipynb
diff --git a/docs/source/onnx/csharp-api/index.rst b/docs/source/onnx/csharp-api/index.rst
new file mode 100644
index 000000000..5af764a30
--- /dev/null
+++ b/docs/source/onnx/csharp-api/index.rst
@@ -0,0 +1,535 @@
+.. _sherpa-onnx-csharp-api:
+
+C# API
+======
+
+In this section, we describe how to use the ``C#``
+API examples of `sherpa-onnx`_.
+
+The ``C#`` API of `sherpa-onnx`_ supports both streaming and non-streaming speech recognition.
+
+The following table lists some ``C#`` API examples:
+
+.. list-table::
+
+ * - Description
+ - URL
+ * - Decode a file with **non-streaming** models
+ - ``_
+ * - Decode a file with **streaming** models
+ - ``_
+ * - **Real-time** speech recognition from a ``microphone``
+ - ``_
+
+You can find the implementation in the following files:
+
+ - API for **streaming** speech recognition
+
+ ``_
+
+ - API for **non-streaming** speech recognition
+
+ ``_
+
+We also provide a nuget package for `sherpa-onnx`_:
+
+ ``_
+
+You can use the following statement in your ``csproj`` file to introduce
+the dependency on `sherpa-onnx`_:
+
+.. code-block:: bash
+
+
+
+One thing to note is that we have provided pre-built libraries for ``C#`` so that you don't need
+to build `sherpa-onnx`_ by yourself when using the ``C#`` API.
+
+In the following, we describe how to run our provided ``C#`` API examples.
+
+.. note::
+
+ Before you continue, please make sure you have installed `.Net `_.
+ If not, please follow ``_ to install ``.Net``.
+
+.. hint::
+
+ ``.Net`` supports Windows, macOS, and Linux.
+
+Decode files with non-streaming models
+--------------------------------------
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/dotnet-examples/offline-decode-files/
+ dotnet build -c Release
+ ./bin/Release/net6.0/offline-decode-files --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ # Zipformer
+
+ dotnet run \
+ --tokens=./sherpa-onnx-zipformer-en-2023-04-01/tokens.txt \
+ --encoder=./sherpa-onnx-zipformer-en-2023-04-01/encoder-epoch-99-avg-1.onnx \
+ --decoder=./sherpa-onnx-zipformer-en-2023-04-01/decoder-epoch-99-avg-1.onnx \
+ --joiner=./sherpa-onnx-zipformer-en-2023-04-01/joiner-epoch-99-avg-1.onnx \
+ --files ./sherpa-onnx-zipformer-en-2023-04-01/test_wavs/0.wav \
+ ./sherpa-onnx-zipformer-en-2023-04-01/test_wavs/1.wav \
+ ./sherpa-onnx-zipformer-en-2023-04-01/test_wavs/8k.wav
+
+ Please refer to
+ https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-transducer/index.html
+ to download pre-trained non-streaming zipformer models.
+
+ # Paraformer
+
+ dotnet run \
+ --tokens=./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt \
+ --paraformer=./sherpa-onnx-paraformer-zh-2023-03-28/model.onnx \
+ --files ./sherpa-onnx-zipformer-en-2023-04-01/test_wavs/0.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/1.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/2.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/8k.wav
+ Please refer to
+ https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-paraformer/index.html
+ to download pre-trained paraformer models
+
+ # NeMo CTC
+
+ dotnet run \
+ --tokens=./sherpa-onnx-nemo-ctc-en-conformer-medium/tokens.txt \
+ --nemo-ctc=./sherpa-onnx-nemo-ctc-en-conformer-medium/model.onnx \
+ --num-threads=1 \
+ --files ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/0.wav \
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/1.wav \
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/8k.wav
+
+ Please refer to
+ https://k2-fsa.github.io/sherpa/onnx/pretrained_models/offline-ctc/index.html
+ to download pre-trained paraformer models
+
+ Copyright (c) 2023 Xiaomi Corporation
+
+ --tokens Path to tokens.txt
+ --encoder Path to encoder.onnx. Used only for transducer models
+ --decoder Path to decoder.onnx. Used only for transducer models
+ --joiner Path to joiner.onnx. Used only for transducer models
+ --paraformer Path to model.onnx. Used only for paraformer models
+ --nemo-ctc Path to model.onnx. Used only for NeMo CTC models
+ --num-threads (Default: 1) Number of threads for computation
+ --decoding-method (Default: greedy_search) Valid decoding methods are:
+ greedy_search, modified_beam_search
+ --max-active-paths (Default: 4) Used only when --decoding--method is
+ modified_beam_search.
+ It specifies number of active paths to keep during the
+ search
+ --files Required. Audio files for decoding
+ --help Display this help screen.
+ --version Display version information.
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a non-streaming model.
+
+We give several examples below for demonstration.
+
+Non-streaming transducer
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/dotnet-examples/offline-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --encoder ./sherpa-onnx-zipformer-en-2023-06-26/encoder-epoch-99-avg-1.onnx \
+ --decoder ./sherpa-onnx-zipformer-en-2023-06-26/decoder-epoch-99-avg-1.onnx \
+ --joiner ./sherpa-onnx-zipformer-en-2023-06-26/joiner-epoch-99-avg-1.onnx \
+ --tokens ./sherpa-onnx-zipformer-en-2023-06-26/tokens.txt \
+ --files ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/0.wav \
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/1.wav \
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/8k.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ /Users/runner/work/sherpa-onnx/sherpa-onnx/sherpa-onnx/csrc/offline-stream.cc:AcceptWaveformImpl:117 Creating a resampler:
+ in_sample_rate: 8000
+ output_sample_rate: 16000
+
+ --------------------
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/0.wav
+ AFTER EARLY NIGHTFALL THE YELLOW LAMPS WOULD LIGHT UP HERE AND THERE THE SQUALID QUARTER OF THE BROTHELS
+ --------------------
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/1.wav
+ GOD AS A DIRECT CONSEQUENCE OF THE SIN WHICH MAN THUS PUNISHED HAD GIVEN HER A LOVELY CHILD WHOSE PLACE WAS ON THAT SAME DISHONORED BOSOM TO CONNECT HER PARENT FOREVER WITH THE RACE AND DESCENT OF MORTALS AND TO BE FINALLY A BLESSED SOUL IN HEAVEN
+ --------------------
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/8k.wav
+ YET THESE THOUGHTS AFFECTED HESTER PRYNNE LESS WITH HOPE THAN APPREHENSION
+ --------------------
+
+Non-streaming paraformer
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa_onnx_offline_paraformer_zh_2023_03_28_chinese` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/dotnet-examples/offline-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+ tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+ rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --paraformer ./sherpa-onnx-paraformer-zh-2023-03-28/model.int8.onnx \
+ --tokens ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt \
+ --files ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/1.wav \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/8k.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ /Users/runner/work/sherpa-onnx/sherpa-onnx/sherpa-onnx/csrc/offline-stream.cc:AcceptWaveformImpl:117 Creating a resampler:
+ in_sample_rate: 8000
+ output_sample_rate: 16000
+
+ --------------------
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav
+ 对我做了介绍啊那么我想说的是呢大家如果对我的研究感兴趣呢你
+ --------------------
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/1.wav
+ 重点呢想谈三个问题首先呢就是这一轮全球金融动荡的表现
+ --------------------
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/8k.wav
+ 甚至出现交易几乎停滞的情况
+ --------------------
+
+Non-streaming CTC model from NeMo
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`stt-en-conformer-ctc-medium-nemo-sherpa-onnx` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/dotnet-examples/offline-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+ tar xvf sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+ rm sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --nemo-ctc ./sherpa-onnx-nemo-ctc-en-conformer-medium/model.onnx \
+ --tokens ./sherpa-onnx-nemo-ctc-en-conformer-medium/tokens.txt \
+ --files ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/0.wav \
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/1.wav \
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/8k.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ /Users/runner/work/sherpa-onnx/sherpa-onnx/sherpa-onnx/csrc/offline-stream.cc:AcceptWaveformImpl:117 Creating a resampler:
+ in_sample_rate: 8000
+ output_sample_rate: 16000
+
+ --------------------
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/0.wav
+ after early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels
+ --------------------
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/1.wav
+ god as a direct consequence of the sin which man thus punished had given her a lovely child whose place was on that same dishonored bosom to connect her parent for ever with the race and descent of mortals and to be finally a blessed soul in heaven
+ --------------------
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/8k.wav
+ yet these thoughts affected hester pryne less with hope than apprehension
+ --------------------
+
+Decode files with streaming models
+----------------------------------
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/dotnet-examples/online-decode-files
+ dotnet build -c Release
+ ./bin/Release/net6.0/online-decode-files --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ dotnet run \
+ --tokens=./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
+ --encoder=./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx \
+ --decoder=./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx \
+ --joiner=./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx \
+ --num-threads=2 \
+ --decoding-method=modified_beam_search \
+ --debug=false \
+ --files ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/test_wavs/0.wav \
+ ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/test_wavs/1.wav
+
+ Please refer to
+ https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/index.html
+ to download pre-trained streaming models.
+
+ Copyright (c) 2023 Xiaomi Corporation
+
+ --tokens Required. Path to tokens.txt
+ --provider (Default: cpu) Provider, e.g., cpu, coreml
+ --encoder Required. Path to encoder.onnx
+ --decoder Required. Path to decoder.onnx
+ --joiner Required. Path to joiner.onnx
+ --num-threads (Default: 1) Number of threads for computation
+ --decoding-method (Default: greedy_search) Valid decoding
+ methods are: greedy_search,
+ modified_beam_search
+ --debug (Default: false) True to show model info
+ during loading
+ --sample-rate (Default: 16000) Sample rate of the data used
+ to train the model
+ --max-active-paths (Default: 4) Used only when --decoding--method
+ is modified_beam_search.
+ It specifies number of active paths to keep
+ during the search
+ --enable-endpoint (Default: false) True to enable endpoint
+ detection.
+ --rule1-min-trailing-silence (Default: 2.4) An endpoint is detected if
+ trailing silence in seconds is
+ larger than this value even if nothing has
+ been decoded. Used only when --enable-endpoint
+ is true.
+ --rule2-min-trailing-silence (Default: 1.2) An endpoint is detected if
+ trailing silence in seconds is
+ larger than this value after something that is
+ not blank has been decoded. Used
+ only when --enable-endpoint is true.
+ --rule3-min-utterance-length (Default: 20) An endpoint is detected if the
+ utterance in seconds is
+ larger than this value. Used only when
+ --enable-endpoint is true.
+ --files Required. Audio files for decoding
+ --help Display this help screen.
+ --version Display version information.
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a streaming model.
+
+We give one example below for demonstration.
+
+Streaming transducer
+^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-streaming-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/dotnet-examples/online-decode-files/
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --encoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/encoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --decoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/decoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --joiner ./sherpa-onnx-streaming-zipformer-en-2023-06-26/joiner-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --tokens ./sherpa-onnx-streaming-zipformer-en-2023-06-26/tokens.txt \
+ --files ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/0.wav \
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/1.wav \
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/8k.wav
+
+You will find the following output:
+
+.. code-block:: bash
+
+ /Users/runner/work/sherpa-onnx/sherpa-onnx/sherpa-onnx/csrc/features.cc:AcceptWaveform:76 Creating a resampler:
+ in_sample_rate: 8000
+ output_sample_rate: 16000
+
+ --------------------
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/0.wav
+ AFTER EARLY NIGHTFALL THE YELLOW LAMPS WOULD LIGHT UP HERE AND THERE THE SQUALID QUARTER OF THE BROTHELS
+ --------------------
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/1.wav
+ GOD AS A DIRECT CONSEQUENCE OF THE SIN WHICH MAN THUS PUNISHED HAD GIVEN HER A LOVELY CHILD WHOSE PLACE WAS ON THAT SAME DISHONOURED BOSOM TO CONNECT HER PARENT FOR EVER WITH THE RACE AND DESCENT OF MORTALS AND TO BE FINALLY A BLESSED SOUL IN HEAVEN
+ --------------------
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/8k.wav
+ YET THESE THOUGHTS AFFECTED HESTER PRYNNE LESS WITH HOPE THAN APPREHENSION
+ --------------------
+
+Real-time speech recognition from microphone
+--------------------------------------------
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/dotnet-examples/speech-recognition-from-microphone
+ dotnet build -c Release
+ ./bin/Release/net6.0/speech-recognition-from-microphone --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --tokens ./icefall-asr-zipformer-streaming-wenetspeech-20230615/data/lang_char/tokens.txt \
+ --encoder ./icefall-asr-zipformer-streaming-wenetspeech-20230615/exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx \
+ --decoder ./icefall-asr-zipformer-streaming-wenetspeech-20230615/exp/decoder-epoch-12-avg-4-chunk-16-left-128.onnx \
+ --joiner ./icefall-asr-zipformer-streaming-wenetspeech-20230615/exp/joiner-epoch-12-avg-4-chunk-16-left-128.onnx \
+
+ Please refer to
+ https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/index.html
+ to download pre-trained streaming models.
+
+ Copyright (c) 2023 Xiaomi Corporation
+
+ --tokens Required. Path to tokens.txt
+ --provider (Default: cpu) Provider, e.g., cpu, coreml
+ --encoder Required. Path to encoder.onnx
+ --decoder Required. Path to decoder.onnx
+ --joiner Required. Path to joiner.onnx
+ --num-threads (Default: 1) Number of threads for computation
+ --decoding-method (Default: greedy_search) Valid decoding
+ methods are: greedy_search,
+ modified_beam_search
+ --debug (Default: false) True to show model info
+ during loading
+ --sample-rate (Default: 16000) Sample rate of the data used
+ to train the model
+ --max-active-paths (Default: 4) Used only when --decoding--method
+ is modified_beam_search.
+ It specifies number of active paths to keep
+ during the search
+ --enable-endpoint (Default: true) True to enable endpoint
+ detection.
+ --rule1-min-trailing-silence (Default: 2.4) An endpoint is detected if
+ trailing silence in seconds is
+ larger than this value even if nothing has
+ been decoded. Used only when --enable-endpoint
+ is true.
+ --rule2-min-trailing-silence (Default: 0.8) An endpoint is detected if
+ trailing silence in seconds is
+ larger than this value after something that is
+ not blank has been decoded. Used
+ only when --enable-endpoint is true.
+ --rule3-min-utterance-length (Default: 20) An endpoint is detected if the
+ utterance in seconds is
+ larger than this value. Used only when
+ --enable-endpoint is true.
+ --help Display this help screen.
+ --version Display version information.
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a streaming model.
+
+We give one example below for demonstration.
+
+Streaming transducer
+^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-streaming-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/dotnet-examples/speech-recognition-from-microphone
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ dotnet run -c Release \
+ --encoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/encoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --decoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/decoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --joiner ./sherpa-onnx-streaming-zipformer-en-2023-06-26/joiner-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --tokens ./sherpa-onnx-streaming-zipformer-en-2023-06-26/tokens.txt
+
+You will find the following output:
+
+.. code-block:: bash
+
+ PortAudio V19.7.0-devel, revision 147dd722548358763a8b649b3e4b41dfffbcfbb6
+ Number of devices: 5
+ Device 0
+ Name: Background Music
+ Max input channels: 2
+ Default sample rate: 44100
+ Device 1
+ Name: Background Music (UI Sounds)
+ Max input channels: 2
+ Default sample rate: 44100
+ Device 2
+ Name: MacBook Pro Microphone
+ Max input channels: 1
+ Default sample rate: 48000
+ Device 3
+ Name: MacBook Pro Speakers
+ Max input channels: 0
+ Default sample rate: 48000
+ Device 4
+ Name: WeMeet Audio Device
+ Max input channels: 2
+ Default sample rate: 48000
+
+ Use default device 2 (MacBook Pro Microphone)
+ StreamParameters [
+ device=2
+ channelCount=1
+ sampleFormat=Float32
+ suggestedLatency=0.034520833333333334
+ hostApiSpecificStreamInfo?=[False]
+ ]
+ Started! Please speak
+
+ 0: THIS IS A TEST
+ 1: THIS IS A SECOND TEST
+
+colab
+-----
+
+We provide a colab notebook
+|Sherpa-onnx csharp api example colab notebook|
+for you to try the ``C#`` API examples of `sherpa-onnx`_.
+
+.. |Sherpa-onnx csharp api example colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-onnx/sherpa_onnx_csharp_api_example.ipynb
diff --git a/docs/source/onnx/faqs/change-kotlin-and-java-package-name.rst b/docs/source/onnx/faqs/change-kotlin-and-java-package-name.rst
new file mode 100644
index 000000000..09c9cc36f
--- /dev/null
+++ b/docs/source/onnx/faqs/change-kotlin-and-java-package-name.rst
@@ -0,0 +1,37 @@
+How to change the package name of our kotlin and/or java API
+============================================================
+
+By default, we use:
+
+.. code-block:: kotlin
+
+ package com.k2fsa.sherpa.onnx
+
+
+If you change our package name without changing the JNI C++ binding code, you would
+get errors like:
+
+ - ``_ changes our package
+ name from ``com.k2fsa.sherpa.onnx`` to ``stt`` and gets the following error:
+
+ .. code-block::
+
+ No implementation found for
+ long stt.OfflineRecognizer.newFromAsset(android.content.res.AssetManager, stt.OfflineRecognizerConfig)
+ (tried Java_stt_OfflineRecognizer_newFromAsset and
+ Java_stt_OfflineRecognizer_newFromAsset__Landroid_content_res_AssetManager_2Lstt_OfflineRecognizerConfig_2) -
+ is the library loaded, e.g. System.loadLibrary?
+
+We suggest that you don't change our package name when using our code. You can use ``import``
+to use our Kotlin or Java API.
+
+If you are familiar with JNI and really want to change our package name, please have a look
+at:
+
+ ``_
+
+It shows how to change the package name from ``com.k2fsa.sherpa.onnx`` to ``com.edgeai.chatappv2``.
+
+.. warning::
+
+ You need to change a lot of files.
diff --git a/docs/source/onnx/faqs/diff-online-offline.rst b/docs/source/onnx/faqs/diff-online-offline.rst
new file mode 100644
index 000000000..933729865
--- /dev/null
+++ b/docs/source/onnx/faqs/diff-online-offline.rst
@@ -0,0 +1,13 @@
+在线、离线、流式、非流式的区别
+==============================
+
+此项目中,``在线`` 等同于流式,``离线`` 等同于非流式。
+
+``在线`` 即流式,是边说边识别;响应速度快、延迟小。
+
+``离线`` 即非流式,是把所有待识别的数据,一次性送给模型;特点是需要
+等待所有的数据都到齐, 然后才能开始识别。
+
+不管是 ``离线`` 还是 ``在线``, 我们这个项目,都不需要访问网络,都可以在本地
+处理;即使断网,也能正常工作。
+
diff --git a/docs/source/onnx/faqs/fix-libasound-module-conf-pulse.rst b/docs/source/onnx/faqs/fix-libasound-module-conf-pulse.rst
new file mode 100644
index 000000000..82fc9c9f7
--- /dev/null
+++ b/docs/source/onnx/faqs/fix-libasound-module-conf-pulse.rst
@@ -0,0 +1,31 @@
+Cannot open shared library libasound_module_conf_pulse.so
+=========================================================
+
+The detailed errors are given below:
+
+.. code-block::
+
+ Cannot open shared library libasound_module_conf_pulse.so
+ (/usr/lib64/alsa-lib/libasound_module_conf_pulse.so: cannot open shared object file: No such file or directory)
+ ALSA lib pcm.c:2722:(snd_pcm_open_noupdate) Unknown PCM
+
+If you use Linux and get the above error when trying to use the microphone, please do the following:
+
+ 1. Locate where is the file ``libasound_module_conf_pulse.so`` on your system
+
+ .. code-block:: bash
+
+ find / -name libasound_module_conf_pulse.so 2>/dev/null
+
+ 2. If the above search command prints::
+
+ /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_conf_pulse.so
+ /usr/lib/i386-linux-gnu/alsa-lib/libasound_module_conf_pulse.so
+
+ 3. Please run::
+
+ sudo mkdir -p /usr/lib64/alsa-lib
+ sudo ln -s /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_conf_pulse.so /usr/lib64/alsa-lib
+
+ 4. Now your issue should be fixed.
+
diff --git a/docs/source/onnx/faqs/fix-libtoolize.rst b/docs/source/onnx/faqs/fix-libtoolize.rst
new file mode 100644
index 000000000..d47e546e5
--- /dev/null
+++ b/docs/source/onnx/faqs/fix-libtoolize.rst
@@ -0,0 +1,13 @@
+./gitcompile: line 89: libtoolize: command not found
+====================================================
+
+If you are using Linux and get the following error:
+
+.. code-block::
+
+ ./gitcompile: line 89: libtoolize: command not found
+
+Please run::
+
+ sudo apt-get install libtool
+
diff --git a/docs/source/onnx/faqs/fix-tts-encoding-for-chinese-models.rst b/docs/source/onnx/faqs/fix-tts-encoding-for-chinese-models.rst
new file mode 100644
index 000000000..1057ee2fe
--- /dev/null
+++ b/docs/source/onnx/faqs/fix-tts-encoding-for-chinese-models.rst
@@ -0,0 +1,6 @@
+TTS 中文模型没有声音
+====================
+
+Please see :ref:`how_to_enable_utf8_on_windows`.
+You need to use ``UTF-8`` encoding for your system.
+
diff --git a/docs/source/onnx/faqs/index.rst b/docs/source/onnx/faqs/index.rst
new file mode 100644
index 000000000..895934547
--- /dev/null
+++ b/docs/source/onnx/faqs/index.rst
@@ -0,0 +1,90 @@
+Frequently Asked Question (FAQs)
+================================
+
+This page contains frequently asked questions for `sherpa-onnx`_.
+
+.. toctree::
+ :maxdepth: 5
+
+ ./diff-online-offline.rst
+ ./change-kotlin-and-java-package-name.rst
+ ./fix-libasound-module-conf-pulse.rst
+ ./fix-tts-encoding-for-chinese-models.rst
+ ./fix-libtoolize.rst
+
+
+OSError: PortAudio library not found
+------------------------------------
+
+If you have the following error on Linux (Ubuntu),
+
+.. code-block:: bash
+
+ Traceback (most recent call last):
+ File "/mnt/sdb/shared/sherpa-onnx/./python-api-examples/vad-microphone.py", line 8, in
+ import sounddevice as sd
+ File "/mnt/sdb/shared/py311/lib/python3.11/site-packages/sounddevice.py", line 71, in
+ raise OSError('PortAudio library not found')
+ OSError: PortAudio library not found
+
+Then please run::
+
+ sudo apt-get install libportaudio2
+
+and then re-try.
+
+imports github.com/k2-fsa/sherpa-onnx-go-linux: build constraints exclude all Go files
+--------------------------------------------------------------------------------------
+
+If you have the following output when running ``go build``::
+
+ [root@VM-0-3-centos non-streaming-decode-files]# go build
+ package non-streaming-decode-files
+ imports github.com/k2-fsa/sherpa-onnx-go/sherpa_onnx
+ imports github.com/k2-fsa/sherpa-onnx-go-linux: build constraints exclude all Go files in /root/go/pkg/mod/github.com/k2-fsa/sherpa-onnx-go-linux@v1.9.21
+
+Please first run::
+
+ go env -w CGO_ENABLED=1
+
+And then re-run ``go build``.
+
+External buffers are not allowed
+--------------------------------
+
+If you are using ``electron >= 21`` and get the following error:
+
+.. code-block::
+
+ External buffers are not allowed
+
+Then please set ``enableExternalBuffer`` to ``false``.
+
+Specifically,
+
+ - For reading wave files, please use ``sherpa_onnx.readWave(filename, false);``,
+ where the second argument ``false`` means to not use external buffers
+
+ - For VAD, please use ``vad.get(startIndex, n, false)`` and ``vad.front(false)``
+
+ - For speaker identification, please use ``extractor.compute(stream, false)``
+
+ - For TTS, please use:
+
+ .. code-block:: javascript
+
+ const audio = tts.generate({
+ text: text,
+ sid: 0,
+ speed: 1.0,
+ enableExternalBuffer: false,
+ });
+
+The given version [17] is not supported, only version 1 to 10 is supported in this build
+----------------------------------------------------------------------------------------
+
+If you have such an error, please find the file ``onnxruntime.dll`` in your ``C`` drive
+and try to remove it.
+
+The reason is that you have two ``onnxruntime.dll`` on your computer and the one
+in your ``C`` drive is outdated.
diff --git a/docs/source/onnx/flutter/index.rst b/docs/source/onnx/flutter/index.rst
new file mode 100644
index 000000000..f9217ac13
--- /dev/null
+++ b/docs/source/onnx/flutter/index.rst
@@ -0,0 +1,9 @@
+.. _sherpa-onnx-flutter:
+
+Flutter
+=======
+
+.. toctree::
+ :maxdepth: 2
+
+ ./pre-built-app.rst
diff --git a/docs/source/onnx/flutter/pre-built-app.rst b/docs/source/onnx/flutter/pre-built-app.rst
new file mode 100644
index 000000000..9afc34a8c
--- /dev/null
+++ b/docs/source/onnx/flutter/pre-built-app.rst
@@ -0,0 +1,46 @@
+Pre-built Flutter Apps
+======================
+
+Links for pre-built Apps can be found in the following table:
+
+.. hint::
+
+ It runs locally, without internet connection.
+
+Text to speech (TTS, Speech synthesis)
+--------------------------------------
+
+.. list-table::
+
+ * - ****
+ - 中国用户
+ - URL
+ * - Android (arm64-v8a, armeabi-v7a, x86_64)
+ - `点这里 `_
+ - ``_
+
+ * - Linux (x64)
+ - `点这里 `_
+ - ``_
+ * - macOS (x64)
+ - `点这里 `_
+ - ``_
+ * - macOS (arm64)
+ - `点这里 `_
+ - ``_
+ * - Windows (x64)
+ - `点这里 `_
+ - ``_
+
+Streaming Speech recognition (STT, ASR)
+---------------------------------------
+
+.. list-table::
+
+ * - ****
+ - 中国用户
+ - URL
+ * - Streaming speech recognition
+ - `点这里 `_
+ - ``_
+
diff --git a/docs/source/onnx/go-api/index.rst b/docs/source/onnx/go-api/index.rst
new file mode 100644
index 000000000..fe67d2eee
--- /dev/null
+++ b/docs/source/onnx/go-api/index.rst
@@ -0,0 +1,429 @@
+.. _sherpa-onnx-go-api:
+
+Go API
+======
+
+In this section, we describe how to use the `Go`_
+API of `sherpa-onnx`_.
+
+The `Go`_ API of `sherpa-onnx`_ supports both streaming and non-streaming speech recognition.
+
+The following table lists some `Go`_ API examples:
+
+.. list-table::
+
+ * - Description
+ - URL
+ * - Decode a file with **non-streaming** models
+ - ``_
+ * - Decode a file with **streaming** models
+ - ``_
+ * - **Real-time** speech recognition from a ``microphone``
+ - ``_
+
+One thing to note is that we have provided pre-built libraries for `Go`_ so that you don't need
+to build `sherpa-onnx`_ by yourself when using the `Go`_ API.
+
+To make supporting multiple platforms easier, we split the `Go`_ API of `sherpa-onnx`_ into
+multiple packages, as listed in the following table:
+
+.. list-table::
+
+ * - OS
+ - Package name
+ - Supported Arch
+ - Doc
+ * - Linux
+ - `sherpa-onnx-go-linux `_
+ - ``x86_64``, ``aarch64``, ``arm``
+ - ``_
+ * - macOS
+ - `sherpa-onnx-go-macos `_
+ - ``x86_64``, ``aarch64``
+ - ``_
+ * - Windows
+ - `sherpa-onnx-go-windows `_
+ - ``x86_64``, ``x86``
+ - ``_
+
+To simplify the usage, we have provided a single `Go`_ package for `sherpa-onnx`_ that
+supports multiple operating systems. It can be found at
+
+ ``_
+
+.. hint::
+
+ Such a design is insipred by the following article:
+
+ `Cross platform Go modules for giants `_.
+
+You can use the following ``import`` to import `sherpa-onnx-go`_
+into your `Go`_ project:
+
+.. code-block:: go
+
+ import (
+ sherpa "github.com/k2-fsa/sherpa-onnx-go/sherpa_onnx"
+ )
+
+In the following, we describe how to run our provided `Go`_ API examples.
+
+.. note::
+
+ Before you continue, please make sure you have installed `Go`_.
+ If not, please follow ``_ to install `Go`_.
+
+.. hint::
+
+ You need to enable `cgo `_ to build `sherpa-onnx-go`_.
+
+Decode files with non-streaming models
+--------------------------------------
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/go-api-examples/non-streaming-decode-files
+ go mod tidy
+ go build
+ ./non-streaming-decode-files --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ Usage of ./non-streaming-decode-files:
+ --debug int Whether to show debug message
+ --decoder string Path to the decoder model
+ --decoding-method string Decoding method. Possible values: greedy_search, modified_beam_search (default "greedy_search")
+ --encoder string Path to the encoder model
+ --joiner string Path to the joiner model
+ --lm-model string Optional. Path to the LM model
+ --lm-scale float32 Optional. Scale for the LM model (default 1)
+ --max-active-paths int Used only when --decoding-method is modified_beam_search (default 4)
+ --model-type string Optional. Used for loading the model in a faster way
+ --nemo-ctc string Path to the NeMo CTC model
+ --num-threads int Number of threads for computing (default 1)
+ --paraformer string Path to the paraformer model
+ --provider string Provider to use (default "cpu")
+ --tokens string Path to the tokens file
+ pflag: help requested
+
+Congratulations! You have successfully built your first `Go`_ API example for speech recognition.
+
+.. note::
+
+ If you are using Windows and don't see any output after running ``./non-streaming-decode-files --help``,
+ please copy ``*.dll`` from ``_ (for Win64)
+ or ``_ (for Win32)
+ to the directory ``sherpa-onnx/go-api-examples/non-streaming-decode-files``.
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a non-streaming model.
+
+We give several examples below for demonstration.
+
+Non-streaming transducer
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/go-api-examples/non-streaming-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ ./non-streaming-decode-files \
+ --encoder ./sherpa-onnx-zipformer-en-2023-06-26/encoder-epoch-99-avg-1.onnx \
+ --decoder ./sherpa-onnx-zipformer-en-2023-06-26/decoder-epoch-99-avg-1.onnx \
+ --joiner ./sherpa-onnx-zipformer-en-2023-06-26/joiner-epoch-99-avg-1.onnx \
+ --tokens ./sherpa-onnx-zipformer-en-2023-06-26/tokens.txt \
+ --model-type transducer \
+ ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/0.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ 2023/08/10 14:52:48.723098 Reading ./sherpa-onnx-zipformer-en-2023-06-26/test_wavs/0.wav
+ 2023/08/10 14:52:48.741042 Initializing recognizer (may take several seconds)
+ 2023/08/10 14:52:51.998848 Recognizer created!
+ 2023/08/10 14:52:51.998870 Start decoding!
+ 2023/08/10 14:52:52.258818 Decoding done!
+ 2023/08/10 14:52:52.258847 after early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels
+ 2023/08/10 14:52:52.258952 Wave duration: 6.625 seconds
+
+Non-streaming paraformer
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa_onnx_offline_paraformer_zh_2023_03_28_chinese` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/go-api-examples/non-streaming-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+ tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+ rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ ./non-streaming-decode-files \
+ --paraformer ./sherpa-onnx-paraformer-zh-2023-03-28/model.int8.onnx \
+ --tokens ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt \
+ --model-type paraformer \
+ ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ 2023/08/10 15:07:10.745412 Reading ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav
+ 2023/08/10 15:07:10.758414 Initializing recognizer (may take several seconds)
+ 2023/08/10 15:07:13.992424 Recognizer created!
+ 2023/08/10 15:07:13.992441 Start decoding!
+ 2023/08/10 15:07:14.382157 Decoding done!
+ 2023/08/10 15:07:14.382847 对我做了介绍啊那么我想说的是呢大家如果对我的研究感兴趣呢你
+ 2023/08/10 15:07:14.382898 Wave duration: 5.614625 seconds
+
+Non-streaming CTC model from NeMo
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`stt-en-conformer-ctc-medium-nemo-sherpa-onnx` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/go-api-examples/non-streaming-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+ tar xvf sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+ rm sherpa-onnx-nemo-ctc-en-conformer-medium.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ ./non-streaming-decode-files \
+ --nemo-ctc ./sherpa-onnx-nemo-ctc-en-conformer-medium/model.onnx \
+ --tokens ./sherpa-onnx-nemo-ctc-en-conformer-medium/tokens.txt \
+ --model-type nemo_ctc \
+ ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/0.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ 2023/08/10 15:11:48.667693 Reading ./sherpa-onnx-nemo-ctc-en-conformer-medium/test_wavs/0.wav
+ 2023/08/10 15:11:48.680855 Initializing recognizer (may take several seconds)
+ 2023/08/10 15:11:51.900852 Recognizer created!
+ 2023/08/10 15:11:51.900869 Start decoding!
+ 2023/08/10 15:11:52.125605 Decoding done!
+ 2023/08/10 15:11:52.125630 after early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels
+ 2023/08/10 15:11:52.125645 Wave duration: 6.625 seconds
+
+Decode files with streaming models
+----------------------------------
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/go-api-examples/streaming-decode-files
+ go mod tidy
+ go build
+ ./streaming-decode-files --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ Usage of ./streaming-decode-files:
+ --debug int Whether to show debug message
+ --decoder string Path to the decoder model
+ --decoding-method string Decoding method. Possible values: greedy_search, modified_beam_search (default "greedy_search")
+ --encoder string Path to the encoder model
+ --joiner string Path to the joiner model
+ --max-active-paths int Used only when --decoding-method is modified_beam_search (default 4)
+ --model-type string Optional. Used for loading the model in a faster way
+ --num-threads int Number of threads for computing (default 1)
+ --provider string Provider to use (default "cpu")
+ --tokens string Path to the tokens file
+ pflag: help requested
+
+.. note::
+
+ If you are using Windows and don't see any output after running ``./streaming-decode-files --help``,
+ please copy ``*.dll`` from ``_ (for Win64)
+ or ``_ (for Win32)
+ to the directory ``sherpa-onnx/go-api-examples/streaming-decode-files``.
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a streaming model.
+
+We give one example below for demonstration.
+
+Streaming transducer
+^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-streaming-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/go-api-examples/streaming-decode-files
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ ./streaming-decode-files \
+ --encoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/encoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --decoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/decoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --joiner ./sherpa-onnx-streaming-zipformer-en-2023-06-26/joiner-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --tokens ./sherpa-onnx-streaming-zipformer-en-2023-06-26/tokens.txt \
+ --model-type zipformer2 \
+ ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/0.wav
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ 2023/08/10 15:17:00.226228 Reading ./sherpa-onnx-streaming-zipformer-en-2023-06-26/test_wavs/0.wav
+ 2023/08/10 15:17:00.241024 Initializing recognizer (may take several seconds)
+ 2023/08/10 15:17:03.352697 Recognizer created!
+ 2023/08/10 15:17:03.352711 Start decoding!
+ 2023/08/10 15:17:04.057130 Decoding done!
+ 2023/08/10 15:17:04.057215 after early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels
+ 2023/08/10 15:17:04.057235 Wave duration: 6.625 seconds
+
+Real-time speech recognition from microphone
+--------------------------------------------
+
+.. hint::
+
+ You need to install ``portaudio`` for this example.
+
+ .. code-block:: bash
+
+ # for macOS
+ brew install portaudio
+ export PKG_CONFIG_PATH=/usr/local/Cellar/portaudio/19.7.0
+
+ # for Ubuntu
+ sudo apt-get install libasound-dev portaudio19-dev libportaudio2 libportaudiocpp0
+
+ To check that you have installed ``portaudio`` successfully, please run:
+
+ .. code-block:: bash
+
+ pkg-config --cflags --libs portaudio-2.0
+
+ It should give you something like below:
+
+ .. code-block:: bash
+
+ # for macOS
+ -I/usr/local/Cellar/portaudio/19.7.0/include -L/usr/local/Cellar/portaudio/19.7.0/lib -lportaudio -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework CoreFoundation -framework CoreServices
+
+ # for Ubuntu
+ -pthread -lportaudio -lasound -lm -lpthread
+
+
+First, let us build the example:
+
+.. code-block:: bash
+
+ git clone https://github.com/k2-fsa/sherpa-onnx
+ cd sherpa-onnx/go-api-examples/real-time-speech-recognition-from-microphone
+ go mod tidy
+ go build
+ ./real-time-speech-recognition-from-microphone --help
+
+You will find the following output:
+
+.. code-block:: bash
+
+ Select default input device: MacBook Pro Microphone
+ Usage of ./real-time-speech-recognition-from-microphone:
+ --debug int Whether to show debug message
+ --decoder string Path to the decoder model
+ --decoding-method string Decoding method. Possible values: greedy_search, modified_beam_search (default "greedy_search")
+ --enable-endpoint int Whether to enable endpoint (default 1)
+ --encoder string Path to the encoder model
+ --joiner string Path to the joiner model
+ --max-active-paths int Used only when --decoding-method is modified_beam_search (default 4)
+ --model-type string Optional. Used for loading the model in a faster way
+ --num-threads int Number of threads for computing (default 1)
+ --provider string Provider to use (default "cpu")
+ --rule1-min-trailing-silence float32 Threshold for rule1 (default 2.4)
+ --rule2-min-trailing-silence float32 Threshold for rule2 (default 1.2)
+ --rule3-min-utterance-length float32 Threshold for rule3 (default 20)
+ --tokens string Path to the tokens file
+ pflag: help requested
+
+Now let us refer to :ref:`sherpa-onnx-pre-trained-models` to download a streaming model.
+
+We give one example below for demonstration.
+
+Streaming transducer
+^^^^^^^^^^^^^^^^^^^^
+
+We will use :ref:`sherpa-onnx-streaming-zipformer-en-2023-06-26-english` as an example.
+
+First, let us download it:
+
+.. code-block:: bash
+
+ cd sherpa-onnx/go-api-examples/real-time-speech-recognition-from-microphone
+ wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+ rm sherpa-onnx-streaming-zipformer-en-2023-06-26.tar.bz2
+
+Now we can use:
+
+.. code-block:: bash
+
+ ./real-time-speech-recognition-from-microphone \
+ --encoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/encoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --decoder ./sherpa-onnx-streaming-zipformer-en-2023-06-26/decoder-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --joiner ./sherpa-onnx-streaming-zipformer-en-2023-06-26/joiner-epoch-99-avg-1-chunk-16-left-128.onnx \
+ --tokens ./sherpa-onnx-streaming-zipformer-en-2023-06-26/tokens.txt \
+ --model-type zipformer2
+
+It should give you the following output:
+
+.. code-block:: bash
+
+ Select default input device: MacBook Pro Microphone
+ 2023/08/10 15:22:00 Initializing recognizer (may take several seconds)
+ 2023/08/10 15:22:03 Recognizer created!
+ Started! Please speak
+ 0: this is the first test
+ 1: this is the second
+
+colab
+-----
+
+We provide a colab notebook
+|Sherpa-onnx go api example colab notebook|
+for you to try the `Go`_ API examples of `sherpa-onnx`_.
+
+.. |Sherpa-onnx go api example colab notebook| image:: https://colab.research.google.com/assets/colab-badge.svg
+ :target: https://github.com/k2-fsa/colab/blob/master/sherpa-onnx/sherpa_onnx_go_api_example.ipynb
diff --git a/docs/source/onnx/harmony-os/how-to-build-har.rst b/docs/source/onnx/harmony-os/how-to-build-har.rst
new file mode 100644
index 000000000..f12a300cd
--- /dev/null
+++ b/docs/source/onnx/harmony-os/how-to-build-har.rst
@@ -0,0 +1,181 @@
+How to build sherpa_onnx.har
+============================
+
+This page describes how to build ``sherpa_onnx.har`` from source.
+
+Note that we have already published `sherpa-onnx`_ at the following address:
+
+ ``_
+
+.. figure:: ./pic/ohpm-package.jpg
+ :alt: Screenshot of the ohpm package
+ :width: 600
+
+ The `sherpa_onnx `_ package.
+
+You can use it directly in your project by modifying ``oh-package.json5`` to add
+the following lines:
+
+.. code-block::
+
+ "dependencies": {
+ // please always use the latest version
+ "sherpa_onnx": "1.10.33",
+ },
+
+or use:
+
+.. code-block::
+
+ ohpm install sherpa_onnx
+
+.. hint::
+
+ If you don't want to change any C++ code of `sherpa-onnx`_, then please
+ use our provided ``sherpa_onnx.har`` package and you can safely ignore this
+ document.
+
+.. hint::
+
+ If you don't want to change any C++ code of `sherpa-onnx`_, then please
+ use our provided ``sherpa_onnx.har`` package and you can safely ignore this
+ document.
+
+.. hint::
+
+ If you don't want to change any C++ code of `sherpa-onnx`_, then please
+ use our provided ``sherpa_onnx.har`` package and you can safely ignore this
+ document.
+
+If you want to modify the source code of `sherpa-onnx`_, then you can follow
+this document to build a new ``sherpa_onnx.har`` package.
+
+Download commandline-tools
+--------------------------
+
+The first step is to download commandline tools for building `sherpa-onnx`_.
+
+Please visit `