Repository: PaddlePaddle/PaddleSpeech Branch: develop Commit: 3afe871a8768 Files: 3420 Total size: 15.9 MB Directory structure: gitextract_h_rw1s1r/ ├── .clang-format ├── .flake8 ├── .gitconfig ├── .github/ │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report-s2t.md │ │ ├── bug-report-tts.md │ │ ├── feature-request.md │ │ ├── others.md │ │ └── question.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── stale.yml ├── .gitignore ├── .mergify.yml ├── .pre-commit-config.yaml ├── .pre-commit-hooks/ │ ├── clang-format.hook │ └── copyright-check.hook ├── .readthedocs.yml ├── .style.yapf ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── README.md ├── README_cn.md ├── audio/ │ ├── CMakeLists.txt │ ├── README.md │ ├── cmake/ │ │ ├── FindGFortranLibs.cmake │ │ ├── external/ │ │ │ └── openblas.cmake │ │ ├── pybind.cmake │ │ └── summary.cmake │ ├── paddleaudio/ │ │ ├── CMakeLists.txt │ │ ├── __init__.py │ │ ├── _extension.py │ │ ├── _internal/ │ │ │ ├── __init__.py │ │ │ └── module_utils.py │ │ ├── backends/ │ │ │ ├── __init__.py │ │ │ ├── common.py │ │ │ ├── no_backend.py │ │ │ ├── soundfile_backend.py │ │ │ ├── sox_io_backend.py │ │ │ └── utils.py │ │ ├── compliance/ │ │ │ ├── __init__.py │ │ │ ├── kaldi.py │ │ │ └── librosa.py │ │ ├── datasets/ │ │ │ ├── __init__.py │ │ │ ├── dataset.py │ │ │ ├── esc50.py │ │ │ ├── gtzan.py │ │ │ ├── hey_snips.py │ │ │ ├── rirs_noises.py │ │ │ ├── tess.py │ │ │ ├── urban_sound.py │ │ │ └── voxceleb.py │ │ ├── features/ │ │ │ ├── __init__.py │ │ │ └── layers.py │ │ ├── functional/ │ │ │ ├── __init__.py │ │ │ ├── functional.py │ │ │ └── window.py │ │ ├── kaldi/ │ │ │ ├── __init__.py │ │ │ └── kaldi.py │ │ ├── metric/ │ │ │ ├── __init__.py │ │ │ └── eer.py │ │ ├── sox_effects/ │ │ │ ├── __init__.py │ │ │ └── sox_effects.py │ │ ├── src/ │ │ │ ├── CMakeLists.txt │ │ │ ├── optional/ │ │ │ │ ├── COPYING │ │ │ │ └── optional.hpp │ │ │ ├── pybind/ │ │ │ │ ├── kaldi/ │ │ │ │ │ ├── feature_common.h │ │ │ │ │ ├── feature_common_inl.h │ │ │ │ │ ├── kaldi_feature.cc │ │ │ │ │ ├── kaldi_feature.h │ │ │ │ │ ├── kaldi_feature_wrapper.cc │ │ │ │ │ └── kaldi_feature_wrapper.h │ │ │ │ ├── pybind.cpp │ │ │ │ └── sox/ │ │ │ │ ├── effects.cpp │ │ │ │ ├── effects.h │ │ │ │ ├── effects_chain.cpp │ │ │ │ ├── effects_chain.h │ │ │ │ ├── io.cpp │ │ │ │ ├── io.h │ │ │ │ ├── types.cpp │ │ │ │ ├── types.h │ │ │ │ ├── utils.cpp │ │ │ │ └── utils.h │ │ │ └── utils.cpp │ │ ├── third_party/ │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ ├── kaldi-native-fbank/ │ │ │ │ └── csrc/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── feature-fbank.cc │ │ │ │ ├── feature-fbank.h │ │ │ │ ├── feature-functions.cc │ │ │ │ ├── feature-functions.h │ │ │ │ ├── feature-window.cc │ │ │ │ ├── feature-window.h │ │ │ │ ├── fftsg.c │ │ │ │ ├── log.cc │ │ │ │ ├── log.h │ │ │ │ ├── mel-computations.cc │ │ │ │ ├── mel-computations.h │ │ │ │ ├── rfft.cc │ │ │ │ └── rfft.h │ │ │ ├── patches/ │ │ │ │ ├── config.guess │ │ │ │ ├── config.sub │ │ │ │ ├── libmad.patch │ │ │ │ └── sox.patch │ │ │ └── sox/ │ │ │ └── CMakeLists.txt │ │ └── utils/ │ │ ├── __init__.py │ │ ├── download.py │ │ ├── env.py │ │ ├── error.py │ │ ├── log.py │ │ ├── numeric.py │ │ ├── sox_utils.py │ │ ├── tensor_utils.py │ │ └── time.py │ ├── setup.py │ ├── tests/ │ │ ├── backends/ │ │ │ ├── base.py │ │ │ ├── common.py │ │ │ ├── soundfile/ │ │ │ │ ├── base.py │ │ │ │ ├── common.py │ │ │ │ ├── info_test.py │ │ │ │ ├── load_test.py │ │ │ │ ├── save_test.py │ │ │ │ └── test_io.py │ │ │ └── sox_io/ │ │ │ ├── common.py │ │ │ ├── info_test.py │ │ │ ├── load_test.py │ │ │ ├── save_test.py │ │ │ ├── smoke_test.py │ │ │ ├── sox_effect_test.py │ │ │ └── sox_effect_test_args.jsonl │ │ ├── benchmark/ │ │ │ ├── README.md │ │ │ ├── log_melspectrogram.py │ │ │ ├── melspectrogram.py │ │ │ └── mfcc.py │ │ ├── common_utils/ │ │ │ ├── __init__.py │ │ │ ├── case_utils.py │ │ │ ├── data_utils.py │ │ │ ├── parameterized_utils.py │ │ │ ├── sox_utils.py │ │ │ └── wav_utils.py │ │ └── features/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── test_istft.py │ │ ├── test_kaldi.py │ │ ├── test_kaldi_feat.py │ │ ├── test_librosa.py │ │ ├── test_log_melspectrogram.py │ │ ├── test_spectrogram.py │ │ ├── test_stft.py │ │ └── testdata/ │ │ ├── fbank_feat.ark │ │ ├── fbank_feat_txt.ark │ │ ├── pitch_feat.ark │ │ └── pitch_feat_txt.ark │ └── tools/ │ └── setup_helpers/ │ ├── __init__.py │ └── extension.py ├── dataset/ │ ├── aishell/ │ │ ├── .gitignore │ │ └── aishell.py │ ├── aishell3/ │ │ └── README.md │ ├── chime3_background/ │ │ └── chime3_background.py │ ├── gigaspeech/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── gigaspeech.py │ │ └── run.sh │ ├── librispeech/ │ │ ├── .gitignore │ │ └── librispeech.py │ ├── magicdata/ │ │ └── README.md │ ├── mini_librispeech/ │ │ ├── .gitignore │ │ └── mini_librispeech.py │ ├── multi_cn/ │ │ └── README.md │ ├── primewords/ │ │ └── README.md │ ├── rir_noise/ │ │ ├── .gitignore │ │ └── rir_noise.py │ ├── st-cmds/ │ │ └── README.md │ ├── tal_cs/ │ │ ├── README.md │ │ └── tal_cs.py │ ├── ted_en_zh/ │ │ ├── .gitignore │ │ └── ted_en_zh.py │ ├── thchs30/ │ │ ├── .gitignore │ │ ├── README.md │ │ └── thchs30.py │ ├── timit/ │ │ ├── .gitignore │ │ ├── timit.py │ │ └── timit_kaldi_standard_split.py │ ├── voxceleb/ │ │ ├── README.md │ │ ├── voxceleb1.py │ │ └── voxceleb2.py │ └── voxforge/ │ ├── run_data.sh │ └── voxforge.py ├── demos/ │ ├── README.md │ ├── README_cn.md │ ├── TTSAndroid/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── baidu/ │ │ │ │ └── paddle/ │ │ │ │ └── lite/ │ │ │ │ └── demo/ │ │ │ │ └── tts/ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── baidu/ │ │ │ │ │ └── paddle/ │ │ │ │ │ └── lite/ │ │ │ │ │ └── demo/ │ │ │ │ │ └── tts/ │ │ │ │ │ ├── AppCompatPreferenceActivity.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── Predictor.java │ │ │ │ │ ├── SettingsActivity.java │ │ │ │ │ └── Utils.java │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── button_drawable.xml │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── menu/ │ │ │ │ │ └── menu_action_options.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── arrays.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── xml/ │ │ │ │ └── settings.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── baidu/ │ │ │ └── paddle/ │ │ │ └── lite/ │ │ │ └── demo/ │ │ │ └── tts/ │ │ │ └── ExampleUnitTest.java │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── TTSArmLinux/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.sh │ │ ├── clean.sh │ │ ├── config.sh │ │ ├── download.sh │ │ ├── front.conf │ │ ├── run.sh │ │ └── src/ │ │ ├── CMakeLists.txt │ │ ├── Predictor.hpp │ │ └── main.cc │ ├── TTSCppFrontend/ │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── build-depends.sh │ │ ├── build.sh │ │ ├── clean.sh │ │ ├── download.sh │ │ ├── front_demo/ │ │ │ ├── front.conf │ │ │ ├── front_demo.cpp │ │ │ └── gentools/ │ │ │ ├── gen_dict_paddlespeech.py │ │ │ ├── genid.py │ │ │ └── word2phones.py │ │ ├── run_front_demo.sh │ │ ├── src/ │ │ │ ├── base/ │ │ │ │ ├── type_conv.cpp │ │ │ │ └── type_conv.h │ │ │ └── front/ │ │ │ ├── front_interface.cpp │ │ │ ├── front_interface.h │ │ │ ├── text_normalize.cpp │ │ │ └── text_normalize.h │ │ └── third-party/ │ │ └── CMakeLists.txt │ ├── asr_deployment/ │ │ ├── README.md │ │ └── README_cn.md │ ├── audio_content_search/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── acs_clinet.py │ │ ├── conf/ │ │ │ ├── acs_application.yaml │ │ │ ├── words.txt │ │ │ ├── ws_conformer_application.yaml │ │ │ └── ws_conformer_wenetspeech_application.yaml │ │ ├── requirements.txt │ │ ├── run.sh │ │ └── streaming_asr_server.py │ ├── audio_searching/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── docker-compose.yaml │ │ ├── requirements.txt │ │ └── src/ │ │ ├── audio_search.py │ │ ├── config.py │ │ ├── encode.py │ │ ├── logs.py │ │ ├── milvus_helpers.py │ │ ├── mysql_helpers.py │ │ ├── operations/ │ │ │ ├── __init__.py │ │ │ ├── count.py │ │ │ ├── drop.py │ │ │ ├── load.py │ │ │ └── search.py │ │ ├── test_audio_search.py │ │ ├── test_vpr_search.py │ │ └── vpr_search.py │ ├── audio_tagging/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── automatic_video_subtitiles/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── recognize.py │ │ └── run.sh │ ├── custom_streaming_asr/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── path.sh │ │ ├── setup_docker.sh │ │ ├── websocket_client.sh │ │ └── websocket_server.sh │ ├── keyword_spotting/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── metaverse/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── path.sh │ │ ├── run.sh │ │ └── sentences.txt │ ├── punctuation_restoration/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── speaker_verification/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── speech_recognition/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── speech_server/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── asr_client.sh │ │ ├── cls_client.sh │ │ ├── conf/ │ │ │ ├── application.yaml │ │ │ └── conformer_talcs_application.yaml │ │ ├── server.sh │ │ ├── sid_client.sh │ │ ├── start_multi_progress_server.py │ │ ├── text_client.sh │ │ └── tts_client.sh │ ├── speech_ssl/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── speech_translation/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ ├── speech_web/ │ │ ├── .gitignore │ │ ├── API.md │ │ ├── README.md │ │ ├── speech_server/ │ │ │ ├── conf/ │ │ │ │ ├── tts3_finetune.yaml │ │ │ │ ├── tts_online_application.yaml │ │ │ │ └── ws_conformer_wenetspeech_application_faster.yaml │ │ │ ├── main.py │ │ │ ├── requirements.txt │ │ │ ├── src/ │ │ │ │ ├── AudioManeger.py │ │ │ │ ├── SpeechBase/ │ │ │ │ │ ├── asr.py │ │ │ │ │ ├── nlp.py │ │ │ │ │ ├── sql_helper.py │ │ │ │ │ ├── tts.py │ │ │ │ │ ├── vpr.py │ │ │ │ │ └── vpr_encode.py │ │ │ │ ├── WebsocketManeger.py │ │ │ │ ├── ernie_sat.py │ │ │ │ ├── finetune.py │ │ │ │ ├── ge2e_clone.py │ │ │ │ ├── robot.py │ │ │ │ ├── tdnn_clone.py │ │ │ │ └── util.py │ │ │ └── vc.py │ │ └── web_client/ │ │ ├── .gitignore │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── api/ │ │ │ │ ├── API.js │ │ │ │ ├── ApiASR.js │ │ │ │ ├── ApiNLP.js │ │ │ │ ├── ApiTTS.js │ │ │ │ ├── ApiVC.js │ │ │ │ └── ApiVPR.js │ │ │ ├── components/ │ │ │ │ ├── Content/ │ │ │ │ │ ├── Header/ │ │ │ │ │ │ ├── Header.vue │ │ │ │ │ │ └── style.less │ │ │ │ │ └── Tail/ │ │ │ │ │ ├── Tail.vue │ │ │ │ │ └── style.less │ │ │ │ ├── Experience.vue │ │ │ │ ├── SubMenu/ │ │ │ │ │ ├── ASR/ │ │ │ │ │ │ ├── ASR.vue │ │ │ │ │ │ ├── ASRT.vue │ │ │ │ │ │ ├── AudioFile/ │ │ │ │ │ │ │ ├── AudioFileIdentification.vue │ │ │ │ │ │ │ └── style.less │ │ │ │ │ │ ├── EndToEnd/ │ │ │ │ │ │ │ ├── EndToEndIdentification.vue │ │ │ │ │ │ │ └── style.less │ │ │ │ │ │ ├── RealTime/ │ │ │ │ │ │ │ ├── RealTime.vue │ │ │ │ │ │ │ └── style.less │ │ │ │ │ │ └── style.less │ │ │ │ │ ├── ChatBot/ │ │ │ │ │ │ ├── ChatT.vue │ │ │ │ │ │ └── style.less │ │ │ │ │ ├── ERNIE_SAT/ │ │ │ │ │ │ └── ERNIE_SAT.vue │ │ │ │ │ ├── FineTune/ │ │ │ │ │ │ └── FineTune.vue │ │ │ │ │ ├── IE/ │ │ │ │ │ │ ├── IET.vue │ │ │ │ │ │ └── style.less │ │ │ │ │ ├── TTS/ │ │ │ │ │ │ ├── TTST.vue │ │ │ │ │ │ └── style.less │ │ │ │ │ ├── VPR/ │ │ │ │ │ │ ├── VPRT.vue │ │ │ │ │ │ └── style.less │ │ │ │ │ └── VoiceClone/ │ │ │ │ │ └── VoiceClone.vue │ │ │ │ └── style.less │ │ │ └── main.js │ │ └── vite.config.js │ ├── story_talker/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── ocr.py │ │ ├── path.sh │ │ └── run.sh │ ├── streaming_asr_server/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── conf/ │ │ │ ├── application.yaml │ │ │ ├── punc_application.yaml │ │ │ ├── ws_conformer_application.yaml │ │ │ ├── ws_conformer_talcs_application.yaml │ │ │ ├── ws_conformer_wenetspeech_application.yaml │ │ │ ├── ws_conformer_wenetspeech_application_faster.yaml │ │ │ └── ws_ds2_application.yaml │ │ ├── local/ │ │ │ ├── punc_server.py │ │ │ ├── rtf_from_log.py │ │ │ ├── streaming_asr_server.py │ │ │ ├── test.sh │ │ │ ├── websocket_client.py │ │ │ └── websocket_client_srt.py │ │ ├── run.sh │ │ ├── server.sh │ │ ├── test.sh │ │ └── web/ │ │ ├── index.html │ │ └── readme.md │ ├── streaming_tts_server/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── client.sh │ │ ├── conf/ │ │ │ ├── tts_online_application.yaml │ │ │ └── tts_online_ws_application.yaml │ │ └── server.sh │ ├── streaming_tts_serving_fastdeploy/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── streaming_tts_serving/ │ │ ├── 1/ │ │ │ └── model.py │ │ ├── config.pbtxt │ │ └── stream_client.py │ ├── style_fs2/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── path.sh │ │ ├── run.sh │ │ ├── sentences.txt │ │ └── style_syn.py │ ├── text_to_speech/ │ │ ├── README.md │ │ ├── README_cn.md │ │ └── run.sh │ └── whisper/ │ ├── README.md │ ├── README_cn.md │ └── run.sh ├── docker/ │ ├── ubuntu16-gpu/ │ │ └── Dockerfile │ ├── ubuntu18-cpu/ │ │ └── Dockerfile │ └── ubuntu20-cpu/ │ └── Dockerfile ├── docs/ │ ├── Makefile │ ├── requirements.txt │ ├── source/ │ │ ├── _static/ │ │ │ └── custom.css │ │ ├── api/ │ │ │ ├── modules.rst │ │ │ ├── paddlespeech.audio.features.layers.rst │ │ │ ├── paddlespeech.audio.features.rst │ │ │ ├── paddlespeech.audio.io.rst │ │ │ ├── paddlespeech.audio.rst │ │ │ ├── paddlespeech.audio.streamdata.autodecode.rst │ │ │ ├── paddlespeech.audio.streamdata.cache.rst │ │ │ ├── paddlespeech.audio.streamdata.compat.rst │ │ │ ├── paddlespeech.audio.streamdata.extradatasets.rst │ │ │ ├── paddlespeech.audio.streamdata.filters.rst │ │ │ ├── paddlespeech.audio.streamdata.gopen.rst │ │ │ ├── paddlespeech.audio.streamdata.handlers.rst │ │ │ ├── paddlespeech.audio.streamdata.mix.rst │ │ │ ├── paddlespeech.audio.streamdata.paddle_utils.rst │ │ │ ├── paddlespeech.audio.streamdata.pipeline.rst │ │ │ ├── paddlespeech.audio.streamdata.rst │ │ │ ├── paddlespeech.audio.streamdata.shardlists.rst │ │ │ ├── paddlespeech.audio.streamdata.tariterators.rst │ │ │ ├── paddlespeech.audio.streamdata.utils.rst │ │ │ ├── paddlespeech.audio.streamdata.writer.rst │ │ │ ├── paddlespeech.audio.text.rst │ │ │ ├── paddlespeech.audio.text.text_featurizer.rst │ │ │ ├── paddlespeech.audio.text.utility.rst │ │ │ ├── paddlespeech.audio.transform.add_deltas.rst │ │ │ ├── paddlespeech.audio.transform.channel_selector.rst │ │ │ ├── paddlespeech.audio.transform.cmvn.rst │ │ │ ├── paddlespeech.audio.transform.functional.rst │ │ │ ├── paddlespeech.audio.transform.perturb.rst │ │ │ ├── paddlespeech.audio.transform.rst │ │ │ ├── paddlespeech.audio.transform.spec_augment.rst │ │ │ ├── paddlespeech.audio.transform.spectrogram.rst │ │ │ ├── paddlespeech.audio.transform.transform_interface.rst │ │ │ ├── paddlespeech.audio.transform.transformation.rst │ │ │ ├── paddlespeech.audio.transform.wpe.rst │ │ │ ├── paddlespeech.audio.utils.check_kwargs.rst │ │ │ ├── paddlespeech.audio.utils.download.rst │ │ │ ├── paddlespeech.audio.utils.dynamic_import.rst │ │ │ ├── paddlespeech.audio.utils.error.rst │ │ │ ├── paddlespeech.audio.utils.log.rst │ │ │ ├── paddlespeech.audio.utils.numeric.rst │ │ │ ├── paddlespeech.audio.utils.rst │ │ │ ├── paddlespeech.audio.utils.tensor_utils.rst │ │ │ ├── paddlespeech.audio.utils.time.rst │ │ │ ├── paddlespeech.cli.asr.infer.rst │ │ │ ├── paddlespeech.cli.asr.rst │ │ │ ├── paddlespeech.cli.base_commands.rst │ │ │ ├── paddlespeech.cli.cls.infer.rst │ │ │ ├── paddlespeech.cli.cls.rst │ │ │ ├── paddlespeech.cli.download.rst │ │ │ ├── paddlespeech.cli.entry.rst │ │ │ ├── paddlespeech.cli.executor.rst │ │ │ ├── paddlespeech.cli.kws.infer.rst │ │ │ ├── paddlespeech.cli.kws.rst │ │ │ ├── paddlespeech.cli.log.rst │ │ │ ├── paddlespeech.cli.rst │ │ │ ├── paddlespeech.cli.st.infer.rst │ │ │ ├── paddlespeech.cli.st.rst │ │ │ ├── paddlespeech.cli.text.infer.rst │ │ │ ├── paddlespeech.cli.text.rst │ │ │ ├── paddlespeech.cli.tts.infer.rst │ │ │ ├── paddlespeech.cli.tts.rst │ │ │ ├── paddlespeech.cli.utils.rst │ │ │ ├── paddlespeech.cli.vector.infer.rst │ │ │ ├── paddlespeech.cli.vector.rst │ │ │ ├── paddlespeech.cls.exps.panns.deploy.rst │ │ │ ├── paddlespeech.cls.exps.panns.rst │ │ │ ├── paddlespeech.cls.exps.rst │ │ │ ├── paddlespeech.cls.models.panns.classifier.rst │ │ │ ├── paddlespeech.cls.models.panns.panns.rst │ │ │ ├── paddlespeech.cls.models.panns.rst │ │ │ ├── paddlespeech.cls.models.rst │ │ │ ├── paddlespeech.cls.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.collate.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.compute_det.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.plot_det_curve.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.score.rst │ │ │ ├── paddlespeech.kws.exps.mdtc.train.rst │ │ │ ├── paddlespeech.kws.exps.rst │ │ │ ├── paddlespeech.kws.models.loss.rst │ │ │ ├── paddlespeech.kws.models.mdtc.rst │ │ │ ├── paddlespeech.kws.models.rst │ │ │ ├── paddlespeech.kws.rst │ │ │ ├── paddlespeech.resource.model_alias.rst │ │ │ ├── paddlespeech.resource.pretrained_models.rst │ │ │ ├── paddlespeech.resource.resource.rst │ │ │ ├── paddlespeech.resource.rst │ │ │ ├── paddlespeech.rst │ │ │ ├── paddlespeech.s2t.decoders.beam_search.batch_beam_search.rst │ │ │ ├── paddlespeech.s2t.decoders.beam_search.beam_search.rst │ │ │ ├── paddlespeech.s2t.decoders.beam_search.rst │ │ │ ├── paddlespeech.s2t.decoders.ctcdecoder.decoders_deprecated.rst │ │ │ ├── paddlespeech.s2t.decoders.ctcdecoder.rst │ │ │ ├── paddlespeech.s2t.decoders.ctcdecoder.swig_wrapper.rst │ │ │ ├── paddlespeech.s2t.decoders.recog.rst │ │ │ ├── paddlespeech.s2t.decoders.rst │ │ │ ├── paddlespeech.s2t.decoders.scorers.ctc.rst │ │ │ ├── paddlespeech.s2t.decoders.scorers.ctc_prefix_score.rst │ │ │ ├── paddlespeech.s2t.decoders.scorers.length_bonus.rst │ │ │ ├── paddlespeech.s2t.decoders.scorers.rst │ │ │ ├── paddlespeech.s2t.decoders.scorers.scorer_interface.rst │ │ │ ├── paddlespeech.s2t.decoders.utils.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.deploy.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.deploy.runtime.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.deploy.server.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.export.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.test.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.test_export.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.test_wav.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.bin.train.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.model.rst │ │ │ ├── paddlespeech.s2t.exps.deepspeech2.rst │ │ │ ├── paddlespeech.s2t.exps.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.alignment.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.export.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.test.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.test_wav.rst │ │ │ ├── paddlespeech.s2t.exps.u2.bin.train.rst │ │ │ ├── paddlespeech.s2t.exps.u2.model.rst │ │ │ ├── paddlespeech.s2t.exps.u2.rst │ │ │ ├── paddlespeech.s2t.exps.u2_kaldi.bin.rst │ │ │ ├── paddlespeech.s2t.exps.u2_kaldi.bin.test.rst │ │ │ ├── paddlespeech.s2t.exps.u2_kaldi.bin.train.rst │ │ │ ├── paddlespeech.s2t.exps.u2_kaldi.model.rst │ │ │ ├── paddlespeech.s2t.exps.u2_kaldi.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.bin.export.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.bin.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.bin.test.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.bin.train.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.model.rst │ │ │ ├── paddlespeech.s2t.exps.u2_st.rst │ │ │ ├── paddlespeech.s2t.frontend.audio.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.augmentation.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.base.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.impulse_response.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.noise_perturb.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.online_bayesian_normalization.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.resample.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.shift_perturb.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.spec_augment.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.speed_perturb.rst │ │ │ ├── paddlespeech.s2t.frontend.augmentor.volume_perturb.rst │ │ │ ├── paddlespeech.s2t.frontend.featurizer.audio_featurizer.rst │ │ │ ├── paddlespeech.s2t.frontend.featurizer.rst │ │ │ ├── paddlespeech.s2t.frontend.featurizer.speech_featurizer.rst │ │ │ ├── paddlespeech.s2t.frontend.featurizer.text_featurizer.rst │ │ │ ├── paddlespeech.s2t.frontend.normalizer.rst │ │ │ ├── paddlespeech.s2t.frontend.rst │ │ │ ├── paddlespeech.s2t.frontend.speech.rst │ │ │ ├── paddlespeech.s2t.frontend.utility.rst │ │ │ ├── paddlespeech.s2t.io.batchfy.rst │ │ │ ├── paddlespeech.s2t.io.collator.rst │ │ │ ├── paddlespeech.s2t.io.converter.rst │ │ │ ├── paddlespeech.s2t.io.dataloader.rst │ │ │ ├── paddlespeech.s2t.io.dataset.rst │ │ │ ├── paddlespeech.s2t.io.reader.rst │ │ │ ├── paddlespeech.s2t.io.rst │ │ │ ├── paddlespeech.s2t.io.sampler.rst │ │ │ ├── paddlespeech.s2t.io.utility.rst │ │ │ ├── paddlespeech.s2t.models.asr_interface.rst │ │ │ ├── paddlespeech.s2t.models.ds2.conv.rst │ │ │ ├── paddlespeech.s2t.models.ds2.deepspeech2.rst │ │ │ ├── paddlespeech.s2t.models.ds2.rst │ │ │ ├── paddlespeech.s2t.models.lm.dataset.rst │ │ │ ├── paddlespeech.s2t.models.lm.rst │ │ │ ├── paddlespeech.s2t.models.lm.transformer.rst │ │ │ ├── paddlespeech.s2t.models.lm_interface.rst │ │ │ ├── paddlespeech.s2t.models.rst │ │ │ ├── paddlespeech.s2t.models.st_interface.rst │ │ │ ├── paddlespeech.s2t.models.u2.rst │ │ │ ├── paddlespeech.s2t.models.u2.u2.rst │ │ │ ├── paddlespeech.s2t.models.u2.updater.rst │ │ │ ├── paddlespeech.s2t.models.u2_st.rst │ │ │ ├── paddlespeech.s2t.models.u2_st.u2_st.rst │ │ │ ├── paddlespeech.s2t.modules.activation.rst │ │ │ ├── paddlespeech.s2t.modules.align.rst │ │ │ ├── paddlespeech.s2t.modules.attention.rst │ │ │ ├── paddlespeech.s2t.modules.cmvn.rst │ │ │ ├── paddlespeech.s2t.modules.conformer_convolution.rst │ │ │ ├── paddlespeech.s2t.modules.crf.rst │ │ │ ├── paddlespeech.s2t.modules.ctc.rst │ │ │ ├── paddlespeech.s2t.modules.decoder.rst │ │ │ ├── paddlespeech.s2t.modules.decoder_layer.rst │ │ │ ├── paddlespeech.s2t.modules.embedding.rst │ │ │ ├── paddlespeech.s2t.modules.encoder.rst │ │ │ ├── paddlespeech.s2t.modules.encoder_layer.rst │ │ │ ├── paddlespeech.s2t.modules.initializer.rst │ │ │ ├── paddlespeech.s2t.modules.loss.rst │ │ │ ├── paddlespeech.s2t.modules.mask.rst │ │ │ ├── paddlespeech.s2t.modules.positionwise_feed_forward.rst │ │ │ ├── paddlespeech.s2t.modules.rst │ │ │ ├── paddlespeech.s2t.modules.subsampling.rst │ │ │ ├── paddlespeech.s2t.rst │ │ │ ├── paddlespeech.s2t.training.cli.rst │ │ │ ├── paddlespeech.s2t.training.extensions.evaluator.rst │ │ │ ├── paddlespeech.s2t.training.extensions.extension.rst │ │ │ ├── paddlespeech.s2t.training.extensions.plot.rst │ │ │ ├── paddlespeech.s2t.training.extensions.rst │ │ │ ├── paddlespeech.s2t.training.gradclip.rst │ │ │ ├── paddlespeech.s2t.training.optimizer.rst │ │ │ ├── paddlespeech.s2t.training.reporter.rst │ │ │ ├── paddlespeech.s2t.training.rst │ │ │ ├── paddlespeech.s2t.training.scheduler.rst │ │ │ ├── paddlespeech.s2t.training.timer.rst │ │ │ ├── paddlespeech.s2t.training.trainer.rst │ │ │ ├── paddlespeech.s2t.training.triggers.compare_value_trigger.rst │ │ │ ├── paddlespeech.s2t.training.triggers.interval_trigger.rst │ │ │ ├── paddlespeech.s2t.training.triggers.limit_trigger.rst │ │ │ ├── paddlespeech.s2t.training.triggers.rst │ │ │ ├── paddlespeech.s2t.training.triggers.time_trigger.rst │ │ │ ├── paddlespeech.s2t.training.triggers.utils.rst │ │ │ ├── paddlespeech.s2t.training.updaters.rst │ │ │ ├── paddlespeech.s2t.training.updaters.standard_updater.rst │ │ │ ├── paddlespeech.s2t.training.updaters.updater.rst │ │ │ ├── paddlespeech.s2t.utils.asr_utils.rst │ │ │ ├── paddlespeech.s2t.utils.bleu_score.rst │ │ │ ├── paddlespeech.s2t.utils.check_kwargs.rst │ │ │ ├── paddlespeech.s2t.utils.checkpoint.rst │ │ │ ├── paddlespeech.s2t.utils.cli_readers.rst │ │ │ ├── paddlespeech.s2t.utils.cli_utils.rst │ │ │ ├── paddlespeech.s2t.utils.cli_writers.rst │ │ │ ├── paddlespeech.s2t.utils.ctc_utils.rst │ │ │ ├── paddlespeech.s2t.utils.dynamic_import.rst │ │ │ ├── paddlespeech.s2t.utils.dynamic_pip_install.rst │ │ │ ├── paddlespeech.s2t.utils.error_rate.rst │ │ │ ├── paddlespeech.s2t.utils.layer_tools.rst │ │ │ ├── paddlespeech.s2t.utils.log.rst │ │ │ ├── paddlespeech.s2t.utils.mp_tools.rst │ │ │ ├── paddlespeech.s2t.utils.profiler.rst │ │ │ ├── paddlespeech.s2t.utils.rst │ │ │ ├── paddlespeech.s2t.utils.socket_server.rst │ │ │ ├── paddlespeech.s2t.utils.spec_augment.rst │ │ │ ├── paddlespeech.s2t.utils.tensor_utils.rst │ │ │ ├── paddlespeech.s2t.utils.text_grid.rst │ │ │ ├── paddlespeech.s2t.utils.utility.rst │ │ │ ├── paddlespeech.server.base_commands.rst │ │ │ ├── paddlespeech.server.bin.paddlespeech_client.rst │ │ │ ├── paddlespeech.server.bin.paddlespeech_server.rst │ │ │ ├── paddlespeech.server.bin.rst │ │ │ ├── paddlespeech.server.engine.acs.python.rst │ │ │ ├── paddlespeech.server.engine.acs.rst │ │ │ ├── paddlespeech.server.engine.asr.online.ctc_endpoint.rst │ │ │ ├── paddlespeech.server.engine.asr.online.ctc_search.rst │ │ │ ├── paddlespeech.server.engine.asr.online.onnx.asr_engine.rst │ │ │ ├── paddlespeech.server.engine.asr.online.onnx.rst │ │ │ ├── paddlespeech.server.engine.asr.online.paddleinference.asr_engine.rst │ │ │ ├── paddlespeech.server.engine.asr.online.paddleinference.rst │ │ │ ├── paddlespeech.server.engine.asr.online.python.asr_engine.rst │ │ │ ├── paddlespeech.server.engine.asr.online.python.rst │ │ │ ├── paddlespeech.server.engine.asr.online.rst │ │ │ ├── paddlespeech.server.engine.asr.paddleinference.asr_engine.rst │ │ │ ├── paddlespeech.server.engine.asr.paddleinference.rst │ │ │ ├── paddlespeech.server.engine.asr.python.asr_engine.rst │ │ │ ├── paddlespeech.server.engine.asr.python.rst │ │ │ ├── paddlespeech.server.engine.asr.rst │ │ │ ├── paddlespeech.server.engine.base_engine.rst │ │ │ ├── paddlespeech.server.engine.cls.paddleinference.cls_engine.rst │ │ │ ├── paddlespeech.server.engine.cls.paddleinference.rst │ │ │ ├── paddlespeech.server.engine.cls.python.cls_engine.rst │ │ │ ├── paddlespeech.server.engine.cls.python.rst │ │ │ ├── paddlespeech.server.engine.cls.rst │ │ │ ├── paddlespeech.server.engine.engine_factory.rst │ │ │ ├── paddlespeech.server.engine.engine_pool.rst │ │ │ ├── paddlespeech.server.engine.engine_warmup.rst │ │ │ ├── paddlespeech.server.engine.rst │ │ │ ├── paddlespeech.server.engine.text.python.rst │ │ │ ├── paddlespeech.server.engine.text.python.text_engine.rst │ │ │ ├── paddlespeech.server.engine.text.rst │ │ │ ├── paddlespeech.server.engine.tts.online.onnx.rst │ │ │ ├── paddlespeech.server.engine.tts.online.onnx.tts_engine.rst │ │ │ ├── paddlespeech.server.engine.tts.online.python.rst │ │ │ ├── paddlespeech.server.engine.tts.online.python.tts_engine.rst │ │ │ ├── paddlespeech.server.engine.tts.online.rst │ │ │ ├── paddlespeech.server.engine.tts.paddleinference.rst │ │ │ ├── paddlespeech.server.engine.tts.paddleinference.tts_engine.rst │ │ │ ├── paddlespeech.server.engine.tts.python.rst │ │ │ ├── paddlespeech.server.engine.tts.python.tts_engine.rst │ │ │ ├── paddlespeech.server.engine.tts.rst │ │ │ ├── paddlespeech.server.engine.vector.python.rst │ │ │ ├── paddlespeech.server.engine.vector.python.vector_engine.rst │ │ │ ├── paddlespeech.server.engine.vector.rst │ │ │ ├── paddlespeech.server.entry.rst │ │ │ ├── paddlespeech.server.executor.rst │ │ │ ├── paddlespeech.server.restful.acs_api.rst │ │ │ ├── paddlespeech.server.restful.api.rst │ │ │ ├── paddlespeech.server.restful.asr_api.rst │ │ │ ├── paddlespeech.server.restful.cls_api.rst │ │ │ ├── paddlespeech.server.restful.request.rst │ │ │ ├── paddlespeech.server.restful.response.rst │ │ │ ├── paddlespeech.server.restful.rst │ │ │ ├── paddlespeech.server.restful.text_api.rst │ │ │ ├── paddlespeech.server.restful.tts_api.rst │ │ │ ├── paddlespeech.server.restful.vector_api.rst │ │ │ ├── paddlespeech.server.rst │ │ │ ├── paddlespeech.server.tests.asr.offline.http_client.rst │ │ │ ├── paddlespeech.server.tests.asr.offline.rst │ │ │ ├── paddlespeech.server.tests.asr.rst │ │ │ ├── paddlespeech.server.tests.rst │ │ │ ├── paddlespeech.server.util.rst │ │ │ ├── paddlespeech.server.utils.audio_handler.rst │ │ │ ├── paddlespeech.server.utils.audio_process.rst │ │ │ ├── paddlespeech.server.utils.buffer.rst │ │ │ ├── paddlespeech.server.utils.config.rst │ │ │ ├── paddlespeech.server.utils.errors.rst │ │ │ ├── paddlespeech.server.utils.exception.rst │ │ │ ├── paddlespeech.server.utils.onnx_infer.rst │ │ │ ├── paddlespeech.server.utils.paddle_predictor.rst │ │ │ ├── paddlespeech.server.utils.rst │ │ │ ├── paddlespeech.server.utils.util.rst │ │ │ ├── paddlespeech.server.utils.vad.rst │ │ │ ├── paddlespeech.server.ws.api.rst │ │ │ ├── paddlespeech.server.ws.asr_api.rst │ │ │ ├── paddlespeech.server.ws.rst │ │ │ ├── paddlespeech.server.ws.tts_api.rst │ │ │ ├── paddlespeech.t2s.audio.audio.rst │ │ │ ├── paddlespeech.t2s.audio.codec.rst │ │ │ ├── paddlespeech.t2s.audio.rst │ │ │ ├── paddlespeech.t2s.audio.spec_normalizer.rst │ │ │ ├── paddlespeech.t2s.datasets.am_batch_fn.rst │ │ │ ├── paddlespeech.t2s.datasets.batch.rst │ │ │ ├── paddlespeech.t2s.datasets.data_table.rst │ │ │ ├── paddlespeech.t2s.datasets.dataset.rst │ │ │ ├── paddlespeech.t2s.datasets.get_feats.rst │ │ │ ├── paddlespeech.t2s.datasets.ljspeech.rst │ │ │ ├── paddlespeech.t2s.datasets.preprocess_utils.rst │ │ │ ├── paddlespeech.t2s.datasets.rst │ │ │ ├── paddlespeech.t2s.datasets.sampler.rst │ │ │ ├── paddlespeech.t2s.datasets.vocoder_batch_fn.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.align.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.synthesize_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.train.rst │ │ │ ├── paddlespeech.t2s.exps.ernie_sat.utils.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.gen_gta_mel.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.train.rst │ │ │ ├── paddlespeech.t2s.exps.fastspeech2.vc2_infer.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.hifigan.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.hifigan.train.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.multi_band_melgan.train.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.parallelwave_gan.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.parallelwave_gan.synthesize_from_wav.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.parallelwave_gan.train.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.style_melgan.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.style_melgan.train.rst │ │ │ ├── paddlespeech.t2s.exps.gan_vocoder.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.inference.rst │ │ │ ├── paddlespeech.t2s.exps.inference_streaming.rst │ │ │ ├── paddlespeech.t2s.exps.ort_predict.rst │ │ │ ├── paddlespeech.t2s.exps.ort_predict_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.ort_predict_streaming.rst │ │ │ ├── paddlespeech.t2s.exps.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.gen_gta_mel.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.inference.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.synthesize_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.speedyspeech.train.rst │ │ │ ├── paddlespeech.t2s.exps.stream_play_tts.rst │ │ │ ├── paddlespeech.t2s.exps.syn_utils.rst │ │ │ ├── paddlespeech.t2s.exps.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.synthesize_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.synthesize_streaming.rst │ │ │ ├── paddlespeech.t2s.exps.tacotron2.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.tacotron2.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.tacotron2.rst │ │ │ ├── paddlespeech.t2s.exps.tacotron2.train.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.synthesize_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.transformer_tts.train.rst │ │ │ ├── paddlespeech.t2s.exps.vits.normalize.rst │ │ │ ├── paddlespeech.t2s.exps.vits.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.vits.rst │ │ │ ├── paddlespeech.t2s.exps.vits.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.vits.synthesize_e2e.rst │ │ │ ├── paddlespeech.t2s.exps.vits.train.rst │ │ │ ├── paddlespeech.t2s.exps.vits.voice_cloning.rst │ │ │ ├── paddlespeech.t2s.exps.voice_cloning.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.config.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.ljspeech.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.preprocess.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.waveflow.train.rst │ │ │ ├── paddlespeech.t2s.exps.wavernn.rst │ │ │ ├── paddlespeech.t2s.exps.wavernn.synthesize.rst │ │ │ ├── paddlespeech.t2s.exps.wavernn.train.rst │ │ │ ├── paddlespeech.t2s.frontend.arpabet.rst │ │ │ ├── paddlespeech.t2s.frontend.g2pw.dataset.rst │ │ │ ├── paddlespeech.t2s.frontend.g2pw.onnx_api.rst │ │ │ ├── paddlespeech.t2s.frontend.g2pw.rst │ │ │ ├── paddlespeech.t2s.frontend.g2pw.utils.rst │ │ │ ├── paddlespeech.t2s.frontend.generate_lexicon.rst │ │ │ ├── paddlespeech.t2s.frontend.mix_frontend.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.abbrrviation.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.acronyms.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.normalizer.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.numbers.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.rst │ │ │ ├── paddlespeech.t2s.frontend.normalizer.width.rst │ │ │ ├── paddlespeech.t2s.frontend.phonectic.rst │ │ │ ├── paddlespeech.t2s.frontend.punctuation.rst │ │ │ ├── paddlespeech.t2s.frontend.rst │ │ │ ├── paddlespeech.t2s.frontend.tone_sandhi.rst │ │ │ ├── paddlespeech.t2s.frontend.vocab.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_frontend.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.char_convert.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.chronology.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.constants.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.num.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.phonecode.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.quantifier.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.rst │ │ │ ├── paddlespeech.t2s.frontend.zh_normalization.text_normlization.rst │ │ │ ├── paddlespeech.t2s.models.ernie_sat.ernie_sat.rst │ │ │ ├── paddlespeech.t2s.models.ernie_sat.ernie_sat_updater.rst │ │ │ ├── paddlespeech.t2s.models.ernie_sat.rst │ │ │ ├── paddlespeech.t2s.models.fastspeech2.fastspeech2.rst │ │ │ ├── paddlespeech.t2s.models.fastspeech2.fastspeech2_updater.rst │ │ │ ├── paddlespeech.t2s.models.fastspeech2.rst │ │ │ ├── paddlespeech.t2s.models.hifigan.hifigan.rst │ │ │ ├── paddlespeech.t2s.models.hifigan.hifigan_updater.rst │ │ │ ├── paddlespeech.t2s.models.hifigan.rst │ │ │ ├── paddlespeech.t2s.models.melgan.melgan.rst │ │ │ ├── paddlespeech.t2s.models.melgan.multi_band_melgan_updater.rst │ │ │ ├── paddlespeech.t2s.models.melgan.rst │ │ │ ├── paddlespeech.t2s.models.melgan.style_melgan.rst │ │ │ ├── paddlespeech.t2s.models.melgan.style_melgan_updater.rst │ │ │ ├── paddlespeech.t2s.models.parallel_wavegan.parallel_wavegan.rst │ │ │ ├── paddlespeech.t2s.models.parallel_wavegan.parallel_wavegan_updater.rst │ │ │ ├── paddlespeech.t2s.models.parallel_wavegan.rst │ │ │ ├── paddlespeech.t2s.models.rst │ │ │ ├── paddlespeech.t2s.models.speedyspeech.rst │ │ │ ├── paddlespeech.t2s.models.speedyspeech.speedyspeech.rst │ │ │ ├── paddlespeech.t2s.models.speedyspeech.speedyspeech_updater.rst │ │ │ ├── paddlespeech.t2s.models.tacotron2.rst │ │ │ ├── paddlespeech.t2s.models.tacotron2.tacotron2.rst │ │ │ ├── paddlespeech.t2s.models.tacotron2.tacotron2_updater.rst │ │ │ ├── paddlespeech.t2s.models.transformer_tts.rst │ │ │ ├── paddlespeech.t2s.models.transformer_tts.transformer_tts.rst │ │ │ ├── paddlespeech.t2s.models.transformer_tts.transformer_tts_updater.rst │ │ │ ├── paddlespeech.t2s.models.vits.duration_predictor.rst │ │ │ ├── paddlespeech.t2s.models.vits.flow.rst │ │ │ ├── paddlespeech.t2s.models.vits.generator.rst │ │ │ ├── paddlespeech.t2s.models.vits.monotonic_align.core.rst │ │ │ ├── paddlespeech.t2s.models.vits.monotonic_align.rst │ │ │ ├── paddlespeech.t2s.models.vits.monotonic_align.setup.rst │ │ │ ├── paddlespeech.t2s.models.vits.posterior_encoder.rst │ │ │ ├── paddlespeech.t2s.models.vits.residual_coupling.rst │ │ │ ├── paddlespeech.t2s.models.vits.rst │ │ │ ├── paddlespeech.t2s.models.vits.text_encoder.rst │ │ │ ├── paddlespeech.t2s.models.vits.transform.rst │ │ │ ├── paddlespeech.t2s.models.vits.vits.rst │ │ │ ├── paddlespeech.t2s.models.vits.vits_updater.rst │ │ │ ├── paddlespeech.t2s.models.vits.wavenet.residual_block.rst │ │ │ ├── paddlespeech.t2s.models.vits.wavenet.rst │ │ │ ├── paddlespeech.t2s.models.vits.wavenet.wavenet.rst │ │ │ ├── paddlespeech.t2s.models.waveflow.rst │ │ │ ├── paddlespeech.t2s.models.wavernn.rst │ │ │ ├── paddlespeech.t2s.models.wavernn.wavernn.rst │ │ │ ├── paddlespeech.t2s.models.wavernn.wavernn_updater.rst │ │ │ ├── paddlespeech.t2s.modules.activation.rst │ │ │ ├── paddlespeech.t2s.modules.causal_conv.rst │ │ │ ├── paddlespeech.t2s.modules.conformer.convolution.rst │ │ │ ├── paddlespeech.t2s.modules.conformer.encoder_layer.rst │ │ │ ├── paddlespeech.t2s.modules.conformer.rst │ │ │ ├── paddlespeech.t2s.modules.conv.rst │ │ │ ├── paddlespeech.t2s.modules.geometry.rst │ │ │ ├── paddlespeech.t2s.modules.layer_norm.rst │ │ │ ├── paddlespeech.t2s.modules.losses.rst │ │ │ ├── paddlespeech.t2s.modules.masked_fill.rst │ │ │ ├── paddlespeech.t2s.modules.nets_utils.rst │ │ │ ├── paddlespeech.t2s.modules.normalizer.rst │ │ │ ├── paddlespeech.t2s.modules.positional_encoding.rst │ │ │ ├── paddlespeech.t2s.modules.pqmf.rst │ │ │ ├── paddlespeech.t2s.modules.predictor.duration_predictor.rst │ │ │ ├── paddlespeech.t2s.modules.predictor.length_regulator.rst │ │ │ ├── paddlespeech.t2s.modules.predictor.rst │ │ │ ├── paddlespeech.t2s.modules.predictor.variance_predictor.rst │ │ │ ├── paddlespeech.t2s.modules.residual_block.rst │ │ │ ├── paddlespeech.t2s.modules.residual_stack.rst │ │ │ ├── paddlespeech.t2s.modules.rst │ │ │ ├── paddlespeech.t2s.modules.style_encoder.rst │ │ │ ├── paddlespeech.t2s.modules.tacotron2.attentions.rst │ │ │ ├── paddlespeech.t2s.modules.tacotron2.decoder.rst │ │ │ ├── paddlespeech.t2s.modules.tacotron2.encoder.rst │ │ │ ├── paddlespeech.t2s.modules.tacotron2.rst │ │ │ ├── paddlespeech.t2s.modules.tade_res_block.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.attention.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.decoder.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.decoder_layer.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.embedding.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.encoder.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.encoder_layer.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.lightconv.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.mask.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.multi_layer_conv.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.positionwise_feed_forward.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.repeat.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.rst │ │ │ ├── paddlespeech.t2s.modules.transformer.subsampling.rst │ │ │ ├── paddlespeech.t2s.modules.upsample.rst │ │ │ ├── paddlespeech.t2s.rst │ │ │ ├── paddlespeech.t2s.training.cli.rst │ │ │ ├── paddlespeech.t2s.training.default_config.rst │ │ │ ├── paddlespeech.t2s.training.experiment.rst │ │ │ ├── paddlespeech.t2s.training.extension.rst │ │ │ ├── paddlespeech.t2s.training.extensions.evaluator.rst │ │ │ ├── paddlespeech.t2s.training.extensions.rst │ │ │ ├── paddlespeech.t2s.training.extensions.snapshot.rst │ │ │ ├── paddlespeech.t2s.training.extensions.visualizer.rst │ │ │ ├── paddlespeech.t2s.training.optimizer.rst │ │ │ ├── paddlespeech.t2s.training.reporter.rst │ │ │ ├── paddlespeech.t2s.training.rst │ │ │ ├── paddlespeech.t2s.training.seeding.rst │ │ │ ├── paddlespeech.t2s.training.trainer.rst │ │ │ ├── paddlespeech.t2s.training.trigger.rst │ │ │ ├── paddlespeech.t2s.training.triggers.interval_trigger.rst │ │ │ ├── paddlespeech.t2s.training.triggers.limit_trigger.rst │ │ │ ├── paddlespeech.t2s.training.triggers.rst │ │ │ ├── paddlespeech.t2s.training.triggers.time_trigger.rst │ │ │ ├── paddlespeech.t2s.training.updater.rst │ │ │ ├── paddlespeech.t2s.training.updaters.rst │ │ │ ├── paddlespeech.t2s.training.updaters.standard_updater.rst │ │ │ ├── paddlespeech.t2s.utils.checkpoint.rst │ │ │ ├── paddlespeech.t2s.utils.display.rst │ │ │ ├── paddlespeech.t2s.utils.error_rate.rst │ │ │ ├── paddlespeech.t2s.utils.h5_utils.rst │ │ │ ├── paddlespeech.t2s.utils.internals.rst │ │ │ ├── paddlespeech.t2s.utils.layer_tools.rst │ │ │ ├── paddlespeech.t2s.utils.mp_tools.rst │ │ │ ├── paddlespeech.t2s.utils.profiler.rst │ │ │ ├── paddlespeech.t2s.utils.rst │ │ │ ├── paddlespeech.t2s.utils.scheduler.rst │ │ │ ├── paddlespeech.text.exps.ernie_linear.avg_model.rst │ │ │ ├── paddlespeech.text.exps.ernie_linear.punc_restore.rst │ │ │ ├── paddlespeech.text.exps.ernie_linear.rst │ │ │ ├── paddlespeech.text.exps.ernie_linear.test.rst │ │ │ ├── paddlespeech.text.exps.ernie_linear.train.rst │ │ │ ├── paddlespeech.text.exps.rst │ │ │ ├── paddlespeech.text.models.ernie_crf.model.rst │ │ │ ├── paddlespeech.text.models.ernie_crf.rst │ │ │ ├── paddlespeech.text.models.ernie_linear.dataset.rst │ │ │ ├── paddlespeech.text.models.ernie_linear.ernie_linear.rst │ │ │ ├── paddlespeech.text.models.ernie_linear.ernie_linear_updater.rst │ │ │ ├── paddlespeech.text.models.ernie_linear.rst │ │ │ ├── paddlespeech.text.models.rst │ │ │ ├── paddlespeech.text.rst │ │ │ ├── paddlespeech.utils.dynamic_import.rst │ │ │ ├── paddlespeech.utils.env.rst │ │ │ ├── paddlespeech.utils.rst │ │ │ ├── paddlespeech.vector.cluster.diarization.rst │ │ │ ├── paddlespeech.vector.cluster.plda.rst │ │ │ ├── paddlespeech.vector.cluster.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.audio_processor.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.config.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.dataset_processors.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.inference.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.preprocess.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.random_cycle.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.speaker_verification_dataset.rst │ │ │ ├── paddlespeech.vector.exps.ge2e.train.rst │ │ │ ├── paddlespeech.vector.exps.rst │ │ │ ├── paddlespeech.vector.io.augment.rst │ │ │ ├── paddlespeech.vector.io.batch.rst │ │ │ ├── paddlespeech.vector.io.dataset.rst │ │ │ ├── paddlespeech.vector.io.dataset_from_json.rst │ │ │ ├── paddlespeech.vector.io.embedding_norm.rst │ │ │ ├── paddlespeech.vector.io.rst │ │ │ ├── paddlespeech.vector.io.signal_processing.rst │ │ │ ├── paddlespeech.vector.models.ecapa_tdnn.rst │ │ │ ├── paddlespeech.vector.models.lstm_speaker_encoder.rst │ │ │ ├── paddlespeech.vector.models.rst │ │ │ ├── paddlespeech.vector.modules.layer.rst │ │ │ ├── paddlespeech.vector.modules.loss.rst │ │ │ ├── paddlespeech.vector.modules.rst │ │ │ ├── paddlespeech.vector.modules.sid_model.rst │ │ │ ├── paddlespeech.vector.rst │ │ │ ├── paddlespeech.vector.training.rst │ │ │ ├── paddlespeech.vector.training.scheduler.rst │ │ │ ├── paddlespeech.vector.training.seeding.rst │ │ │ ├── paddlespeech.vector.utils.rst │ │ │ ├── paddlespeech.vector.utils.time.rst │ │ │ ├── paddlespeech.vector.utils.vector_utils.rst │ │ │ └── paddlespeech.version.rst │ │ ├── asr/ │ │ │ ├── PPASR.md │ │ │ ├── PPASR_cn.md │ │ │ ├── data_preparation.md │ │ │ ├── feature_list.md │ │ │ ├── models_introduction.md │ │ │ ├── ngram_lm.md │ │ │ └── quick_start.md │ │ ├── audio/ │ │ │ ├── _static/ │ │ │ │ └── custom.css │ │ │ ├── _templates/ │ │ │ │ ├── module.rst_t │ │ │ │ ├── package.rst_t │ │ │ │ └── toc.rst_t │ │ │ ├── conf.py │ │ │ └── index.rst │ │ ├── audio_api/ │ │ │ ├── modules.rst │ │ │ ├── paddleaudio.backends.common.rst │ │ │ ├── paddleaudio.backends.no_backend.rst │ │ │ ├── paddleaudio.backends.rst │ │ │ ├── paddleaudio.backends.soundfile_backend.rst │ │ │ ├── paddleaudio.backends.sox_io_backend.rst │ │ │ ├── paddleaudio.backends.utils.rst │ │ │ ├── paddleaudio.compliance.kaldi.rst │ │ │ ├── paddleaudio.compliance.librosa.rst │ │ │ ├── paddleaudio.compliance.rst │ │ │ ├── paddleaudio.datasets.dataset.rst │ │ │ ├── paddleaudio.datasets.esc50.rst │ │ │ ├── paddleaudio.datasets.gtzan.rst │ │ │ ├── paddleaudio.datasets.hey_snips.rst │ │ │ ├── paddleaudio.datasets.rirs_noises.rst │ │ │ ├── paddleaudio.datasets.rst │ │ │ ├── paddleaudio.datasets.tess.rst │ │ │ ├── paddleaudio.datasets.urban_sound.rst │ │ │ ├── paddleaudio.datasets.voxceleb.rst │ │ │ ├── paddleaudio.features.layers.rst │ │ │ ├── paddleaudio.features.rst │ │ │ ├── paddleaudio.functional.functional.rst │ │ │ ├── paddleaudio.functional.rst │ │ │ ├── paddleaudio.functional.window.rst │ │ │ ├── paddleaudio.kaldi.kaldi.rst │ │ │ ├── paddleaudio.kaldi.rst │ │ │ ├── paddleaudio.metric.eer.rst │ │ │ ├── paddleaudio.metric.rst │ │ │ ├── paddleaudio.rst │ │ │ ├── paddleaudio.sox_effects.rst │ │ │ ├── paddleaudio.sox_effects.sox_effects.rst │ │ │ ├── paddleaudio.utils.download.rst │ │ │ ├── paddleaudio.utils.env.rst │ │ │ ├── paddleaudio.utils.error.rst │ │ │ ├── paddleaudio.utils.log.rst │ │ │ ├── paddleaudio.utils.numeric.rst │ │ │ ├── paddleaudio.utils.rst │ │ │ ├── paddleaudio.utils.sox_utils.rst │ │ │ ├── paddleaudio.utils.tensor_utils.rst │ │ │ └── paddleaudio.utils.time.rst │ │ ├── cls/ │ │ │ ├── custom_dataset.md │ │ │ └── quick_start.md │ │ ├── conf.py │ │ ├── demo_video.rst │ │ ├── dependencies.md │ │ ├── index.rst │ │ ├── install.md │ │ ├── install_cn.md │ │ ├── introduction.md │ │ ├── reference.md │ │ ├── released_model.md │ │ ├── streaming_asr_demo_video.rst │ │ ├── streaming_tts_demo_video.rst │ │ ├── tts/ │ │ │ ├── PPTTS.md │ │ │ ├── PPTTS_cn.md │ │ │ ├── README.md │ │ │ ├── advanced_usage.md │ │ │ ├── demo.rst │ │ │ ├── demo_2.rst │ │ │ ├── gan_vocoder.md │ │ │ ├── models_introduction.md │ │ │ ├── quick_start.md │ │ │ ├── quick_start_cn.md │ │ │ ├── svs_music_score.md │ │ │ ├── test_sentence.txt │ │ │ ├── tts_datasets.md │ │ │ ├── tts_papers.md │ │ │ └── zh_text_frontend.md │ │ ├── tts_demo_video.rst │ │ └── vpr/ │ │ ├── PPVPR.md │ │ └── PPVPR_cn.md │ ├── topic/ │ │ ├── ctc/ │ │ │ ├── ctc_loss.ipynb │ │ │ ├── ctc_loss_compare.ipynb │ │ │ └── ctc_loss_speed_compare.ipynb │ │ ├── frontend/ │ │ │ └── g2p.md │ │ ├── gan_vocoder/ │ │ │ └── gan_vocoder.ipynb │ │ └── package_release/ │ │ └── python_package_release.md │ └── tutorial/ │ ├── .gitkeep │ ├── asr/ │ │ ├── tutorial_deepspeech2.ipynb │ │ └── tutorial_transformer.ipynb │ ├── cls/ │ │ └── cls_tutorial.ipynb │ ├── st/ │ │ └── st_tutorial.ipynb │ └── tts/ │ └── tts_tutorial.ipynb ├── examples/ │ ├── aishell/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── asr0/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── conf/ │ │ │ │ ├── deepspeech2.yaml │ │ │ │ ├── deepspeech2_online.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ └── tuning/ │ │ │ │ ├── chunk_decode.yaml │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── download_lm_ch.sh │ │ │ │ ├── export.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_export.sh │ │ │ │ ├── test_wav.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── asr1/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── conf/ │ │ │ │ ├── augmentation.json │ │ │ │ ├── chunk_conformer.yaml │ │ │ │ ├── chunk_roformer.yaml │ │ │ │ ├── chunk_roformer_bidecoder.yaml │ │ │ │ ├── chunk_squeezeformer.yaml │ │ │ │ ├── conformer.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ ├── squeezeformer.yaml │ │ │ │ ├── transformer.yaml │ │ │ │ └── tuning/ │ │ │ │ ├── chunk_decode.yaml │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── aishell_train_lms.sh │ │ │ │ ├── align.sh │ │ │ │ ├── data.sh │ │ │ │ ├── export.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_wav.sh │ │ │ │ ├── tlg.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── asr3/ │ │ ├── README.md │ │ ├── RESULT.md │ │ ├── cmd.sh │ │ ├── conf/ │ │ │ ├── preprocess.yaml │ │ │ ├── train_with_wav2vec.yaml │ │ │ ├── tuning/ │ │ │ │ └── decode.yaml │ │ │ ├── wav2vec2ASR.yaml │ │ │ └── wav2vec2ASR_adadelta.yaml │ │ ├── local/ │ │ │ ├── aishell_prepare.py │ │ │ ├── data.sh │ │ │ ├── test.sh │ │ │ ├── test_wav.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── aishell3/ │ │ ├── README.md │ │ ├── ernie_sat/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── tts3/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ ├── conformer.yaml │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── ort_predict.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ └── run.sh │ │ ├── vc0/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── train.sh │ │ │ │ └── voice_cloning.sh │ │ │ └── run.sh │ │ ├── vc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── voice_cloning.sh │ │ │ └── run.sh │ │ ├── vc2/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ └── voice_cloning.sh │ │ │ └── run.sh │ │ ├── vits/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── vits-vc/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── train.sh │ │ │ │ └── voice_cloning.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ └── preprocess.sh │ │ │ └── run.sh │ │ └── voc5/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ └── run.sh │ ├── aishell3_vctk/ │ │ ├── README.md │ │ └── ernie_sat/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ ├── local/ │ │ │ ├── preprocess.sh │ │ │ └── synthesize_e2e.sh │ │ └── run.sh │ ├── ami/ │ │ ├── README.md │ │ └── sd0/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── conf/ │ │ │ └── ecapa_tdnn.yaml │ │ ├── local/ │ │ │ ├── ami_prepare.py │ │ │ ├── ami_splits.py │ │ │ ├── compute_embdding.py │ │ │ ├── dataio.py │ │ │ ├── experiment.py │ │ │ └── process.sh │ │ ├── path.sh │ │ └── run.sh │ ├── callcenter/ │ │ ├── README.md │ │ └── asr1/ │ │ ├── .gitignore │ │ ├── RESULTS.md │ │ ├── conf/ │ │ │ ├── augmentation.json │ │ │ ├── chunk_conformer.yaml │ │ │ ├── conformer.yaml │ │ │ ├── preprocess.yaml │ │ │ └── tuning/ │ │ │ ├── chunk_decode.yaml │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── align.sh │ │ │ ├── data.sh │ │ │ ├── download_lm_ch.sh │ │ │ ├── export.sh │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── canton/ │ │ └── tts3/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ ├── local/ │ │ │ ├── inference.sh │ │ │ ├── ort_predict.sh │ │ │ ├── preprocess.sh │ │ │ └── synthesize_e2e.sh │ │ └── run.sh │ ├── csmsc/ │ │ ├── README.md │ │ ├── jets/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── tts0/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── tts2/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── inference_mlu.sh │ │ │ │ ├── inference_npu.sh │ │ │ │ ├── inference_xpu.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── ort_predict.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ ├── synthesize_e2e_mlu.sh │ │ │ │ ├── synthesize_e2e_npu.sh │ │ │ │ ├── synthesize_e2e_xpu.sh │ │ │ │ ├── synthesize_mlu.sh │ │ │ │ ├── synthesize_npu.sh │ │ │ │ ├── synthesize_xpu.sh │ │ │ │ ├── train.sh │ │ │ │ ├── train_mlu.sh │ │ │ │ ├── train_npu.sh │ │ │ │ └── train_xpu.sh │ │ │ ├── path.sh │ │ │ ├── run.sh │ │ │ ├── run_mlu.sh │ │ │ ├── run_npu.sh │ │ │ └── run_xpu.sh │ │ ├── tts3/ │ │ │ ├── README.md │ │ │ ├── README_cn.md │ │ │ ├── conf/ │ │ │ │ ├── cnndecoder.yaml │ │ │ │ ├── conformer.yaml │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── PTQ_dynamic.sh │ │ │ │ ├── PTQ_static.sh │ │ │ │ ├── export2lite.sh │ │ │ │ ├── inference.sh │ │ │ │ ├── inference_streaming.sh │ │ │ │ ├── inference_xpu.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── lite_predict_streaming.sh │ │ │ │ ├── ort_predict.sh │ │ │ │ ├── ort_predict_streaming.sh │ │ │ │ ├── paddle2onnx.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── simple.lexicon │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ ├── synthesize_e2e_xpu.sh │ │ │ │ ├── synthesize_streaming.sh │ │ │ │ ├── synthesize_xpu.sh │ │ │ │ ├── train.sh │ │ │ │ └── train_xpu.sh │ │ │ ├── path.sh │ │ │ ├── run.sh │ │ │ ├── run_cnndecoder.sh │ │ │ └── run_xpu.sh │ │ ├── tts3_rhy/ │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ └── synthesize_e2e.sh │ │ │ └── run.sh │ │ ├── vits/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── PTQ_static.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc3/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ ├── default.yaml │ │ │ │ └── finetune.yaml │ │ │ ├── local/ │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc4/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ └── synthesize.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc5/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ ├── default.yaml │ │ │ │ ├── finetune.yaml │ │ │ │ └── iSTFT.yaml │ │ │ ├── finetune.sh │ │ │ ├── iSTFTNet.md │ │ │ ├── local/ │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── voc6/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ ├── local/ │ │ │ ├── preprocess.sh │ │ │ └── synthesize.sh │ │ ├── path.sh │ │ └── run.sh │ ├── esc50/ │ │ ├── README.md │ │ ├── RESULTS.md │ │ └── cls0/ │ │ ├── conf/ │ │ │ └── panns.yaml │ │ ├── local/ │ │ │ ├── export.sh │ │ │ ├── infer.sh │ │ │ ├── static_model_infer.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── hey_snips/ │ │ ├── README.md │ │ └── kws0/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── mdtc.yaml │ │ ├── local/ │ │ │ ├── plot.sh │ │ │ ├── score.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── iwslt2012/ │ │ └── punc0/ │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── conf/ │ │ │ ├── default.yaml │ │ │ ├── ernie-3.0-base.yaml │ │ │ ├── ernie-3.0-medium.yaml │ │ │ ├── ernie-3.0-mini.yaml │ │ │ ├── ernie-3.0-nano-zh.yaml │ │ │ └── ernie-tiny.yaml │ │ ├── local/ │ │ │ ├── data.sh │ │ │ ├── preprocess.py │ │ │ ├── punc_restore.sh │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── librispeech/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── asr0/ │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── conf/ │ │ │ │ ├── deepspeech2.yaml │ │ │ │ ├── deepspeech2_online.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ └── tuning/ │ │ │ │ ├── chunk_decode.yaml │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── download_lm_en.sh │ │ │ │ ├── export.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_wav.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── asr1/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── cmd.sh │ │ │ ├── conf/ │ │ │ │ ├── augmentation.json │ │ │ │ ├── chunk_conformer.yaml │ │ │ │ ├── chunk_transformer.yaml │ │ │ │ ├── conformer.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ ├── transformer.yaml │ │ │ │ └── tuning/ │ │ │ │ ├── chunk_decode.yaml │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── align.sh │ │ │ │ ├── data.sh │ │ │ │ ├── download_lm_en.sh │ │ │ │ ├── export.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_wav.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── asr2/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── cmd.sh │ │ │ ├── conf/ │ │ │ │ ├── augmentation.json │ │ │ │ ├── decode/ │ │ │ │ │ ├── decode.yaml │ │ │ │ │ ├── decode_att.yaml │ │ │ │ │ ├── decode_base.yaml │ │ │ │ │ ├── decode_ctc.yaml │ │ │ │ │ └── decode_wo_lm.yaml │ │ │ │ ├── fbank.conf │ │ │ │ ├── lm/ │ │ │ │ │ └── transformer.yaml │ │ │ │ ├── pitch.conf │ │ │ │ ├── preprocess.yaml │ │ │ │ └── transformer.yaml │ │ │ ├── local/ │ │ │ │ ├── align.sh │ │ │ │ ├── cacu_perplexity.sh │ │ │ │ ├── data.sh │ │ │ │ ├── data_prep.sh │ │ │ │ ├── download_lm_en.sh │ │ │ │ ├── espnet_json_to_manifest.py │ │ │ │ ├── export.sh │ │ │ │ ├── recog.sh │ │ │ │ ├── test.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── asr3/ │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── cmd.sh │ │ │ ├── conf/ │ │ │ │ ├── preprocess.yaml │ │ │ │ ├── tuning/ │ │ │ │ │ └── decode.yaml │ │ │ │ └── wav2vec2ASR.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_wav.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── asr4/ │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── cmd.sh │ │ │ ├── conf/ │ │ │ │ ├── config.json │ │ │ │ ├── hubertASR.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ ├── preprocessor_config.json │ │ │ │ └── tuning/ │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── test.sh │ │ │ │ ├── test_wav.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── asr5/ │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── avg.sh │ │ ├── cmd.sh │ │ ├── compute_wer.py │ │ ├── conf/ │ │ │ ├── preprocess.yaml │ │ │ ├── preprocessor_config.json │ │ │ ├── tuning/ │ │ │ │ └── decode.yaml │ │ │ └── wavlmASR.yaml │ │ ├── local/ │ │ │ ├── data.sh │ │ │ ├── test.sh │ │ │ ├── test_wav.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── ljspeech/ │ │ ├── README.md │ │ ├── tts0/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ └── run.sh │ │ ├── tts1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── tts3/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── ort_predict.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ └── run.sh │ │ ├── voc0/ │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ └── preprocess.sh │ │ │ └── run.sh │ │ └── voc5/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ └── run.sh │ ├── mustc/ │ │ └── st1/ │ │ ├── cmd.sh │ │ ├── conf/ │ │ │ ├── fbank.conf │ │ │ ├── pitch.conf │ │ │ ├── transformer_de.yaml │ │ │ ├── transformer_es.yaml │ │ │ ├── transformer_fr.yaml │ │ │ ├── transformer_it.yaml │ │ │ ├── transformer_nl.yaml │ │ │ ├── transformer_pt.yaml │ │ │ ├── transformer_ro.yaml │ │ │ └── transformer_ru.yaml │ │ ├── local/ │ │ │ ├── augmentation.json │ │ │ ├── data.sh │ │ │ ├── data_prep.sh │ │ │ ├── divide_lang.sh │ │ │ ├── remove_punctuation.pl │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── opencpop/ │ │ ├── README.md │ │ ├── svs1/ │ │ │ ├── README.md │ │ │ ├── README_cn.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── pinyin_to_phone.txt │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ ├── synthesize_e2e.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── dygraph_to_static.sh │ │ │ │ └── preprocess.sh │ │ │ └── run.sh │ │ └── voc5/ │ │ ├── conf/ │ │ │ ├── default.yaml │ │ │ └── finetune.yaml │ │ ├── finetune.sh │ │ ├── local/ │ │ │ └── dygraph_to_static.sh │ │ └── run.sh │ ├── other/ │ │ ├── augmentation/ │ │ │ └── augmentation.json │ │ ├── cc-cedict/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ └── parser.py │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── g2p/ │ │ │ ├── README.md │ │ │ ├── compare_badcase.py │ │ │ ├── get_g2p_data.py │ │ │ ├── path.sh │ │ │ ├── run.sh │ │ │ └── test_g2p.py │ │ ├── ge2e/ │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── preprocess.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── mfa/ │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ ├── detect_oov.py │ │ │ │ ├── generate_canton_lexicon_wavlabs.py │ │ │ │ ├── generate_lexicon.py │ │ │ │ ├── reorganize_aishell3.py │ │ │ │ ├── reorganize_baker.py │ │ │ │ ├── reorganize_ljspeech.py │ │ │ │ └── reorganize_vctk.py │ │ │ ├── run.sh │ │ │ └── run_canton.sh │ │ ├── ngram_lm/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ └── s0/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── data/ │ │ │ │ ├── README.md │ │ │ │ ├── custom_confusion.txt │ │ │ │ └── text_correct.txt │ │ │ ├── local/ │ │ │ │ ├── build_zh_lm.sh │ │ │ │ ├── download_lm_zh.sh │ │ │ │ └── kenlm_score_test.py │ │ │ ├── path.sh │ │ │ ├── requirements.txt │ │ │ └── run.sh │ │ ├── punctuation_restoration/ │ │ │ └── README.md │ │ ├── rhy/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── data/ │ │ │ │ └── rhy_token │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── pre_for_sp_aishell.py │ │ │ │ ├── pre_for_sp_csmsc.py │ │ │ │ ├── rhy_predict.sh │ │ │ │ ├── test.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── spm/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── path.sh │ │ │ ├── run.sh │ │ │ └── text │ │ ├── tn/ │ │ │ ├── README.md │ │ │ ├── data/ │ │ │ │ └── textnorm_test_cases.txt │ │ │ ├── get_textnorm_data.py │ │ │ ├── path.sh │ │ │ ├── run.sh │ │ │ └── test_textnorm.py │ │ └── tts_finetune/ │ │ └── tts3/ │ │ ├── README.md │ │ ├── conf/ │ │ │ ├── fastspeech2_layers.txt │ │ │ └── finetune.yaml │ │ ├── local/ │ │ │ ├── check_oov.py │ │ │ ├── extract_feature.py │ │ │ ├── finetune.py │ │ │ ├── generate_duration.py │ │ │ ├── get_mfa_result.py │ │ │ └── prepare_env.py │ │ ├── path.sh │ │ ├── run.sh │ │ ├── run_en.sh │ │ └── run_mix.sh │ ├── tal_cs/ │ │ └── asr1/ │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── conf/ │ │ │ ├── chunk_conformer.yaml │ │ │ ├── conformer.yaml │ │ │ ├── preprocess.yaml │ │ │ └── tuning/ │ │ │ ├── chunk_decode.yaml │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── data.sh │ │ │ ├── test.sh │ │ │ ├── test_wav.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── ted_en_zh/ │ │ ├── README.md │ │ ├── st0/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── conf/ │ │ │ │ ├── preprocess.yaml │ │ │ │ ├── transformer.yaml │ │ │ │ ├── transformer_mtl_noam.yaml │ │ │ │ └── tuning/ │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── test.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── st1/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── cmd.sh │ │ ├── conf/ │ │ │ ├── fbank.conf │ │ │ ├── pitch.conf │ │ │ ├── preprocess.yaml │ │ │ ├── transformer.yaml │ │ │ ├── transformer_mtl_noam.yaml │ │ │ └── tuning/ │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── convert_torch_to_paddle.py │ │ │ ├── data.sh │ │ │ ├── divide_lang.sh │ │ │ ├── download_pretrain.sh │ │ │ ├── remove_punctuation.pl │ │ │ ├── ted_en_zh.py │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── tess/ │ │ ├── README.md │ │ └── cls0/ │ │ ├── conf/ │ │ │ ├── panns_logmelspectrogram.yaml │ │ │ ├── panns_melspectrogram.yaml │ │ │ ├── panns_mfcc.yaml │ │ │ └── panns_spectrogram.yaml │ │ ├── local/ │ │ │ ├── train.py │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── thchs30/ │ │ ├── README.md │ │ └── align0/ │ │ ├── README.md │ │ ├── data/ │ │ │ └── dict/ │ │ │ └── syllable.lexicon │ │ ├── local/ │ │ │ ├── data.sh │ │ │ ├── gen_word2phone.py │ │ │ └── reorganize_thchs30.py │ │ ├── path.sh │ │ └── run.sh │ ├── timit/ │ │ ├── README.md │ │ └── asr1/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── conf/ │ │ │ ├── augmentation.json │ │ │ ├── dev_spk.list │ │ │ ├── preprocess.yaml │ │ │ ├── test_spk.list │ │ │ ├── transformer.yaml │ │ │ └── tuning/ │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── align.sh │ │ │ ├── data.sh │ │ │ ├── export.sh │ │ │ ├── test.sh │ │ │ ├── timit_data_prep.sh │ │ │ ├── timit_norm_trans.pl │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── tiny/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── asr0/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ ├── deepspeech2.yaml │ │ │ │ ├── deepspeech2_online.yaml │ │ │ │ ├── preprocess.yaml │ │ │ │ └── tuning/ │ │ │ │ ├── chunk_decode.yaml │ │ │ │ └── decode.yaml │ │ │ ├── local/ │ │ │ │ ├── data.sh │ │ │ │ ├── download_lm_en.sh │ │ │ │ ├── export.sh │ │ │ │ ├── test.sh │ │ │ │ └── train.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── asr1/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── conf/ │ │ │ ├── augmentation.json │ │ │ ├── chunk_confermer.yaml │ │ │ ├── chunk_transformer.yaml │ │ │ ├── conformer.yaml │ │ │ ├── preprocess.yaml │ │ │ ├── transformer.yaml │ │ │ └── tuning/ │ │ │ ├── chunk_decode.yaml │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── align.sh │ │ │ ├── data.sh │ │ │ ├── export.sh │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── vctk/ │ │ ├── README.md │ │ ├── ernie_sat/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ └── run.sh │ │ ├── tts3/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── inference.sh │ │ │ │ ├── lite_predict.sh │ │ │ │ ├── ort_predict.sh │ │ │ │ ├── preprocess.sh │ │ │ │ ├── synthesize.sh │ │ │ │ └── synthesize_e2e.sh │ │ │ └── run.sh │ │ ├── vc3/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ ├── preprocess.sh │ │ │ │ ├── train.sh │ │ │ │ └── voice_conversion.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── voc1/ │ │ │ ├── README.md │ │ │ ├── conf/ │ │ │ │ └── default.yaml │ │ │ ├── local/ │ │ │ │ └── preprocess.sh │ │ │ └── run.sh │ │ └── voc5/ │ │ ├── README.md │ │ ├── conf/ │ │ │ └── default.yaml │ │ └── run.sh │ ├── voxceleb/ │ │ ├── README.md │ │ └── sv0/ │ │ ├── README.md │ │ ├── RESULT.md │ │ ├── conf/ │ │ │ ├── ecapa_tdnn.yaml │ │ │ └── ecapa_tdnn_small.yaml │ │ ├── local/ │ │ │ ├── convert.sh │ │ │ ├── data.sh │ │ │ ├── data_prepare.py │ │ │ ├── emb.sh │ │ │ ├── make_rirs_noise_csv_dataset_from_json.py │ │ │ ├── make_vox_csv_dataset_from_json.py │ │ │ ├── make_voxceleb_kaldi_trial.py │ │ │ ├── test.sh │ │ │ └── train.sh │ │ ├── path.sh │ │ └── run.sh │ ├── wenetspeech/ │ │ ├── README.md │ │ ├── asr0/ │ │ │ └── RESULTS.md │ │ └── asr1/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── RESULTS.md │ │ ├── conf/ │ │ │ ├── chunk_conformer.yaml │ │ │ ├── chunk_conformer_u2pp.yaml │ │ │ ├── conformer.yaml │ │ │ ├── preprocess.yaml │ │ │ └── tuning/ │ │ │ ├── chunk_decode.yaml │ │ │ └── decode.yaml │ │ ├── local/ │ │ │ ├── data.sh │ │ │ ├── export.sh │ │ │ ├── extract_meta.py │ │ │ ├── process_opus.py │ │ │ ├── quant.sh │ │ │ ├── test.sh │ │ │ ├── test_wav.sh │ │ │ ├── train.sh │ │ │ └── wenetspeech_data_prep.sh │ │ ├── path.sh │ │ └── run.sh │ └── zh_en_tts/ │ └── tts3/ │ ├── .gitignore │ ├── README.md │ ├── conf/ │ │ └── default.yaml │ ├── local/ │ │ ├── inference.sh │ │ ├── mfa_download.sh │ │ ├── model_download.sh │ │ ├── ort_predict.sh │ │ ├── preprocess.sh │ │ ├── synthesize.sh │ │ └── synthesize_e2e.sh │ └── run.sh ├── paddlespeech/ │ ├── __init__.py │ ├── audio/ │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── backends/ │ │ │ ├── __init__.py │ │ │ ├── common.py │ │ │ └── soundfile_backend.py │ │ ├── compliance/ │ │ │ ├── __init__.py │ │ │ ├── kaldi.py │ │ │ └── librosa.py │ │ ├── datasets/ │ │ │ ├── __init__.py │ │ │ ├── dataset.py │ │ │ ├── esc50.py │ │ │ └── voxceleb.py │ │ ├── functional/ │ │ │ ├── __init__.py │ │ │ ├── functional.py │ │ │ └── window.py │ │ ├── streamdata/ │ │ │ ├── __init__.py │ │ │ ├── autodecode.py │ │ │ ├── cache.py │ │ │ ├── compat.py │ │ │ ├── extradatasets.py │ │ │ ├── filters.py │ │ │ ├── gopen.py │ │ │ ├── handlers.py │ │ │ ├── mix.py │ │ │ ├── paddle_utils.py │ │ │ ├── pipeline.py │ │ │ ├── shardlists.py │ │ │ ├── soundfile.py │ │ │ ├── tariterators.py │ │ │ ├── utils.py │ │ │ └── writer.py │ │ ├── text/ │ │ │ ├── __init__.py │ │ │ ├── text_featurizer.py │ │ │ └── utility.py │ │ ├── transform/ │ │ │ ├── __init__.py │ │ │ ├── add_deltas.py │ │ │ ├── channel_selector.py │ │ │ ├── cmvn.py │ │ │ ├── functional.py │ │ │ ├── perturb.py │ │ │ ├── spec_augment.py │ │ │ ├── spectrogram.py │ │ │ ├── transform_interface.py │ │ │ ├── transformation.py │ │ │ └── wpe.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── check_kwargs.py │ │ ├── download.py │ │ ├── dynamic_import.py │ │ ├── error.py │ │ ├── log.py │ │ ├── numeric.py │ │ ├── tensor_utils.py │ │ └── time.py │ ├── audiotools/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── core/ │ │ │ ├── __init__.py │ │ │ ├── _julius.py │ │ │ ├── audio_signal.py │ │ │ ├── display.py │ │ │ ├── dsp.py │ │ │ ├── effects.py │ │ │ ├── ffmpeg.py │ │ │ ├── loudness.py │ │ │ └── util.py │ │ ├── data/ │ │ │ ├── __init__.py │ │ │ ├── datasets.py │ │ │ ├── preprocess.py │ │ │ └── transforms.py │ │ ├── metrics/ │ │ │ ├── __init__.py │ │ │ └── quality.py │ │ ├── ml/ │ │ │ ├── __init__.py │ │ │ ├── accelerator.py │ │ │ ├── basemodel.py │ │ │ └── decorators.py │ │ └── post.py │ ├── cli/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── __init__.py │ │ ├── asr/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── base_commands.py │ │ ├── cls/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── download.py │ │ ├── entry.py │ │ ├── executor.py │ │ ├── kws/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── log.py │ │ ├── ssl/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── st/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── text/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── tts/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ ├── utils.py │ │ ├── vector/ │ │ │ ├── __init__.py │ │ │ └── infer.py │ │ └── whisper/ │ │ ├── __init__.py │ │ └── infer.py │ ├── cls/ │ │ ├── __init__.py │ │ ├── exps/ │ │ │ ├── __init__.py │ │ │ └── panns/ │ │ │ ├── __init__.py │ │ │ ├── deploy/ │ │ │ │ ├── __init__.py │ │ │ │ └── predict.py │ │ │ ├── export_model.py │ │ │ ├── predict.py │ │ │ └── train.py │ │ └── models/ │ │ ├── __init__.py │ │ └── panns/ │ │ ├── __init__.py │ │ ├── classifier.py │ │ └── panns.py │ ├── dataset/ │ │ ├── __init__.py │ │ ├── aidatatang_200zh/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ └── aidatatang_200zh.py │ │ ├── aishell/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ └── aishell.py │ │ ├── download.py │ │ └── s2t/ │ │ ├── __init__.py │ │ ├── avg_model.py │ │ ├── build_vocab.py │ │ ├── compute_mean_std.py │ │ ├── compute_wer.py │ │ ├── format_data.py │ │ └── format_rsl.py │ ├── kws/ │ │ ├── __init__.py │ │ ├── exps/ │ │ │ ├── __init__.py │ │ │ └── mdtc/ │ │ │ ├── __init__.py │ │ │ ├── collate.py │ │ │ ├── compute_det.py │ │ │ ├── plot_det_curve.py │ │ │ ├── score.py │ │ │ └── train.py │ │ └── models/ │ │ ├── __init__.py │ │ ├── loss.py │ │ └── mdtc.py │ ├── resource/ │ │ ├── __init__.py │ │ ├── model_alias.py │ │ ├── pretrained_models.py │ │ └── resource.py │ ├── s2t/ │ │ ├── __init__.py │ │ ├── decoders/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── beam_search/ │ │ │ │ ├── __init__.py │ │ │ │ ├── batch_beam_search.py │ │ │ │ └── beam_search.py │ │ │ ├── ctcdecoder/ │ │ │ │ ├── __init__.py │ │ │ │ ├── decoders_deprecated.py │ │ │ │ ├── scorer_deprecated.py │ │ │ │ ├── swig_wrapper.py │ │ │ │ └── tests/ │ │ │ │ └── test_decoders.py │ │ │ ├── recog.py │ │ │ ├── recog_bin.py │ │ │ ├── scorers/ │ │ │ │ ├── __init__.py │ │ │ │ ├── ctc.py │ │ │ │ ├── ctc_prefix_score.py │ │ │ │ ├── length_bonus.py │ │ │ │ ├── ngram.py │ │ │ │ └── scorer_interface.py │ │ │ └── utils.py │ │ ├── exps/ │ │ │ ├── __init__.py │ │ │ ├── deepspeech2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── deploy/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── client.py │ │ │ │ │ │ ├── record.py │ │ │ │ │ │ ├── runtime.py │ │ │ │ │ │ ├── send.py │ │ │ │ │ │ └── server.py │ │ │ │ │ ├── export.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── test_export.py │ │ │ │ │ ├── test_wav.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ ├── hubert/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── test_wav.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ ├── lm/ │ │ │ │ └── transformer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── cacu_perplexity.py │ │ │ │ └── lm_cacu_perplexity.py │ │ │ ├── u2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── alignment.py │ │ │ │ │ ├── export.py │ │ │ │ │ ├── quant.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── test_wav.py │ │ │ │ │ └── train.py │ │ │ │ ├── model.py │ │ │ │ └── trainer.py │ │ │ ├── u2_kaldi/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── recog.py │ │ │ │ │ ├── test.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ ├── u2_st/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── export.py │ │ │ │ │ ├── test.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ ├── wav2vec2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── test_wav.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ ├── wavlm/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bin/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test.py │ │ │ │ │ ├── test_wav.py │ │ │ │ │ └── train.py │ │ │ │ └── model.py │ │ │ └── whisper/ │ │ │ └── test_wav.py │ │ ├── frontend/ │ │ │ ├── __init__.py │ │ │ ├── audio.py │ │ │ ├── augmentor/ │ │ │ │ ├── __init__.py │ │ │ │ ├── augmentation.py │ │ │ │ ├── base.py │ │ │ │ ├── impulse_response.py │ │ │ │ ├── noise_perturb.py │ │ │ │ ├── online_bayesian_normalization.py │ │ │ │ ├── resample.py │ │ │ │ ├── shift_perturb.py │ │ │ │ ├── spec_augment.py │ │ │ │ ├── speed_perturb.py │ │ │ │ └── volume_perturb.py │ │ │ ├── featurizer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── audio_featurizer.py │ │ │ │ ├── speech_featurizer.py │ │ │ │ └── text_featurizer.py │ │ │ ├── normalizer.py │ │ │ ├── speech.py │ │ │ └── utility.py │ │ ├── io/ │ │ │ ├── __init__.py │ │ │ ├── batchfy.py │ │ │ ├── collator.py │ │ │ ├── converter.py │ │ │ ├── dataloader.py │ │ │ ├── dataset.py │ │ │ ├── reader.py │ │ │ ├── sampler.py │ │ │ ├── speechbrain/ │ │ │ │ ├── __init__.py │ │ │ │ ├── batch.py │ │ │ │ ├── data_pipeline.py │ │ │ │ ├── data_utils.py │ │ │ │ ├── dataio.py │ │ │ │ ├── dataloader.py │ │ │ │ ├── dataset.py │ │ │ │ ├── depgraph.py │ │ │ │ ├── make_dataloader.py │ │ │ │ ├── sampler.py │ │ │ │ └── sb_pipeline.py │ │ │ └── utility.py │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── asr_interface.py │ │ │ ├── ds2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── conv.py │ │ │ │ └── deepspeech2.py │ │ │ ├── hubert/ │ │ │ │ ├── __init__.py │ │ │ │ ├── hubert_ASR.py │ │ │ │ └── modules/ │ │ │ │ ├── __init__.py │ │ │ │ └── hubert_model.py │ │ │ ├── lm/ │ │ │ │ ├── __init__.py │ │ │ │ ├── dataset.py │ │ │ │ └── transformer.py │ │ │ ├── lm_interface.py │ │ │ ├── st_interface.py │ │ │ ├── u2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── u2.py │ │ │ │ └── updater.py │ │ │ ├── u2_st/ │ │ │ │ ├── __init__.py │ │ │ │ └── u2_st.py │ │ │ ├── wav2vec2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── modules/ │ │ │ │ │ ├── VanillaNN.py │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── activations.py │ │ │ │ │ ├── containers.py │ │ │ │ │ ├── linear.py │ │ │ │ │ ├── modeling_outputs.py │ │ │ │ │ ├── modeling_wav2vec2.py │ │ │ │ │ ├── normalization.py │ │ │ │ │ └── wav2vec2_model.py │ │ │ │ ├── processing/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── signal_processing.py │ │ │ │ │ └── speech_augmentation.py │ │ │ │ └── wav2vec2_ASR.py │ │ │ ├── wavlm/ │ │ │ │ ├── __init__.py │ │ │ │ ├── modules/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── activations.py │ │ │ │ │ ├── functional.py │ │ │ │ │ └── modules.py │ │ │ │ ├── wavlm_asr.py │ │ │ │ └── wavlm_paddle.py │ │ │ └── whisper/ │ │ │ ├── __init__.py │ │ │ ├── tokenizer.py │ │ │ ├── utils.py │ │ │ ├── whisper.py │ │ │ └── whisper_LICENSE │ │ ├── modules/ │ │ │ ├── __init__.py │ │ │ ├── activation.py │ │ │ ├── align.py │ │ │ ├── attention.py │ │ │ ├── cmvn.py │ │ │ ├── conformer_convolution.py │ │ │ ├── conv2d.py │ │ │ ├── crf.py │ │ │ ├── ctc.py │ │ │ ├── decoder.py │ │ │ ├── decoder_layer.py │ │ │ ├── embedding.py │ │ │ ├── encoder.py │ │ │ ├── encoder_layer.py │ │ │ ├── fbank.py │ │ │ ├── initializer.py │ │ │ ├── loss.py │ │ │ ├── mask.py │ │ │ ├── positionwise_feed_forward.py │ │ │ ├── subsampling.py │ │ │ └── time_reduction.py │ │ ├── training/ │ │ │ ├── __init__.py │ │ │ ├── cli.py │ │ │ ├── extensions/ │ │ │ │ ├── __init__.py │ │ │ │ ├── evaluator.py │ │ │ │ ├── extension.py │ │ │ │ ├── plot.py │ │ │ │ ├── snapshot.py │ │ │ │ └── visualizer.py │ │ │ ├── optimizer/ │ │ │ │ ├── __init__.py │ │ │ │ └── adadelta.py │ │ │ ├── reporter.py │ │ │ ├── scheduler.py │ │ │ ├── timer.py │ │ │ ├── trainer.py │ │ │ ├── triggers/ │ │ │ │ ├── __init__.py │ │ │ │ ├── compare_value_trigger.py │ │ │ │ ├── interval_trigger.py │ │ │ │ ├── limit_trigger.py │ │ │ │ ├── time_trigger.py │ │ │ │ └── utils.py │ │ │ └── updaters/ │ │ │ ├── __init__.py │ │ │ ├── standard_updater.py │ │ │ ├── trainer.py │ │ │ └── updater.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── asr_utils.py │ │ ├── bleu_score.py │ │ ├── check_kwargs.py │ │ ├── checkpoint.py │ │ ├── cli_readers.py │ │ ├── cli_utils.py │ │ ├── cli_writers.py │ │ ├── ctc_utils.py │ │ ├── dynamic_import.py │ │ ├── dynamic_pip_install.py │ │ ├── error_rate.py │ │ ├── layer_tools.py │ │ ├── log.py │ │ ├── mp_tools.py │ │ ├── profiler.py │ │ ├── socket_server.py │ │ ├── spec_augment.py │ │ ├── tensor_utils.py │ │ ├── text_grid.py │ │ └── utility.py │ ├── server/ │ │ ├── README.md │ │ ├── README_cn.md │ │ ├── __init__.py │ │ ├── base_commands.py │ │ ├── bin/ │ │ │ ├── __init__.py │ │ │ ├── paddlespeech_client.py │ │ │ └── paddlespeech_server.py │ │ ├── conf/ │ │ │ ├── application.yaml │ │ │ ├── tts_online_application.yaml │ │ │ ├── vector_application.yaml │ │ │ ├── ws_conformer_application.yaml │ │ │ ├── ws_conformer_wenetspeech_application_faster.yaml │ │ │ └── ws_ds2_application.yaml │ │ ├── engine/ │ │ │ ├── __init__.py │ │ │ ├── acs/ │ │ │ │ ├── __init__.py │ │ │ │ └── python/ │ │ │ │ ├── __init__.py │ │ │ │ └── acs_engine.py │ │ │ ├── asr/ │ │ │ │ ├── __init__.py │ │ │ │ ├── online/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── ctc_endpoint.py │ │ │ │ │ ├── ctc_search.py │ │ │ │ │ ├── onnx/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── asr_engine.py │ │ │ │ │ ├── paddleinference/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── asr_engine.py │ │ │ │ │ └── python/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── asr_engine.py │ │ │ │ ├── paddleinference/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── asr_engine.py │ │ │ │ └── python/ │ │ │ │ ├── __init__.py │ │ │ │ └── asr_engine.py │ │ │ ├── base_engine.py │ │ │ ├── cls/ │ │ │ │ ├── __init__.py │ │ │ │ ├── paddleinference/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── cls_engine.py │ │ │ │ └── python/ │ │ │ │ ├── __init__.py │ │ │ │ └── cls_engine.py │ │ │ ├── engine_factory.py │ │ │ ├── engine_pool.py │ │ │ ├── engine_warmup.py │ │ │ ├── text/ │ │ │ │ ├── __init__.py │ │ │ │ └── python/ │ │ │ │ ├── __init__.py │ │ │ │ └── text_engine.py │ │ │ ├── tts/ │ │ │ │ ├── __init__.py │ │ │ │ ├── online/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── onnx/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── tts_engine.py │ │ │ │ │ └── python/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── tts_engine.py │ │ │ │ ├── paddleinference/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── tts_engine.py │ │ │ │ └── python/ │ │ │ │ ├── __init__.py │ │ │ │ └── tts_engine.py │ │ │ └── vector/ │ │ │ ├── __init__.py │ │ │ └── python/ │ │ │ ├── __init__.py │ │ │ └── vector_engine.py │ │ ├── entry.py │ │ ├── executor.py │ │ ├── restful/ │ │ │ ├── __init__.py │ │ │ ├── acs_api.py │ │ │ ├── api.py │ │ │ ├── asr_api.py │ │ │ ├── cls_api.py │ │ │ ├── request.py │ │ │ ├── response.py │ │ │ ├── text_api.py │ │ │ ├── tts_api.py │ │ │ └── vector_api.py │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── asr/ │ │ │ │ ├── __init__.py │ │ │ │ ├── offline/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── http_client.py │ │ │ │ └── online/ │ │ │ │ ├── README.md │ │ │ │ ├── README_cn.md │ │ │ │ └── microphone_client.py │ │ │ ├── text/ │ │ │ │ └── http_client.py │ │ │ └── tts/ │ │ │ ├── offline/ │ │ │ │ └── http_client.py │ │ │ └── online/ │ │ │ ├── http_client.py │ │ │ └── ws_client.py │ │ ├── util.py │ │ ├── utils/ │ │ │ ├── __init__.py │ │ │ ├── audio_handler.py │ │ │ ├── audio_process.py │ │ │ ├── buffer.py │ │ │ ├── config.py │ │ │ ├── errors.py │ │ │ ├── exception.py │ │ │ ├── onnx_infer.py │ │ │ ├── paddle_predictor.py │ │ │ ├── util.py │ │ │ └── vad.py │ │ └── ws/ │ │ ├── __init__.py │ │ ├── api.py │ │ ├── asr_api.py │ │ └── tts_api.py │ ├── t2s/ │ │ ├── __init__.py │ │ ├── assets/ │ │ │ ├── __init__.py │ │ │ ├── csmsc_test.txt │ │ │ ├── sentences.txt │ │ │ ├── sentences_canton.txt │ │ │ ├── sentences_en.txt │ │ │ ├── sentences_mix.txt │ │ │ ├── sentences_sing.txt │ │ │ └── sentences_ssml.txt │ │ ├── audio/ │ │ │ ├── __init__.py │ │ │ ├── audio.py │ │ │ ├── codec.py │ │ │ └── spec_normalizer.py │ │ ├── datasets/ │ │ │ ├── __init__.py │ │ │ ├── am_batch_fn.py │ │ │ ├── batch.py │ │ │ ├── data_table.py │ │ │ ├── dataset.py │ │ │ ├── get_feats.py │ │ │ ├── ljspeech.py │ │ │ ├── preprocess_utils.py │ │ │ ├── sampler.py │ │ │ └── vocoder_batch_fn.py │ │ ├── exps/ │ │ │ ├── PTQ_dynamic.py │ │ │ ├── PTQ_static.py │ │ │ ├── __init__.py │ │ │ ├── diffsinger/ │ │ │ │ ├── __init__.py │ │ │ │ ├── gen_gta_mel.py │ │ │ │ ├── get_minmax.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ └── train.py │ │ │ ├── dygraph_to_static.py │ │ │ ├── ernie_sat/ │ │ │ │ ├── __init__.py │ │ │ │ ├── align.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize.py │ │ │ │ ├── synthesize_e2e.py │ │ │ │ ├── train.py │ │ │ │ └── utils.py │ │ │ ├── fastspeech2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── gen_gta_mel.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── train.py │ │ │ │ └── vc2_infer.py │ │ │ ├── gan_vocoder/ │ │ │ │ ├── README.md │ │ │ │ ├── __init__.py │ │ │ │ ├── hifigan/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── train.py │ │ │ │ ├── multi_band_melgan/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── train.py │ │ │ │ ├── normalize.py │ │ │ │ ├── parallelwave_gan/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── synthesize_from_wav.py │ │ │ │ │ └── train.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── style_melgan/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── train.py │ │ │ │ └── synthesize.py │ │ │ ├── inference.py │ │ │ ├── inference_streaming.py │ │ │ ├── jets/ │ │ │ │ ├── __init__.py │ │ │ │ ├── inference.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize.py │ │ │ │ ├── synthesize_e2e.py │ │ │ │ └── train.py │ │ │ ├── lite_predict.py │ │ │ ├── lite_predict_streaming.py │ │ │ ├── lite_syn_utils.py │ │ │ ├── ort_predict.py │ │ │ ├── ort_predict_e2e.py │ │ │ ├── ort_predict_streaming.py │ │ │ ├── speedyspeech/ │ │ │ │ ├── __init__.py │ │ │ │ ├── gen_gta_mel.py │ │ │ │ ├── inference.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize_e2e.py │ │ │ │ └── train.py │ │ │ ├── starganv2_vc/ │ │ │ │ ├── __init__.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── train.py │ │ │ │ └── vc.py │ │ │ ├── stream_play_tts.py │ │ │ ├── syn_utils.py │ │ │ ├── synthesize.py │ │ │ ├── synthesize_e2e.py │ │ │ ├── synthesize_streaming.py │ │ │ ├── tacotron2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── preprocess.py │ │ │ │ └── train.py │ │ │ ├── transformer_tts/ │ │ │ │ ├── __init__.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize.py │ │ │ │ ├── synthesize_e2e.py │ │ │ │ └── train.py │ │ │ ├── vits/ │ │ │ │ ├── __init__.py │ │ │ │ ├── inference.py │ │ │ │ ├── lite_predict.py │ │ │ │ ├── normalize.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize.py │ │ │ │ ├── synthesize_e2e.py │ │ │ │ ├── train.py │ │ │ │ └── voice_cloning.py │ │ │ ├── voice_cloning.py │ │ │ ├── waveflow/ │ │ │ │ ├── __init__.py │ │ │ │ ├── config.py │ │ │ │ ├── ljspeech.py │ │ │ │ ├── preprocess.py │ │ │ │ ├── synthesize.py │ │ │ │ └── train.py │ │ │ └── wavernn/ │ │ │ ├── __init__.py │ │ │ ├── synthesize.py │ │ │ └── train.py │ │ ├── frontend/ │ │ │ ├── __init__.py │ │ │ ├── arpabet.py │ │ │ ├── canton_frontend.py │ │ │ ├── en_frontend.py │ │ │ ├── g2pw/ │ │ │ │ ├── __init__.py │ │ │ │ ├── dataset.py │ │ │ │ ├── onnx_api.py │ │ │ │ └── utils.py │ │ │ ├── generate_lexicon.py │ │ │ ├── mix_frontend.py │ │ │ ├── normalizer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── abbrrviation.py │ │ │ │ ├── acronyms.py │ │ │ │ ├── normalizer.py │ │ │ │ ├── numbers.py │ │ │ │ └── width.py │ │ │ ├── phonectic.py │ │ │ ├── polyphonic.py │ │ │ ├── polyphonic.yaml │ │ │ ├── punctuation.py │ │ │ ├── rhy_prediction/ │ │ │ │ ├── __init__.py │ │ │ │ └── rhy_predictor.py │ │ │ ├── sing_frontend.py │ │ │ ├── ssml/ │ │ │ │ ├── __init__.py │ │ │ │ └── xml_processor.py │ │ │ ├── tone_sandhi.py │ │ │ ├── vocab.py │ │ │ ├── zh_frontend.py │ │ │ └── zh_normalization/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── char_convert.py │ │ │ ├── chronology.py │ │ │ ├── constants.py │ │ │ ├── num.py │ │ │ ├── phonecode.py │ │ │ ├── quantifier.py │ │ │ └── text_normlization.py │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── diffsinger/ │ │ │ │ ├── __init__.py │ │ │ │ ├── diffsinger.py │ │ │ │ ├── diffsinger_updater.py │ │ │ │ └── fastspeech2midi.py │ │ │ ├── ernie_sat/ │ │ │ │ ├── __init__.py │ │ │ │ ├── ernie_sat.py │ │ │ │ └── ernie_sat_updater.py │ │ │ ├── fastspeech2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── fastspeech2.py │ │ │ │ └── fastspeech2_updater.py │ │ │ ├── hifigan/ │ │ │ │ ├── __init__.py │ │ │ │ ├── hifigan.py │ │ │ │ └── hifigan_updater.py │ │ │ ├── jets/ │ │ │ │ ├── __init__.py │ │ │ │ ├── alignments.py │ │ │ │ ├── generator.py │ │ │ │ ├── jets.py │ │ │ │ ├── jets_updater.py │ │ │ │ └── length_regulator.py │ │ │ ├── melgan/ │ │ │ │ ├── __init__.py │ │ │ │ ├── melgan.py │ │ │ │ ├── multi_band_melgan_updater.py │ │ │ │ ├── style_melgan.py │ │ │ │ └── style_melgan_updater.py │ │ │ ├── parallel_wavegan/ │ │ │ │ ├── __init__.py │ │ │ │ ├── parallel_wavegan.py │ │ │ │ └── parallel_wavegan_updater.py │ │ │ ├── speedyspeech/ │ │ │ │ ├── __init__.py │ │ │ │ ├── speedyspeech.py │ │ │ │ └── speedyspeech_updater.py │ │ │ ├── starganv2_vc/ │ │ │ │ ├── AuxiliaryASR/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── config.yml │ │ │ │ │ ├── layers.py │ │ │ │ │ └── model.py │ │ │ │ ├── JDCNet/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── model.py │ │ │ │ ├── __init__.py │ │ │ │ ├── losses.py │ │ │ │ ├── starganv2_vc.py │ │ │ │ ├── starganv2_vc_updater.py │ │ │ │ └── transforms.py │ │ │ ├── tacotron2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── tacotron2.py │ │ │ │ └── tacotron2_updater.py │ │ │ ├── transformer_tts/ │ │ │ │ ├── __init__.py │ │ │ │ ├── transformer_tts.py │ │ │ │ └── transformer_tts_updater.py │ │ │ ├── vits/ │ │ │ │ ├── __init__.py │ │ │ │ ├── duration_predictor.py │ │ │ │ ├── flow.py │ │ │ │ ├── generator.py │ │ │ │ ├── monotonic_align/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── core.pyx │ │ │ │ │ └── setup.py │ │ │ │ ├── posterior_encoder.py │ │ │ │ ├── residual_coupling.py │ │ │ │ ├── text_encoder.py │ │ │ │ ├── transform.py │ │ │ │ ├── vits.py │ │ │ │ ├── vits_updater.py │ │ │ │ └── wavenet/ │ │ │ │ ├── __init__.py │ │ │ │ ├── residual_block.py │ │ │ │ └── wavenet.py │ │ │ ├── waveflow.py │ │ │ └── wavernn/ │ │ │ ├── __init__.py │ │ │ ├── wavernn.py │ │ │ └── wavernn_updater.py │ │ ├── modules/ │ │ │ ├── __init__.py │ │ │ ├── activation.py │ │ │ ├── adversarial_loss/ │ │ │ │ ├── __init__.py │ │ │ │ ├── gradient_reversal.py │ │ │ │ └── speaker_classifier.py │ │ │ ├── causal_conv.py │ │ │ ├── conformer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── convolution.py │ │ │ │ └── encoder_layer.py │ │ │ ├── conv.py │ │ │ ├── diffnet.py │ │ │ ├── diffusion.py │ │ │ ├── fftconv1d.py │ │ │ ├── geometry.py │ │ │ ├── layer_norm.py │ │ │ ├── losses.py │ │ │ ├── masked_fill.py │ │ │ ├── nets_utils.py │ │ │ ├── normalizer.py │ │ │ ├── positional_encoding.py │ │ │ ├── pqmf.py │ │ │ ├── predictor/ │ │ │ │ ├── __init__.py │ │ │ │ ├── duration_predictor.py │ │ │ │ ├── length_regulator.py │ │ │ │ └── variance_predictor.py │ │ │ ├── residual_block.py │ │ │ ├── residual_stack.py │ │ │ ├── style_encoder.py │ │ │ ├── tacotron2/ │ │ │ │ ├── __init__.py │ │ │ │ ├── attentions.py │ │ │ │ ├── decoder.py │ │ │ │ └── encoder.py │ │ │ ├── tade_res_block.py │ │ │ ├── transformer/ │ │ │ │ ├── __init__.py │ │ │ │ ├── attention.py │ │ │ │ ├── decoder.py │ │ │ │ ├── decoder_layer.py │ │ │ │ ├── embedding.py │ │ │ │ ├── encoder.py │ │ │ │ ├── encoder_layer.py │ │ │ │ ├── lightconv.py │ │ │ │ ├── mask.py │ │ │ │ ├── multi_layer_conv.py │ │ │ │ ├── positionwise_feed_forward.py │ │ │ │ ├── repeat.py │ │ │ │ └── subsampling.py │ │ │ ├── upsample.py │ │ │ └── wavenet_denoiser.py │ │ ├── training/ │ │ │ ├── __init__.py │ │ │ ├── cli.py │ │ │ ├── default_config.py │ │ │ ├── experiment.py │ │ │ ├── extension.py │ │ │ ├── extensions/ │ │ │ │ ├── __init__.py │ │ │ │ ├── evaluator.py │ │ │ │ ├── snapshot.py │ │ │ │ └── visualizer.py │ │ │ ├── optimizer.py │ │ │ ├── reporter.py │ │ │ ├── seeding.py │ │ │ ├── trainer.py │ │ │ ├── trigger.py │ │ │ ├── triggers/ │ │ │ │ ├── __init__.py │ │ │ │ ├── interval_trigger.py │ │ │ │ ├── limit_trigger.py │ │ │ │ └── time_trigger.py │ │ │ ├── updater.py │ │ │ └── updaters/ │ │ │ ├── __init__.py │ │ │ └── standard_updater.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── checkpoint.py │ │ ├── display.py │ │ ├── error_rate.py │ │ ├── h5_utils.py │ │ ├── internals.py │ │ ├── layer_tools.py │ │ ├── mp_tools.py │ │ ├── profiler.py │ │ └── scheduler.py │ ├── text/ │ │ ├── __init__.py │ │ ├── exps/ │ │ │ ├── __init__.py │ │ │ └── ernie_linear/ │ │ │ ├── __init__.py │ │ │ ├── avg_model.py │ │ │ ├── punc_restore.py │ │ │ ├── test.py │ │ │ └── train.py │ │ └── models/ │ │ ├── __init__.py │ │ ├── ernie_crf/ │ │ │ ├── __init__.py │ │ │ └── model.py │ │ └── ernie_linear/ │ │ ├── __init__.py │ │ ├── dataset.py │ │ ├── ernie_linear.py │ │ └── ernie_linear_updater.py │ ├── utils/ │ │ ├── __init__.py │ │ ├── argparse.py │ │ ├── dynamic_import.py │ │ ├── env.py │ │ └── initialize.py │ └── vector/ │ ├── __init__.py │ ├── cluster/ │ │ ├── __init__.py │ │ ├── diarization.py │ │ └── plda.py │ ├── exps/ │ │ ├── __init__.py │ │ ├── ecapa_tdnn/ │ │ │ ├── extract_emb.py │ │ │ ├── test.py │ │ │ └── train.py │ │ └── ge2e/ │ │ ├── __init__.py │ │ ├── audio_processor.py │ │ ├── config.py │ │ ├── dataset_processors.py │ │ ├── inference.py │ │ ├── preprocess.py │ │ ├── random_cycle.py │ │ ├── speaker_verification_dataset.py │ │ └── train.py │ ├── io/ │ │ ├── __init__.py │ │ ├── augment.py │ │ ├── batch.py │ │ ├── dataset.py │ │ ├── dataset_from_json.py │ │ ├── embedding_norm.py │ │ └── signal_processing.py │ ├── models/ │ │ ├── __init__.py │ │ ├── ecapa_tdnn.py │ │ └── lstm_speaker_encoder.py │ ├── modules/ │ │ ├── __init__.py │ │ ├── layer.py │ │ ├── loss.py │ │ └── sid_model.py │ ├── training/ │ │ ├── __init__.py │ │ ├── scheduler.py │ │ └── seeding.py │ └── utils/ │ ├── __init__.py │ ├── time.py │ └── vector_utils.py ├── runtime/ │ ├── .clang-format │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── build.sh │ ├── build_android.sh │ ├── build_ios.sh │ ├── cmake/ │ │ ├── EnableCMP0048.cmake │ │ ├── EnableCMP0077.cmake │ │ ├── FindGFortranLibs.cmake │ │ ├── absl.cmake │ │ ├── boost.cmake │ │ ├── eigen.cmake │ │ ├── fastdeploy.cmake │ │ ├── gflags.cmake │ │ ├── glog.cmake │ │ ├── gtest.cmake │ │ ├── kenlm.cmake │ │ ├── libsndfile.cmake │ │ ├── openblas.cmake │ │ ├── openfst.cmake │ │ ├── paddleinference.cmake │ │ ├── pybind.cmake │ │ ├── summary.cmake │ │ └── system.cmake │ ├── docker/ │ │ └── .gitkeep │ ├── engine/ │ │ ├── CMakeLists.txt │ │ ├── asr/ │ │ │ ├── CMakeLists.txt │ │ │ ├── decoder/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── common.h │ │ │ │ ├── ctc_beam_search_opt.h │ │ │ │ ├── ctc_prefix_beam_search_decoder.cc │ │ │ │ ├── ctc_prefix_beam_search_decoder.h │ │ │ │ ├── ctc_prefix_beam_search_decoder_main.cc │ │ │ │ ├── ctc_prefix_beam_search_score.h │ │ │ │ ├── ctc_tlg_decoder.cc │ │ │ │ ├── ctc_tlg_decoder.h │ │ │ │ ├── ctc_tlg_decoder_main.cc │ │ │ │ ├── decoder_itf.h │ │ │ │ └── param.h │ │ │ ├── nnet/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── decodable.cc │ │ │ │ ├── decodable.h │ │ │ │ ├── nnet_itf.h │ │ │ │ ├── nnet_producer.cc │ │ │ │ ├── nnet_producer.h │ │ │ │ ├── u2_nnet.cc │ │ │ │ ├── u2_nnet.h │ │ │ │ ├── u2_nnet_main.cc │ │ │ │ ├── u2_nnet_thread_main.cc │ │ │ │ ├── u2_onnx_nnet.cc │ │ │ │ └── u2_onnx_nnet.h │ │ │ ├── recognizer/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── recognizer.cc │ │ │ │ ├── recognizer.h │ │ │ │ ├── recognizer_batch_main.cc │ │ │ │ ├── recognizer_batch_main2.cc │ │ │ │ ├── recognizer_controller.cc │ │ │ │ ├── recognizer_controller.h │ │ │ │ ├── recognizer_controller_impl.cc │ │ │ │ ├── recognizer_controller_impl.h │ │ │ │ ├── recognizer_instance.cc │ │ │ │ ├── recognizer_instance.h │ │ │ │ ├── recognizer_main.cc │ │ │ │ └── recognizer_resource.h │ │ │ └── server/ │ │ │ ├── CMakeLists.txt │ │ │ └── websocket/ │ │ │ ├── CMakeLists.txt │ │ │ ├── websocket_client.cc │ │ │ ├── websocket_client.h │ │ │ ├── websocket_client_main.cc │ │ │ ├── websocket_server.cc │ │ │ ├── websocket_server.h │ │ │ └── websocket_server_main.cc │ │ ├── audio_classification/ │ │ │ ├── CMakeLists.txt │ │ │ └── nnet/ │ │ │ ├── CMakeLists.txt │ │ │ ├── panns_interface.cc │ │ │ ├── panns_interface.h │ │ │ ├── panns_nnet.cc │ │ │ ├── panns_nnet.h │ │ │ └── panns_nnet_main.cc │ │ ├── codelab/ │ │ │ ├── CMakeLists.txt │ │ │ └── README.md │ │ ├── common/ │ │ │ ├── CMakeLists.txt │ │ │ ├── base/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── basic_types.h │ │ │ │ ├── common.h │ │ │ │ ├── config.h │ │ │ │ ├── flags.h.in │ │ │ │ ├── glog_utils.cc │ │ │ │ ├── glog_utils.h │ │ │ │ ├── log.h.in │ │ │ │ ├── log_impl.cc │ │ │ │ ├── log_impl.h │ │ │ │ ├── macros.h │ │ │ │ ├── safe_queue.h │ │ │ │ ├── safe_queue_inl.h │ │ │ │ └── thread_pool.h │ │ │ ├── frontend/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── assembler.cc │ │ │ │ ├── assembler.h │ │ │ │ ├── audio_cache.cc │ │ │ │ ├── audio_cache.h │ │ │ │ ├── cmvn.cc │ │ │ │ ├── cmvn.h │ │ │ │ ├── compute_fbank_main.cc │ │ │ │ ├── compute_linear_spectrogram_main.cc │ │ │ │ ├── data_cache.h │ │ │ │ ├── db_norm.cc │ │ │ │ ├── db_norm.h │ │ │ │ ├── fbank.h │ │ │ │ ├── feature-fbank.cc │ │ │ │ ├── feature-fbank.h │ │ │ │ ├── feature-functions.cc │ │ │ │ ├── feature-functions.h │ │ │ │ ├── feature-window.cc │ │ │ │ ├── feature-window.h │ │ │ │ ├── feature_cache.cc │ │ │ │ ├── feature_cache.h │ │ │ │ ├── feature_common.h │ │ │ │ ├── feature_common_inl.h │ │ │ │ ├── feature_pipeline.cc │ │ │ │ ├── feature_pipeline.h │ │ │ │ ├── fftsg.c │ │ │ │ ├── frontend_itf.h │ │ │ │ ├── linear_spectrogram.cc │ │ │ │ ├── linear_spectrogram.h │ │ │ │ ├── mel-computations.cc │ │ │ │ ├── mel-computations.h │ │ │ │ ├── normalizer.h │ │ │ │ ├── rfft.cc │ │ │ │ ├── rfft.h │ │ │ │ ├── wave-reader.cc │ │ │ │ └── wave-reader.h │ │ │ ├── matrix/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── kaldi-matrix-inl.h │ │ │ │ ├── kaldi-matrix.cc │ │ │ │ ├── kaldi-matrix.h │ │ │ │ ├── kaldi-vector-inl.h │ │ │ │ ├── kaldi-vector.cc │ │ │ │ ├── kaldi-vector.h │ │ │ │ └── matrix-common.h │ │ │ └── utils/ │ │ │ ├── CMakeLists.txt │ │ │ ├── audio_process.cc │ │ │ ├── audio_process.h │ │ │ ├── blank_process_test.cc │ │ │ ├── file_utils.cc │ │ │ ├── file_utils.h │ │ │ ├── math.cc │ │ │ ├── math.h │ │ │ ├── picojson.h │ │ │ ├── strings.cc │ │ │ ├── strings.h │ │ │ ├── strings_test.cc │ │ │ ├── timer.cc │ │ │ └── timer.h │ │ ├── kaldi/ │ │ │ ├── CMakeLists.txt │ │ │ ├── base/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── io-funcs-inl.h │ │ │ │ ├── io-funcs.cc │ │ │ │ ├── io-funcs.h │ │ │ │ ├── kaldi-common.h │ │ │ │ ├── kaldi-error.cc │ │ │ │ ├── kaldi-error.h │ │ │ │ ├── kaldi-math.cc │ │ │ │ ├── kaldi-math.h │ │ │ │ ├── kaldi-types.h │ │ │ │ ├── kaldi-utils.cc │ │ │ │ ├── kaldi-utils.h │ │ │ │ ├── timer.cc │ │ │ │ ├── timer.h │ │ │ │ └── version.h │ │ │ ├── decoder/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── decodable-itf.h │ │ │ │ ├── lattice-faster-decoder.cc │ │ │ │ ├── lattice-faster-decoder.h │ │ │ │ ├── lattice-faster-online-decoder.cc │ │ │ │ └── lattice-faster-online-decoder.h │ │ │ ├── fstbin/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── fstaddselfloops.cc │ │ │ │ ├── fstdeterminizestar.cc │ │ │ │ ├── fstisstochastic.cc │ │ │ │ ├── fstminimizeencoded.cc │ │ │ │ └── fsttablecompose.cc │ │ │ ├── fstext/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── determinize-lattice-inl.h │ │ │ │ ├── determinize-lattice.h │ │ │ │ ├── determinize-star-inl.h │ │ │ │ ├── determinize-star.h │ │ │ │ ├── fstext-lib.h │ │ │ │ ├── fstext-utils-inl.h │ │ │ │ ├── fstext-utils.h │ │ │ │ ├── kaldi-fst-io-inl.h │ │ │ │ ├── kaldi-fst-io.cc │ │ │ │ ├── kaldi-fst-io.h │ │ │ │ ├── lattice-utils-inl.h │ │ │ │ ├── lattice-utils.h │ │ │ │ ├── lattice-weight.h │ │ │ │ ├── pre-determinize-inl.h │ │ │ │ ├── pre-determinize.h │ │ │ │ ├── remove-eps-local-inl.h │ │ │ │ ├── remove-eps-local.h │ │ │ │ └── table-matcher.h │ │ │ ├── lat/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── determinize-lattice-pruned.cc │ │ │ │ ├── determinize-lattice-pruned.h │ │ │ │ ├── kaldi-lattice.cc │ │ │ │ ├── kaldi-lattice.h │ │ │ │ ├── lattice-functions.cc │ │ │ │ └── lattice-functions.h │ │ │ ├── lm/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── arpa-file-parser.cc │ │ │ │ ├── arpa-file-parser.h │ │ │ │ ├── arpa-lm-compiler.cc │ │ │ │ └── arpa-lm-compiler.h │ │ │ ├── lmbin/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── arpa2fst.cc │ │ │ └── util/ │ │ │ ├── CMakeLists.txt │ │ │ ├── basic-filebuf.h │ │ │ ├── common-utils.h │ │ │ ├── const-integer-set-inl.h │ │ │ ├── const-integer-set.h │ │ │ ├── edit-distance-inl.h │ │ │ ├── edit-distance.h │ │ │ ├── hash-list-inl.h │ │ │ ├── hash-list.h │ │ │ ├── kaldi-cygwin-io-inl.h │ │ │ ├── kaldi-holder-inl.h │ │ │ ├── kaldi-holder.cc │ │ │ ├── kaldi-holder.h │ │ │ ├── kaldi-io-inl.h │ │ │ ├── kaldi-io.cc │ │ │ ├── kaldi-io.h │ │ │ ├── kaldi-pipebuf.h │ │ │ ├── kaldi-semaphore.cc │ │ │ ├── kaldi-semaphore.h │ │ │ ├── kaldi-table-inl.h │ │ │ ├── kaldi-table.cc │ │ │ ├── kaldi-table.h │ │ │ ├── kaldi-thread.cc │ │ │ ├── kaldi-thread.h │ │ │ ├── options-itf.h │ │ │ ├── parse-options.cc │ │ │ ├── parse-options.h │ │ │ ├── simple-io-funcs.cc │ │ │ ├── simple-io-funcs.h │ │ │ ├── simple-options.cc │ │ │ ├── simple-options.h │ │ │ ├── stl-utils.h │ │ │ ├── table-types.h │ │ │ ├── text-utils.cc │ │ │ └── text-utils.h │ │ └── vad/ │ │ ├── CMakeLists.txt │ │ ├── frontend/ │ │ │ └── wav.h │ │ ├── interface/ │ │ │ ├── CMakeLists.txt │ │ │ ├── vad_interface.cc │ │ │ ├── vad_interface.h │ │ │ └── vad_interface_main.cc │ │ └── nnet/ │ │ ├── CMakeLists.txt │ │ ├── vad.cc │ │ ├── vad.h │ │ └── vad_nnet_main.cc │ ├── examples/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── android/ │ │ │ └── VadJni/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── .gitignore │ │ │ │ ├── build.gradle │ │ │ │ ├── libs/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── proguard-rules.pro │ │ │ │ └── src/ │ │ │ │ ├── androidTest/ │ │ │ │ │ └── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── baidu/ │ │ │ │ │ └── paddlespeech/ │ │ │ │ │ └── vadjni/ │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ │ └── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── assets/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── cpp/ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── native-lib.cpp │ │ │ │ │ └── vad_interface.h │ │ │ │ ├── java/ │ │ │ │ │ └── com/ │ │ │ │ │ └── baidu/ │ │ │ │ │ └── paddlespeech/ │ │ │ │ │ └── vadjni/ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── drawable-v24/ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ ├── layout/ │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── mipmap-anydpi-v26/ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── mipmap-anydpi-v33/ │ │ │ │ │ └── ic_launcher.xml │ │ │ │ ├── values/ │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── themes.xml │ │ │ │ ├── values-night/ │ │ │ │ │ └── themes.xml │ │ │ │ └── xml/ │ │ │ │ ├── backup_rules.xml │ │ │ │ └── data_extraction_rules.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ └── settings.gradle │ │ ├── audio_classification/ │ │ │ ├── README.md │ │ │ ├── android_demo/ │ │ │ │ ├── .gitignore │ │ │ │ ├── app/ │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── build.gradle │ │ │ │ │ ├── proguard-rules.pro │ │ │ │ │ └── src/ │ │ │ │ │ ├── androidTest/ │ │ │ │ │ │ └── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── cls/ │ │ │ │ │ │ └── ExampleInstrumentedTest.kt │ │ │ │ │ └── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── cpp/ │ │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ │ ├── includes/ │ │ │ │ │ │ │ └── panns_interface.h │ │ │ │ │ │ └── native-lib.cpp │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── cls/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ │ ├── drawable-v24/ │ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ ├── layout/ │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── mipmap-anydpi-v26/ │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── themes.xml │ │ │ │ │ ├── values-night/ │ │ │ │ │ │ └── themes.xml │ │ │ │ │ └── xml/ │ │ │ │ │ ├── backup_rules.xml │ │ │ │ │ └── data_extraction_rules.xml │ │ │ │ ├── build.gradle │ │ │ │ ├── gradle/ │ │ │ │ │ └── wrapper/ │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ │ ├── gradle.properties │ │ │ │ ├── gradlew │ │ │ │ ├── gradlew.bat │ │ │ │ └── settings.gradle │ │ │ ├── conf │ │ │ ├── label_list │ │ │ └── scp │ │ ├── codelab/ │ │ │ ├── README.md │ │ │ ├── decoder/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── path.sh │ │ │ │ ├── run.sh │ │ │ │ └── valgrind.sh │ │ │ ├── feat/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── path.sh │ │ │ │ ├── run.sh │ │ │ │ └── valgrind.sh │ │ │ ├── nnet/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── path.sh │ │ │ │ ├── run.sh │ │ │ │ └── valgrind.sh │ │ │ └── u2/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ ├── decode.sh │ │ │ │ ├── feat.sh │ │ │ │ ├── nnet.sh │ │ │ │ └── recognizer.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── custom_asr/ │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ ├── compile_lexicon_token_fst.sh │ │ │ │ ├── mk_slot_graph.sh │ │ │ │ ├── mk_tlg_with_slot.sh │ │ │ │ └── train_lm_with_slot.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── text_lm/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── local/ │ │ │ │ └── mmseg.py │ │ │ ├── path.sh │ │ │ └── run.sh │ │ ├── u2pp_ol/ │ │ │ ├── README.md │ │ │ └── wenetspeech/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── RESULTS.md │ │ │ ├── local/ │ │ │ │ ├── aishell_train_lms.sh │ │ │ │ ├── decode.sh │ │ │ │ ├── feat.sh │ │ │ │ ├── nnet.sh │ │ │ │ ├── recognizer.sh │ │ │ │ ├── recognizer_fastdeploy.sh │ │ │ │ ├── recognizer_quant.sh │ │ │ │ ├── recognizer_wfst.sh │ │ │ │ ├── recognizer_wfst_fastdeploy.sh │ │ │ │ ├── run_build_tlg.sh │ │ │ │ └── split_data.sh │ │ │ ├── path.sh │ │ │ └── run.sh │ │ └── vad/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── conf/ │ │ │ └── vad.ini │ │ ├── local/ │ │ │ ├── build.sh │ │ │ ├── build_android.sh │ │ │ ├── decode.sh │ │ │ └── download.sh │ │ ├── path.sh │ │ ├── run.sh │ │ └── vad-android-demo/ │ │ ├── .gradle/ │ │ │ ├── 6.1.1/ │ │ │ │ └── gc.properties │ │ │ ├── buildOutputCleanup/ │ │ │ │ └── cache.properties │ │ │ └── vcs-1/ │ │ │ └── gc.properties │ │ ├── LICENSE.md │ │ ├── README │ │ ├── README.md │ │ ├── build.gradle │ │ ├── example/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── local.properties │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ ├── androidTest/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── konovalov/ │ │ │ │ └── vad/ │ │ │ │ └── example/ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── konovalov/ │ │ │ │ └── vad/ │ │ │ │ └── example/ │ │ │ │ ├── MainActivity.java │ │ │ │ └── recorder/ │ │ │ │ ├── VoiceRecorder.java │ │ │ │ └── VoiceRecorderConfig.java │ │ │ └── res/ │ │ │ ├── drawable/ │ │ │ │ └── ic_launcher_background.xml │ │ │ ├── drawable-v24/ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── layout/ │ │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26/ │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ └── values/ │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── local.properties │ │ ├── settings.gradle │ │ └── vad/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── consumer-rules.pro │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── konovalov/ │ │ │ └── vad/ │ │ │ └── ExampleInstrumentedTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── cpp/ │ │ │ ├── CMakeLists.txt │ │ │ ├── includes/ │ │ │ │ └── vad_interface.h │ │ │ └── native-lib.cpp │ │ ├── java/ │ │ │ └── com/ │ │ │ └── konovalov/ │ │ │ └── vad/ │ │ │ ├── Vad.java │ │ │ └── VadListener.java │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ ├── patch/ │ │ ├── CPPLINT.cfg │ │ ├── README.md │ │ └── openfst/ │ │ └── src/ │ │ ├── include/ │ │ │ └── fst/ │ │ │ ├── flags.h │ │ │ └── log.h │ │ └── lib/ │ │ └── flags.cc │ └── tools/ │ ├── clang-format.sh │ ├── setup_valgrind.sh │ └── venv.sh ├── setup.cfg ├── setup.py ├── tests/ │ ├── benchmark/ │ │ ├── conformer/ │ │ │ ├── README.md │ │ │ ├── prepare.sh │ │ │ ├── run.sh │ │ │ └── run_benchmark.sh │ │ └── pwgan/ │ │ ├── README.md │ │ ├── run_all.sh │ │ └── run_benchmark.sh │ ├── chains/ │ │ ├── ds2/ │ │ │ ├── README.md │ │ │ ├── ds2_params_lite_train_infer.txt │ │ │ ├── ds2_params_whole_train_infer.txt │ │ │ ├── lite_train_infer.sh │ │ │ ├── prepare.sh │ │ │ ├── speedyspeech_params_lite.txt │ │ │ ├── test.sh │ │ │ └── whole_train_infer.sh │ │ └── speedyspeech/ │ │ ├── README.md │ │ ├── infer.sh │ │ ├── lite_train_infer.sh │ │ ├── prepare.sh │ │ ├── speedyspeech_params_lite_multi_gpu.txt │ │ ├── speedyspeech_params_lite_single_gpu.txt │ │ ├── speedyspeech_params_whole_multi_gpu.txt │ │ ├── speedyspeech_params_whole_single_gpu.txt │ │ ├── test.sh │ │ └── whole_train_infer.sh │ ├── test_tipc/ │ │ ├── barrier.sh │ │ ├── benchmark_train.sh │ │ ├── common_func.sh │ │ ├── configs/ │ │ │ ├── conformer/ │ │ │ │ └── train_infer_python.txt │ │ │ ├── mdtc/ │ │ │ │ └── train_infer_python.txt │ │ │ └── pwgan/ │ │ │ └── train_infer_python.txt │ │ ├── conformer/ │ │ │ └── scripts/ │ │ │ └── aishell_tiny.py │ │ ├── docs/ │ │ │ └── benchmark_train.md │ │ ├── prepare.sh │ │ └── test_train_inference_python.sh │ └── unit/ │ ├── asr/ │ │ ├── deepspeech2_model_test.py │ │ ├── deepspeech2_online_model_test.py │ │ ├── deepspeech2_online_model_test.sh │ │ ├── error_rate_test.py │ │ ├── mask_test.py │ │ ├── reverse_pad_list.py │ │ └── u2_model_test.py │ ├── audiotools/ │ │ ├── core/ │ │ │ ├── test_audio_signal.py │ │ │ ├── test_bands.py │ │ │ ├── test_display.py │ │ │ ├── test_dsp.py │ │ │ ├── test_effects.py │ │ │ ├── test_fftconv.py │ │ │ ├── test_grad.py │ │ │ ├── test_highpass.py │ │ │ ├── test_loudness.py │ │ │ ├── test_lowpass.py │ │ │ └── test_util.py │ │ ├── data/ │ │ │ ├── test_datasets.py │ │ │ ├── test_preprocess.py │ │ │ └── test_transforms.py │ │ ├── ml/ │ │ │ ├── test_decorators.py │ │ │ └── test_model.py │ │ ├── test_audiotools.sh │ │ └── test_post.py │ ├── ci.sh │ ├── cli/ │ │ ├── aishell_test_prepare.py │ │ ├── calc_RTF_CER_by_aishell.sh │ │ ├── path.sh │ │ └── test_cli.sh │ ├── doc/ │ │ └── test_cli.md │ ├── server/ │ │ ├── offline/ │ │ │ ├── change_yaml.py │ │ │ ├── conf/ │ │ │ │ └── application.yaml │ │ │ └── test_server_client.sh │ │ └── online/ │ │ └── tts/ │ │ ├── check_server/ │ │ │ ├── change_yaml.py │ │ │ ├── conf/ │ │ │ │ └── application.yaml │ │ │ ├── test.sh │ │ │ ├── test_all.sh │ │ │ └── tts_online_application.yaml │ │ └── test_server/ │ │ └── test_http_client.py │ ├── tts/ │ │ ├── test_data_table.py │ │ ├── test_enfrontend.py │ │ ├── test_expansion.py │ │ ├── test_fftconv1d.py │ │ ├── test_losses.py │ │ ├── test_mixfrontend.py │ │ ├── test_optimizer.py │ │ ├── test_pwg.py │ │ ├── test_raise.py │ │ ├── test_reporter.py │ │ ├── test_snapshot.py │ │ ├── test_ssml.py │ │ ├── test_stft.py │ │ └── test_to_static.py │ └── vector/ │ ├── conftest.py │ └── test_augment.py ├── third_party/ │ ├── README.md │ ├── __init__.py │ ├── ctc_decoders/ │ │ ├── .gitignore │ │ ├── COPYING.APACHE2.0 │ │ ├── COPYING.LESSER.3 │ │ ├── LICENSE │ │ ├── __init__.py │ │ ├── ctc_beam_search_decoder.cpp │ │ ├── ctc_beam_search_decoder.h │ │ ├── ctc_greedy_decoder.cpp │ │ ├── ctc_greedy_decoder.h │ │ ├── decoder_utils.cpp │ │ ├── decoder_utils.h │ │ ├── decoders.i │ │ ├── path_trie.cpp │ │ ├── path_trie.h │ │ ├── scorer.cpp │ │ ├── scorer.h │ │ ├── setup.py │ │ └── setup.sh │ ├── install.sh │ ├── install_win_ctc.bat │ └── python_kaldi_features/ │ ├── .gitignore │ ├── LICENSE │ ├── MANIFEST │ ├── README.rst │ ├── docs/ │ │ ├── Makefile │ │ ├── make.bat │ │ └── source/ │ │ ├── conf.py │ │ └── index.rst │ ├── example.py │ ├── python_speech_features/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── base_orig.py │ │ ├── sigproc.py │ │ └── sigproc_orig.py │ ├── requirements.txt │ ├── setup.py │ └── test/ │ └── test_sigproc.py ├── tools/ │ ├── Dockerfile │ ├── Makefile │ ├── extras/ │ │ ├── README.md │ │ ├── install_autolog.sh │ │ ├── install_gcc.sh │ │ ├── install_kaldi.sh │ │ ├── install_kenlm.sh │ │ ├── install_liblbfgs.sh │ │ ├── install_mfa_v1.sh │ │ ├── install_mfa_v2.sh │ │ ├── install_miniconda.sh │ │ ├── install_mkl.sh │ │ ├── install_ngram.sh │ │ ├── install_openblas.sh │ │ ├── install_openfst.sh │ │ ├── install_pynini.sh │ │ ├── install_sclite.sh │ │ ├── install_soundfile.sh │ │ ├── install_sox.sh │ │ ├── install_srilm.sh │ │ ├── install_venv.sh │ │ └── srilm.patch │ ├── get_contributors.ipynb │ ├── pre_commit.sh │ ├── release_note.py │ ├── setup_anaconda.sh │ └── watermark.py └── utils/ ├── DER.py ├── README.md ├── __init__.py ├── addjson.py ├── apply-cmvn.py ├── avg.sh ├── avg_model.py ├── build_kenlm_model_from_arpa.sh ├── build_vocab.py ├── caculate_rtf.py ├── compute-cmvn-stats.py ├── compute-wer.py ├── compute_mean_std.py ├── compute_statistics.py ├── copy-feats.py ├── data2json.sh ├── dump.sh ├── dump_manifest.py ├── duration_from_maniefst.sh ├── espnet_json_to_manifest.py ├── feat-to-shape.py ├── feat_to_shape.sh ├── filter.py ├── filter_scp.pl ├── format_data.py ├── format_rsl.py ├── format_triplet_data.py ├── fst/ │ ├── add_lex_disambig.pl │ ├── compile_lexicon_token_fst.sh │ ├── ctc_token_fst.py │ ├── ctc_token_fst_corrected.py │ ├── eps2disambig.pl │ ├── make_lexicon_fst.pl │ ├── make_tlg.sh │ ├── prepare_dict.py │ ├── remove_oovs.pl │ ├── rnnt_token_fst.py │ └── s2eps.pl ├── gen_duration_from_textgrid.py ├── generate_infer_yaml.py ├── json2trn.py ├── link_wav.py ├── log.sh ├── manifest_key_value.py ├── md-eval.pl ├── merge_scp2json.py ├── ngram_train.sh ├── pack_model.sh ├── parallel/ │ └── run.pl ├── parse_options.sh ├── pd_env_collect.sh ├── profile.sh ├── reduce_data_dir.sh ├── remove_longshortdata.py ├── remove_longshortdata.sh ├── score_sclite.sh ├── scp2json.py ├── show_results.sh ├── spk2utt_to_utt2spk.pl ├── split_data.sh ├── split_json.sh ├── split_scp.pl ├── spm_decode ├── spm_encode ├── spm_train ├── tarball.sh ├── text2token.py ├── text_to_lexicon.py ├── tokenizer.perl ├── train_arpa_with_kenlm.sh ├── update_json.sh ├── utility.sh ├── utt2spk_to_spk2utt.pl └── zh_tn.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ # This file is used by clang-format to autoformat paddle source code # # The clang-format is part of llvm toolchain. # It need to install llvm and clang to format source code style. # # The basic usage is, # clang-format -i -style=file PATH/TO/SOURCE/CODE # # The -style=file implicit use ".clang-format" file located in one of # parent directory. # The -i means inplace change. # # The document of clang-format is # http://clang.llvm.org/docs/ClangFormat.html # http://clang.llvm.org/docs/ClangFormatStyleOptions.html --- Language: Cpp BasedOnStyle: Google IndentWidth: 4 TabWidth: 4 ContinuationIndentWidth: 4 MaxEmptyLinesToKeep: 2 AccessModifierOffset: -2 # The private/protected/public has no indent in class Standard: Cpp11 AllowAllParametersOfDeclarationOnNextLine: true BinPackParameters: false BinPackArguments: false ... ================================================ FILE: .flake8 ================================================ [flake8] ########## OPTIONS ########## # Set the maximum length that any line (with some exceptions) may be. max-line-length = 120 ################### FILE PATTERNS ########################## # Provide a comma-separated list of glob patterns to exclude from checks. exclude = # git folder .git, # python cache __pycache__, # third party utils/compute-wer.py, third_party/, # Provide a comma-separate list of glob patterns to include for checks. filename = *.py ########## RULES ########## # ERROR CODES # # E/W - PEP8 errors/warnings (pycodestyle) # F - linting errors (pyflakes) # C - McCabe complexity error (mccabe) # # W503 - line break before binary operator # Specify a list of codes to ignore. ignore = W503 E252,E262,E127,E265,E126,E266,E241,E261,E128,E125,E129 W291,W293,W605 E203,E305,E402,E501,E721,E741,F403,F405,F821,F841,F999,W503,W504,C408,E302,W291,E303, # shebang has extra meaning in fbcode lints, so I think it's not worth trying # to line this up with executable bit EXE001, # these ignores are from flake8-bugbear; please fix! B007,B008, # these ignores are from flake8-comprehensions; please fix! C400,C401,C402,C403,C404,C405,C407,C411,C413,C414,C415 per-file-ignores = */__init__.py: F401 # Specify the list of error codes you wish Flake8 to report. select = E, W, F, C ================================================ FILE: .gitconfig ================================================ [alias] st = status ci = commit br = branch co = checkout df = diff l = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short ll = log --stat [merge] tool = vimdiff [core] excludesfile = ~/.gitignore editor = vim [color] branch = auto diff = auto status = auto [color "branch"] current = yellow reverse local = yellow remote = green [color "diff"] meta = yellow bold frag = magenta bold old = red bold new = green bold [color "status"] added = yellow changed = green untracked = cyan [push] default = matching [credential] helper = store [user] name = email = ================================================ FILE: .github/CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Racial or political allusions * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at paddlespeech@baidu.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: .github/CONTRIBUTING.md ================================================ # 💡 paddlespeech 提交代码须知 ### Discussed in https://github.com/PaddlePaddle/PaddleSpeech/discussions/1326
Originally posted by **yt605155624** January 12, 2022 1. 写完代码之后可以用我们的 pre-commit 检查一下代码格式,注意只改自己修改的代码的格式即可,其他的代码有可能也被改了格式,不要 add 就好 ``` pip install pre-commit pre-commit run --file 你修改的代码 ``` 2. 提交 commit 中增加必要信息跳过不必要的 CI - 提交 asr 相关代码 ```text git commit -m "xxxxxx, test=asr" ``` - 提交 tts 相关代码 ```text git commit -m "xxxxxx, test=tts" ``` - 仅修改文档 ```text git commit -m "xxxxxx, test=doc" ``` 注意: 1. 虽然跳过了 CI,但是还要先排队排到才能跳过,所以非自己方向看到 pending 不要着急 🤣 2. 在 `git commit --amend` 的时候才加 `test=xxx` 可能不太有效 3. 一个 pr 多次提交 commit 注意每次都要加 `test=xxx`,因为每个 commit 都会触发 CI 4. 删除 python 环境中已经安装好的 paddlespeech,否则可能会影响 import paddlespeech 的顺序
================================================ FILE: .github/ISSUE_TEMPLATE/bug-report-s2t.md ================================================ --- name: "\U0001F41B S2T Bug Report" about: Create a report to help us improve title: "[S2T]XXXX" labels: Bug, S2T assignees: zh794390558 --- For support and discussions, please use our [Discourse forums](https://github.com/PaddlePaddle/DeepSpeech/discussions). If you've found a bug then please create an issue with the following information: **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** - OS: [e.g. Ubuntu] - GCC/G++ Version [e.g. 8.3] - Python Version [e.g. 3.7] - PaddlePaddle Version [e.g. 2.0.0] - Model Version [e.g. 2.0.0] - GPU/DRIVER Information [e.g. Tesla V100-SXM2-32GB/440.64.00] - CUDA/CUDNN Version [e.g. cuda-10.2] - MKL Version - TensorRT Version **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report-tts.md ================================================ --- name: "\U0001F41B TTS Bug Report" about: Create a report to help us improve title: "[TTS]XXXX" labels: Bug, T2S --- For support and discussions, please use our [Discourse forums](https://github.com/PaddlePaddle/DeepSpeech/discussions). If you've found a bug then please create an issue with the following information: **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** - OS: [e.g. Ubuntu] - GCC/G++ Version [e.g. 8.3] - Python Version [e.g. 3.7] - PaddlePaddle Version [e.g. 2.0.0] - Model Version [e.g. 2.0.0] - GPU/DRIVER Information [e.g. Tesla V100-SXM2-32GB/440.64.00] - CUDA/CUDNN Version [e.g. cuda-10.2] - MKL Version - TensorRT Version **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature-request.md ================================================ --- name: "\U0001F680 Feature Request" about: As a user, I want to request a New Feature on the product. title: '' labels: feature request assignees: D-DanielYang, iftaken --- ## Feature Request **Is your feature request related to a problem? Please describe:** **Describe the feature you'd like:** **Describe alternatives you've considered:** ================================================ FILE: .github/ISSUE_TEMPLATE/others.md ================================================ --- name: "\U0001F9E9 Others" about: Report any other non-support related issues. title: '' labels: '' assignees: '' --- ## Others ================================================ FILE: .github/ISSUE_TEMPLATE/question.md ================================================ --- name: "\U0001F914 Ask a Question" about: I want to ask a question. title: '' labels: Question assignees: '' --- ## General Question ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ### PR types ### PR changes ### Describe ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 45 # Number of days of inactivity before a stale issue is closed daysUntilClose: 30 # Issues with these labels will never be considered stale exemptLabels: - Roadmap - Bug - feature request - Tips # Label to use when marking an issue as stale staleLabel: Stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. unmarkComment: false # Comment to post when closing a stale issue. Set to `false` to disable closeComment: > This issue is closed. Please re-open if needed. ================================================ FILE: .gitignore ================================================ .DS_Store *.pyc .vscode *.log *.wav *.pdmodel *.pdiparams* *.zip *.tar *.tar.gz .ipynb_checkpoints *.npz *.done *.whl *.egg-info build *output/ .history .idea audio/dist/ audio/fc_patch/ docs/build/ docs/topic/ctc/warp-ctc/ tools/venv tools/kenlm tools/sox-14.4.2 tools/soxbindings tools/montreal-forced-aligner/ tools/Montreal-Forced-Aligner/ tools/sctk tools/sctk-20159b5/ tools/kaldi tools/OpenBLAS/ tools/Miniconda3-latest-Linux-x86_64.sh tools/activate_python.sh tools/miniconda.sh tools/CRF++-0.58/ tools/liblbfgs-1.10/ tools/srilm/ tools/env.sh tools/openfst-1.8.1/ tools/libsndfile/ tools/python-soundfile/ tools/onnx tools/onnxruntime tools/Paddle2ONNX tools/onnx-simplifier/ speechx/fc_patch/ third_party/ctc_decoders/paddlespeech_ctcdecoders.py kernel_meta/ ================================================ FILE: .mergify.yml ================================================ pull_request_rules: - name: automatic merge for develop when CI passes and 1 reviews conditions: - "approved-reviews-by>=1" - check-success=Travis CI - Pull Request - base=develop actions: merge: method: merge - name: delete head branch after merged conditions: - merged actions: delete_head_branch: {} - name: "add label=auto-merge for PR by mergify" conditions: - author=mergify[bot] actions: label: add: ["auto-merge"] - name: warn on conflicts conditions: - conflict actions: comment: message: This pull request is now in conflict :( label: add: ["conflicts"] - name: unlabel conflicts conditions: - -conflict actions: label: remove: ["conflicts"] - name: "auto add label=Dataset" conditions: - files~=^dataset/ actions: label: add: ["Dataset"] - name: "auto add label=S2T" conditions: - files~=^paddlespeech/s2t/ actions: label: add: ["S2T"] - name: "auto add label=T2S" conditions: - files~=^paddlespeech/t2s/ actions: label: add: ["T2S"] - name: "auto add label=Audio" conditions: - files~=^paddlespeech/audio/ actions: label: add: ["Audio"] - name: "auto add label=Vector" conditions: - files~=^paddlespeech/vector/ actions: label: add: ["Vector"] - name: "auto add label=Text" conditions: - files~=^paddlespeech/text/ actions: label: add: ["Text"] - name: "auto add label=Example" conditions: - files~=^examples/ actions: label: add: ["Example"] - name: "auto add label=CLI" conditions: - files~=^paddlespeech/cli actions: label: add: ["CLI"] - name: "auto add label=Server" conditions: - files~=^paddlespeech/server actions: label: add: ["Server"] - name: "auto add label=Demo" conditions: - files~=^demos/ actions: label: add: ["Demo"] - name: "auto add label=README" conditions: - files~=(README.md|READEME_cn.md) actions: label: add: ["README"] - name: "auto add label=Documentation" conditions: - files~=^(docs/|CHANGELOG.md) actions: label: add: ["Documentation"] - name: "auto add label=CI" conditions: - files~=^(.circleci/|ci/|.github/|.travis.yml|.travis|env.sh) actions: label: add: ["CI"] - name: "auto add label=Installation" conditions: - files~=^(tools/|setup.py|setup.cfg|setup_audio.py) actions: label: add: ["Installation"] - name: "auto add label=Test" conditions: - files~=^(tests/) actions: label: add: ["Test"] - name: "auto add label=mergify" conditions: - files~=^.mergify.yml actions: label: add: ["mergify"] - name: "auto add label=Docker" conditions: - files~=^docker/ actions: label: add: ["Docker"] - name: "auto add label=Deployment" conditions: - files~=^runtime/ actions: label: add: ["Deployment"] ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/pre-commit/mirrors-yapf.git rev: v0.16.0 hooks: - id: yapf files: \.py$ exclude: (?=runtime/engine/kaldi|audio/paddleaudio/src|third_party).*(\.cpp|\.cc|\.h\.hpp|\.py)$ - repo: https://github.com/pre-commit/pre-commit-hooks rev: a11d9314b22d8f8c7556443875b731ef05965464 hooks: - id: check-merge-conflict - id: check-symlinks - id: detect-private-key files: (?!.*paddle)^.*$ - id: end-of-file-fixer files: \.md$ #- id: trailing-whitespace # files: \.md$ - id: requirements-txt-fixer exclude: (?=third_party).*$ - id: check-yaml - id: check-json - id: pretty-format-json args: - --no-sort-keys - --autofix - id: check-merge-conflict # - id: flake8 # aergs: # - --ignore=E501,E228,E226,E261,E266,E128,E402,W503 # - --builtins=G,request # - --jobs=1 # exclude: (?=runtime/engine/kaldi|audio/paddleaudio/src|third_party).*(\.cpp|\.cc|\.h\.hpp|\.py)$ - repo : https://github.com/Lucas-C/pre-commit-hooks rev: v1.0.1 hooks: - id: forbid-crlf files: \.md$ - id: remove-crlf files: \.md$ - id: forbid-tabs files: \.md$ - id: remove-tabs files: \.md$ - repo: local hooks: - id: clang-format name: clang-format description: Format files with ClangFormat entry: bash .pre-commit-hooks/clang-format.hook -i language: system files: \.(h\+\+|h|hh|hxx|hpp|cuh|c|cc|cpp|cu|c\+\+|cxx|tpp|txx)$ exclude: (?=runtime/engine/kaldi|audio/paddleaudio/src|runtime/patch|runtime/tools/fstbin|runtime/tools/lmbin|third_party/ctc_decoders|runtime/engine/common/utils).*(\.cpp|\.cc|\.h|\.hpp|\.py)$ - id: cpplint name: cpplint description: Static code analysis of C/C++ files language: python files: \.(h\+\+|h|hh|hxx|hpp|cuh|c|cc|cpp|cu|c\+\+|cxx|tpp|txx)$ exclude: (?=runtime/engine/kaldi|runtime/engine/common/matrix|audio/paddleaudio/src|runtime/patch|runtime/tools/fstbin|runtime/tools/lmbin|third_party/ctc_decoders|runtime/engine/common/utils).*(\.cpp|\.cc|\.h|\.hpp|\.py)$ entry: cpplint --filter=-build,-whitespace,+whitespace/comma,-whitespace/indent - repo: https://github.com/asottile/reorder_python_imports rev: v2.4.0 hooks: - id: reorder-python-imports exclude: (?=runtime/engine/kaldi|audio/paddleaudio/src|runtime/patch|runtime/tools/fstbin|runtime/tools/lmbin|third_party/ctc_decoders).*(\.cpp|\.cc|\.h\.hpp|\.py)$ ================================================ FILE: .pre-commit-hooks/clang-format.hook ================================================ #!/usr/bin/env bash set -e readonly VERSION="3.9" version=$(clang-format -version) # if ! [[ $version == *"$VERSION"* ]]; then # echo "clang-format version check failed." # echo "a version contains '$VERSION' is needed, but get '$version'" # echo "you can install the right version, and make an soft-link to '\$PATH' env" # exit -1 # fi clang-format $@ ================================================ FILE: .pre-commit-hooks/copyright-check.hook ================================================ # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # 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. import argparse import io, re import sys, os import subprocess import platform COPYRIGHT = ''' Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved. 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. ''' LANG_COMMENT_MARK = None NEW_LINE_MARK = None COPYRIGHT_HEADER = None if platform.system() == "Windows": NEW_LINE_MARK = "\r\n" else: NEW_LINE_MARK = '\n' COPYRIGHT_HEADER = COPYRIGHT.split(NEW_LINE_MARK)[1] p = re.search('(\d{4})', COPYRIGHT_HEADER).group(0) process = subprocess.Popen(["date", "+%Y"], stdout=subprocess.PIPE) date, err = process.communicate() date = date.decode("utf-8").rstrip("\n") COPYRIGHT_HEADER = COPYRIGHT_HEADER.replace(p, date) def generate_copyright(template, lang='C'): if lang == 'Python': LANG_COMMENT_MARK = '#' else: LANG_COMMENT_MARK = "//" lines = template.split(NEW_LINE_MARK) BLANK = " " ans = LANG_COMMENT_MARK + BLANK + COPYRIGHT_HEADER + NEW_LINE_MARK for lino, line in enumerate(lines): if lino == 0 or lino == 1 or lino == len(lines) - 1: continue if len(line) == 0: BLANK = "" else: BLANK = " " ans += LANG_COMMENT_MARK + BLANK + line + NEW_LINE_MARK return ans + "\n" def lang_type(filename): if filename.endswith(".py"): return "Python" elif filename.endswith(".h"): return "C" elif filename.endswith(".c"): return "C" elif filename.endswith(".hpp"): return "C" elif filename.endswith(".cc"): return "C" elif filename.endswith(".cpp"): return "C" elif filename.endswith(".cu"): return "C" elif filename.endswith(".cuh"): return "C" elif filename.endswith(".go"): return "C" elif filename.endswith(".proto"): return "C" else: print("Unsupported filetype %s", filename) exit(0) PYTHON_ENCODE = re.compile("^[ \t\v]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)") def main(argv=None): parser = argparse.ArgumentParser( description='Checker for copyright declaration.') parser.add_argument('filenames', nargs='*', help='Filenames to check') args = parser.parse_args(argv) retv = 0 for filename in args.filenames: fd = io.open(filename, encoding="utf-8") first_line = fd.readline() second_line = fd.readline() if "COPYRIGHT (C)" in first_line.upper(): continue if first_line.startswith("#!") or PYTHON_ENCODE.match( second_line) != None or PYTHON_ENCODE.match(first_line) != None: continue original_contents = io.open(filename, encoding="utf-8").read() new_contents = generate_copyright( COPYRIGHT, lang_type(filename)) + original_contents print('Auto Insert Copyright Header {}'.format(filename)) retv = 1 with io.open(filename, 'w') as output_file: output_file.write(new_contents) return retv if __name__ == '__main__': exit(main()) ================================================ FILE: .readthedocs.yml ================================================ # .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/source/conf.py # Build documentation with MkDocs #mkdocs: # configuration: mkdocs.yml # Optionally build your docs in additional formats such as PDF formats: [] # Optionally set the version of Python and requirements required to build your docs python: version: 3.7 install: - requirements: docs/requirements.txt - method: setuptools path: . system_packages: true ================================================ FILE: .style.yapf ================================================ [style] based_on_style = pep8 column_limit = 80 ================================================ FILE: .travis.yml ================================================ language: cpp cache: ccache sudo: required dist: Bionic services: - docker os: - linux env: - JOB=PRE_COMMIT addons: apt: packages: - git - python3-pip - python3-dev before_install: - python3 --version - python3 -m pip --version - pip3 --version - sudo pip3 install -U virtualenv pre-commit pip - docker pull paddlepaddle/paddle:latest script: - exit_code=0 - docker run -i --rm -v "$PWD:/py_unittest" paddlepaddle/paddle:latest /bin/bash -c 'cd /py_unittest && bash .travis/precommit.sh && source env.sh && bash .travis/unittest.sh' || exit_code=$(( exit_code | $? )) exit $exit_code notifications: email: on_success: change on_failure: always ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: MANIFEST.in ================================================ include paddlespeech/t2s/exps/*.txt include paddlespeech/t2s/frontend/*.yaml ================================================ FILE: README.md ================================================ ([简体中文](./README_cn.md)|English)

Quick Start | Documents | Models List | AIStudio Courses | NAACL2022 Best Demo Award Paper | Gitee

------------------------------------------------------------------------------------ **PaddleSpeech** is an open-source toolkit on [PaddlePaddle](https://github.com/PaddlePaddle/Paddle) platform for a variety of critical tasks in speech and audio, with the state-of-art and influential models. **PaddleSpeech** won the [NAACL2022 Best Demo Award](https://2022.naacl.org/blog/best-demo-award/), please check out our paper on [Arxiv](https://arxiv.org/abs/2205.12007). ##### Speech Recognition
Input Audio Recognition Result

I knocked at the door on the ancient side of the building.

我认为跑步最重要的就是给我带来了身体健康。
##### Speech Translation (English to Chinese)
Input Audio Translations Result

我 在 这栋 建筑 的 古老 门上 敲门。
##### Text-to-Speech
Input Text Synthetic Audio
Life was like a box of chocolates, you never know what you're gonna get.
早上好,今天是2020/10/29,最低温度是-3°C。
季姬寂,集鸡,鸡即棘鸡。棘鸡饥叽,季姬及箕稷济鸡。鸡既济,跻姬笈,季姬忌,急咭鸡,鸡急,继圾几,季姬急,即籍箕击鸡,箕疾击几伎,伎即齑,鸡叽集几基,季姬急极屐击鸡,鸡既殛,季姬激,即记《季姬击鸡记》。
大家好,我是 parrot 虚拟老师,我们来读一首诗,我与春风皆过客,I and the spring breeze are passing by,你携秋水揽星河,you take the autumn water to take the galaxy。
宜家唔系事必要你讲,但系你所讲嘅说话将会变成呈堂证供。
各个国家有各个国家嘅国歌
For more synthesized audios, please refer to [PaddleSpeech Text-to-Speech samples](https://paddlespeech.readthedocs.io/en/latest/tts/demo.html). ##### Punctuation Restoration
Input Text Output Text
今天的天气真不错啊你下午有空吗我想约你一起去吃饭 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。
### Features Via the easy-to-use, efficient, flexible and scalable implementation, our vision is to empower both industrial application and academic research, including training, inference & testing modules, and deployment process. To be more specific, this toolkit features at: - 📦 **Ease of Use**: low barriers to install, [CLI](#quick-start), [Server](#quick-start-server), and [Streaming Server](#quick-start-streaming-server) is available to quick-start your journey. - 🏆 **Align to the State-of-the-Art**: we provide high-speed and ultra-lightweight models, and also cutting-edge technology. - 🏆 **Streaming ASR and TTS System**: we provide production ready streaming asr and streaming tts system. - 💯 **Rule-based Chinese frontend**: our frontend contains Text Normalization and Grapheme-to-Phoneme (G2P, including Polyphone and Tone Sandhi). Moreover, we use self-defined linguistic rules to adapt Chinese context. - 📦 **Varieties of Functions that Vitalize both Industrial and Academia**: - 🛎️ *Implementation of critical audio tasks*: this toolkit contains audio functions like Automatic Speech Recognition, Text-to-Speech Synthesis, Speaker Verification, KeyWord Spotting, Audio Classification, and Speech Translation, etc. - 🔬 *Integration of mainstream models and datasets*: the toolkit implements modules that participate in the whole pipeline of the speech tasks, and uses mainstream datasets like LibriSpeech, LJSpeech, AIShell, CSMSC, etc. See also [model list](#model-list) for more details. - 🧩 *Cascaded models application*: as an extension of the typical traditional audio tasks, we combine the workflows of the aforementioned tasks with other fields like Natural language processing (NLP) and Computer Vision (CV). ### Recent Update - 🎉 2025.09.01: Add [Whisper large v3 and turbo model](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/demos/whisper). - 🤗 2025.08.11: Add [code-switch online model and server demo](./examples/tal_cs/asr1/). - 👑 2023.05.31: Add [WavLM ASR-en](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/examples/librispeech/asr5), WavLM fine-tuning for ASR on LibriSpeech. - 🎉 2023.05.18: Add [Squeezeformer](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/examples/aishell/asr1), Squeezeformer training for ASR on Aishell. - 👑 2023.05.04: Add [HuBERT ASR-en](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/examples/librispeech/asr4), HuBERT fine-tuning for ASR on LibriSpeech. - ⚡ 2023.04.28: Fix [0-d tensor](https://github.com/PaddlePaddle/PaddleSpeech/pull/3214), with the upgrade of paddlepaddle==2.5, the problem of modifying 0-d tensor has been solved. - 👑 2023.04.25: Add [AMP for U2 conformer](https://github.com/PaddlePaddle/PaddleSpeech/pull/3167). - 🔥 2023.04.06: Add [subtitle file (.srt format) generation example](./demos/streaming_asr_server). - 🔥 2023.03.14: Add SVS(Singing Voice Synthesis) examples with Opencpop dataset, including [DiffSinger](./examples/opencpop/svs1)、[PWGAN](./examples/opencpop/voc1) and [HiFiGAN](./examples/opencpop/voc5), the effect is continuously optimized. - 👑 2023.03.09: Add [Wav2vec2ASR-zh](./examples/aishell/asr3). - 🎉 2023.03.07: Add [TTS ARM Linux C++ Demo (with C++ Chinese Text Frontend)](./demos/TTSArmLinux). - 🔥 2023.03.03 Add Voice Conversion [StarGANv2-VC synthesize pipeline](./examples/vctk/vc3). - 🎉 2023.02.16: Add [Cantonese TTS](./examples/canton/tts3). - 🔥 2023.01.10: Add [code-switch asr CLI and Demos](./demos/speech_recognition). - 👑 2023.01.06: Add [code-switch asr tal_cs recipe](./examples/tal_cs/asr1/). - 🎉 2022.12.02: Add [end-to-end Prosody Prediction pipeline](./examples/csmsc/tts3_rhy) (including using prosody labels in Acoustic Model). - 🎉 2022.11.30: Add [TTS Android Demo](./demos/TTSAndroid). - 🤗 2022.11.28: PP-TTS and PP-ASR demos are available in [AIStudio](https://aistudio.baidu.com/aistudio/modelsoverview) and [official website of paddlepaddle](https://www.paddlepaddle.org.cn/models). - 👑 2022.11.18: Add [Whisper CLI and Demos](https://github.com/PaddlePaddle/PaddleSpeech/pull/2640), support multi language recognition and translation. - 🔥 2022.11.18: Add [Wav2vec2 CLI and Demos](./demos/speech_ssl), Support ASR and Feature Extraction. - 🎉 2022.11.17: Add [male voice for TTS](https://github.com/PaddlePaddle/PaddleSpeech/pull/2660). - 🔥 2022.11.07: Add [U2/U2++ C++ High Performance Streaming ASR Deployment](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/runtime/examples/u2pp_ol/wenetspeech). - 👑 2022.11.01: Add [Adversarial Loss](https://arxiv.org/pdf/1907.04448.pdf) for [Chinese English mixed TTS](./examples/zh_en_tts/tts3). - 🔥 2022.10.26: Add [Prosody Prediction](./examples/other/rhy) for TTS. - 🎉 2022.10.21: Add [SSML](https://github.com/PaddlePaddle/PaddleSpeech/discussions/2538) for TTS Chinese Text Frontend. - 👑 2022.10.11: Add [Wav2vec2ASR-en](./examples/librispeech/asr3), wav2vec2.0 fine-tuning for ASR on LibriSpeech. - 🔥 2022.09.26: Add Voice Cloning, TTS finetune, and [ERNIE-SAT](https://arxiv.org/abs/2211.03545) in [PaddleSpeech Web Demo](./demos/speech_web). - ⚡ 2022.09.09: Add AISHELL-3 Voice Cloning [example](./examples/aishell3/vc2) with ECAPA-TDNN speaker encoder. - ⚡ 2022.08.25: Release TTS [finetune](./examples/other/tts_finetune/tts3) example. - 🔥 2022.08.22: Add [ERNIE-SAT](https://arxiv.org/abs/2211.03545) models: [ERNIE-SAT-vctk](./examples/vctk/ernie_sat)、[ERNIE-SAT-aishell3](./examples/aishell3/ernie_sat)、[ERNIE-SAT-zh_en](./examples/aishell3_vctk/ernie_sat). - 🔥 2022.08.15: Add [g2pW](https://github.com/GitYCC/g2pW) into TTS Chinese Text Frontend. - 🔥 2022.08.09: Release [Chinese English mixed TTS](./examples/zh_en_tts/tts3). - ⚡ 2022.08.03: Add ONNXRuntime infer for TTS CLI. - 🎉 2022.07.18: Release VITS: [VITS-csmsc](./examples/csmsc/vits)、[VITS-aishell3](./examples/aishell3/vits)、[VITS-VC](./examples/aishell3/vits-vc). - 🎉 2022.06.22: All TTS models support ONNX format. - 🍀 2022.06.17: Add [PaddleSpeech Web Demo](./demos/speech_web). - 👑 2022.05.13: Release [PP-ASR](./docs/source/asr/PPASR.md)、[PP-TTS](./docs/source/tts/PPTTS.md)、[PP-VPR](docs/source/vpr/PPVPR.md). - 👏🏻 2022.05.06: `PaddleSpeech Streaming Server` is available for `Streaming ASR` with `Punctuation Restoration` and `Token Timestamp` and `Text-to-Speech`. - 👏🏻 2022.05.06: `PaddleSpeech Server` is available for `Audio Classification`, `Automatic Speech Recognition` and `Text-to-Speech`, `Speaker Verification` and `Punctuation Restoration`. - 👏🏻 2022.03.28: `PaddleSpeech CLI` is available for `Speaker Verification`. - 👏🏻 2021.12.10: `PaddleSpeech CLI` is available for `Audio Classification`, `Automatic Speech Recognition`, `Speech Translation (English to Chinese)` and `Text-to-Speech`. ### Community - Scan the QR code below with your Wechat, you can access to official technical exchange group and get the bonus ( more than 20GB learning materials, such as papers, codes and videos ) and the live link of the lessons. Look forward to your participation.
## Installation We strongly recommend our users to install PaddleSpeech in **Linux** with *python>=3.8*. ### **Dependency Introduction** + gcc >= 4.8.5 + paddlepaddle + python >= 3.8 + OS support: Linux(recommend), Windows, Mac OSX PaddleSpeech depends on paddlepaddle. For installation, please refer to the official website of [paddlepaddle](https://www.paddlepaddle.org.cn/en) and choose according to your own machine. Here is an example of the cpu version. ```bash pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple ``` You can also specify the version of paddlepaddle or install the develop version. ```bash # install 2.4.1 version. Note, 2.4.1 is just an example, please follow the minimum dependency of paddlepaddle for your selection pip install paddlepaddle==2.4.1 -i https://mirror.baidu.com/pypi/simple # install develop version pip install paddlepaddle==0.0.0 -f https://www.paddlepaddle.org.cn/whl/linux/cpu-mkl/develop.html ``` There are two quick installation methods for PaddleSpeech, one is pip installation, and the other is source code compilation (recommended). ### pip install ```shell pip install pytest-runner pip install paddlespeech ``` ### source code compilation ```shell git clone https://github.com/PaddlePaddle/PaddleSpeech.git cd PaddleSpeech pip install pytest-runner pip install . # If you need to install in editable mode, you need to use --use-pep517. The command is as follows: # pip install -e . --use-pep517 ``` For more installation problems, such as conda environment, librosa-dependent, gcc problems, kaldi installation, etc., you can refer to this [installation document](./docs/source/install.md). If you encounter problems during installation, you can leave a message on [#2150](https://github.com/PaddlePaddle/PaddleSpeech/issues/2150) and find related problems ## Quick Start Developers can have a try of our models with [PaddleSpeech Command Line](./paddlespeech/cli/README.md) or Python. Change `--input` to test your own audio/text and support 16k wav format audio. **You can also quickly experience it in AI Studio 👉🏻 [PaddleSpeech API Demo](https://aistudio.baidu.com/aistudio/projectdetail/4353348?sUid=2470186&shared=1&ts=1660876445786)** Test audio sample download ```shell wget -c https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav wget -c https://paddlespeech.cdn.bcebos.com/PaddleAudio/en.wav ``` ### Automatic Speech Recognition
 (Click to expand)Open Source Speech Recognition **command line experience** ```shell paddlespeech asr --lang zh --input zh.wav ``` **Python API experience** ```python >>> from paddlespeech.cli.asr.infer import ASRExecutor >>> asr = ASRExecutor() >>> result = asr(audio_file="zh.wav") >>> print(result) 我认为跑步最重要的就是给我带来了身体健康 ```
### Text-to-Speech
 Open Source Speech Synthesis Output 24k sample rate wav format audio **command line experience** ```shell paddlespeech tts --input "你好,欢迎使用百度飞桨深度学习框架!" --output output.wav ``` **Python API experience** ```python >>> from paddlespeech.cli.tts.infer import TTSExecutor >>> tts = TTSExecutor() >>> tts(text="今天天气十分不错。", output="output.wav") ``` - You can experience in [Huggingface Spaces](https://huggingface.co/spaces) [TTS Demo](https://huggingface.co/spaces/KPatrick/PaddleSpeechTTS)
### Audio Classification
 An open-domain sound classification tool Sound classification model based on 527 categories of AudioSet dataset **command line experience** ```shell paddlespeech cls --input zh.wav ``` **Python API experience** ```python >>> from paddlespeech.cli.cls.infer import CLSExecutor >>> cls = CLSExecutor() >>> result = cls(audio_file="zh.wav") >>> print(result) Speech 0.9027186632156372 ```
### Voiceprint Extraction
 Industrial-grade voiceprint extraction tool **command line experience** ```shell paddlespeech vector --task spk --input zh.wav ``` **Python API experience** ```python >>> from paddlespeech.cli.vector import VectorExecutor >>> vec = VectorExecutor() >>> result = vec(audio_file="zh.wav") >>> print(result) # 187维向量 [ -0.19083306 9.474295 -14.122263 -2.0916545 0.04848729 4.9295826 1.4780062 0.3733844 10.695862 3.2697146 -4.48199 -0.6617882 -9.170393 -11.1568775 -1.2358263 ...] ```
### Punctuation Restoration
 Quick recovery of text punctuation, works with ASR models **command line experience** ```shell paddlespeech text --task punc --input 今天的天气真不错啊你下午有空吗我想约你一起去吃饭 ``` **Python API experience** ```python >>> from paddlespeech.cli.text.infer import TextExecutor >>> text_punc = TextExecutor() >>> result = text_punc(text="今天的天气真不错啊你下午有空吗我想约你一起去吃饭") 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。 ```
### Speech Translation
 End-to-end English to Chinese Speech Translation Tool Use pre-compiled kaldi related tools, only support experience in Ubuntu system **command line experience** ```shell paddlespeech st --input en.wav ``` **Python API experience** ```python >>> from paddlespeech.cli.st.infer import STExecutor >>> st = STExecutor() >>> result = st(audio_file="en.wav") ['我 在 这栋 建筑 的 古老 门上 敲门 。'] ```
## Quick Start Server Developers can have a try of our speech server with [PaddleSpeech Server Command Line](./paddlespeech/server/README.md). **You can try it quickly in AI Studio (recommend): [SpeechServer](https://aistudio.baidu.com/aistudio/projectdetail/4354592?sUid=2470186&shared=1&ts=1660877827034)** **Start server** ```shell paddlespeech_server start --config_file ./demos/speech_server/conf/application.yaml ``` **Access Speech Recognition Services** ```shell paddlespeech_client asr --server_ip 127.0.0.1 --port 8090 --input input_16k.wav ``` **Access Text to Speech Services** ```shell paddlespeech_client tts --server_ip 127.0.0.1 --port 8090 --input "您好,欢迎使用百度飞桨语音合成服务。" --output output.wav ``` **Access Audio Classification Services** ```shell paddlespeech_client cls --server_ip 127.0.0.1 --port 8090 --input input.wav ``` For more information about server command lines, please see: [speech server demos](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/demos/speech_server) ## Quick Start Streaming Server Developers can have a try of [streaming asr](./demos/streaming_asr_server/README.md) and [streaming tts](./demos/streaming_tts_server/README.md) server. **Start Streaming Speech Recognition Server** ``` paddlespeech_server start --config_file ./demos/streaming_asr_server/conf/application.yaml ``` **Access Streaming Speech Recognition Services** ``` paddlespeech_client asr_online --server_ip 127.0.0.1 --port 8090 --input input_16k.wav ``` **Start Streaming Text to Speech Server** ``` paddlespeech_server start --config_file ./demos/streaming_tts_server/conf/tts_online_application.yaml ``` **Access Streaming Text to Speech Services** ``` paddlespeech_client tts_online --server_ip 127.0.0.1 --port 8092 --protocol http --input "您好,欢迎使用百度飞桨语音合成服务。" --output output.wav ``` For more information please see: [streaming asr](./demos/streaming_asr_server/README.md) and [streaming tts](./demos/streaming_tts_server/README.md) ## Model List PaddleSpeech supports a series of most popular models. They are summarized in [released models](./docs/source/released_model.md) and attached with available pretrained models. **Speech-to-Text** contains *Acoustic Model*, *Language Model*, and *Speech Translation*, with the following details:
Speech-to-Text Module Type Dataset Model Type Example
Speech Recogination Aishell DeepSpeech2 RNN + Conv based Models deepspeech2-aishell
Transformer based Attention Models u2.transformer.conformer-aishell
Librispeech Transformer based Attention Models deepspeech2-librispeech / transformer.conformer.u2-librispeech / transformer.conformer.u2-kaldi-librispeech
TIMIT Unified Streaming & Non-streaming Two-pass u2-timit
Alignment THCHS30 MFA mfa-thchs30
Language Model Ngram Language Model kenlm
Speech Translation (English to Chinese) TED En-Zh Transformer + ASR MTL transformer-ted
FAT + Transformer + ASR MTL fat-st-ted
**Text-to-Speech** in PaddleSpeech mainly contains three modules: *Text Frontend*, *Acoustic Model* and *Vocoder*. Acoustic Model and Vocoder models are listed as follow:
Text-to-Speech Module Type Model Type Dataset Example
Text Frontend tn / g2p
Acoustic Model Tacotron2 LJSpeech / CSMSC tacotron2-ljspeech / tacotron2-csmsc
Transformer TTS LJSpeech transformer-ljspeech
SpeedySpeech CSMSC speedyspeech-csmsc
FastSpeech2 LJSpeech / VCTK / CSMSC / AISHELL-3 / ZH_EN / finetune fastspeech2-ljspeech / fastspeech2-vctk / fastspeech2-csmsc / fastspeech2-aishell3 / fastspeech2-zh_en / fastspeech2-finetune
ERNIE-SAT VCTK / AISHELL-3 / ZH_EN ERNIE-SAT-vctk / ERNIE-SAT-aishell3 / ERNIE-SAT-zh_en
DiffSinger Opencpop DiffSinger-opencpop
Vocoder WaveFlow LJSpeech waveflow-ljspeech
Parallel WaveGAN LJSpeech / VCTK / CSMSC / AISHELL-3 / Opencpop PWGAN-ljspeech / PWGAN-vctk / PWGAN-csmsc / PWGAN-aishell3 / PWGAN-opencpop
Multi Band MelGAN CSMSC Multi Band MelGAN-csmsc
Style MelGAN CSMSC Style MelGAN-csmsc
HiFiGAN LJSpeech / VCTK / CSMSC / AISHELL-3 / Opencpop HiFiGAN-ljspeech / HiFiGAN-vctk / HiFiGAN-csmsc / HiFiGAN-aishell3 / HiFiGAN-opencpop
WaveRNN CSMSC WaveRNN-csmsc
Voice Cloning GE2E Librispeech, etc. GE2E
SV2TTS (GE2E + Tacotron2) AISHELL-3 VC0
SV2TTS (GE2E + FastSpeech2) AISHELL-3 VC1
SV2TTS (ECAPA-TDNN + FastSpeech2) AISHELL-3 VC2
GE2E + VITS AISHELL-3 VITS-VC
End-to-End VITS CSMSC / AISHELL-3 VITS-csmsc / VITS-aishell3
**Audio Classification**
Task Dataset Model Type Example
Audio Classification ESC-50 PANN pann-esc50
**Keyword Spotting**
Task Dataset Model Type Example
Keyword Spotting hey-snips MDTC mdtc-hey-snips
**Speaker Verification**
Task Dataset Model Type Example
Speaker Verification VoxCeleb1/2 ECAPA-TDNN ecapa-tdnn-voxceleb12
**Speaker Diarization**
Task Dataset Model Type Example
Speaker Diarization AMI ECAPA-TDNN + AHC / SC ecapa-tdnn-ami
**Punctuation Restoration**
Task Dataset Model Type Example
Punctuation Restoration IWLST2012_zh Ernie Linear iwslt2012-punc0
## Documents Normally, [Speech SoTA](https://paperswithcode.com/area/speech), [Audio SoTA](https://paperswithcode.com/area/audio) and [Music SoTA](https://paperswithcode.com/area/music) give you an overview of the hot academic topics in the related area. To focus on the tasks in PaddleSpeech, you will find the following guidelines are helpful to grasp the core ideas. - [Installation](./docs/source/install.md) - [Quick Start](#quickstart) - [Some Demos](./demos/README.md) - Tutorials - [Automatic Speech Recognition](./docs/source/asr/quick_start.md) - [Introduction](./docs/source/asr/models_introduction.md) - [Data Preparation](./docs/source/asr/data_preparation.md) - [Ngram LM](./docs/source/asr/ngram_lm.md) - [Text-to-Speech](./docs/source/tts/quick_start.md) - [Introduction](./docs/source/tts/models_introduction.md) - [Advanced Usage](./docs/source/tts/advanced_usage.md) - [Chinese Rule Based Text Frontend](./docs/source/tts/zh_text_frontend.md) - [Test Audio Samples](https://paddlespeech.readthedocs.io/en/latest/tts/demo.html) - Speaker Verification - [Audio Searching](./demos/audio_searching/README.md) - [Speaker Verification](./demos/speaker_verification/README.md) - [Audio Classification](./demos/audio_tagging/README.md) - [Speech Translation](./demos/speech_translation/README.md) - [Speech Server](./demos/speech_server/README.md) - [Released Models](./docs/source/released_model.md) - [Speech-to-Text](#SpeechToText) - [Text-to-Speech](#TextToSpeech) - [Audio Classification](#AudioClassification) - [Speaker Verification](#SpeakerVerification) - [Speaker Diarization](#SpeakerDiarization) - [Punctuation Restoration](#PunctuationRestoration) - [Community](#Community) - [Welcome to contribute](#contribution) - [License](#License) The Text-to-Speech module is originally called [Parakeet](https://github.com/PaddlePaddle/Parakeet), and now merged with this repository. If you are interested in academic research about this task, please see [TTS research overview](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/docs/source/tts#overview). Also, [this document](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/docs/source/tts/models_introduction.md) is a good guideline for the pipeline components. ## ⭐ Examples - **[PaddleBoBo](https://github.com/JiehangXie/PaddleBoBo): Use PaddleSpeech TTS to generate virtual human voice.**
- [PaddleSpeech Demo Video](https://paddlespeech.readthedocs.io/en/latest/demo_video.html) - **[VTuberTalk](https://github.com/jerryuhoo/VTuberTalk): Use PaddleSpeech TTS and ASR to clone voice from videos.** ## Citation To cite PaddleSpeech for research, please use the following format. ```text @inproceedings{zhang2022paddlespeech, title = {PaddleSpeech: An Easy-to-Use All-in-One Speech Toolkit}, author = {Hui Zhang, Tian Yuan, Junkun Chen, Xintong Li, Renjie Zheng, Yuxin Huang, Xiaojie Chen, Enlei Gong, Zeyu Chen, Xiaoguang Hu, dianhai yu, Yanjun Ma, Liang Huang}, booktitle = {Proceedings of the 2022 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies: Demonstrations}, year = {2022}, publisher = {Association for Computational Linguistics}, } @InProceedings{pmlr-v162-bai22d, title = {{A}$^3${T}: Alignment-Aware Acoustic and Text Pretraining for Speech Synthesis and Editing}, author = {Bai, He and Zheng, Renjie and Chen, Junkun and Ma, Mingbo and Li, Xintong and Huang, Liang}, booktitle = {Proceedings of the 39th International Conference on Machine Learning}, pages = {1399--1411}, year = {2022}, volume = {162}, series = {Proceedings of Machine Learning Research}, month = {17--23 Jul}, publisher = {PMLR}, pdf = {https://proceedings.mlr.press/v162/bai22d/bai22d.pdf}, url = {https://proceedings.mlr.press/v162/bai22d.html}, } @inproceedings{zheng2021fused, title={Fused acoustic and text encoding for multimodal bilingual pretraining and speech translation}, author={Zheng, Renjie and Chen, Junkun and Ma, Mingbo and Huang, Liang}, booktitle={International Conference on Machine Learning}, pages={12736--12746}, year={2021}, organization={PMLR} } ``` ## Contribute to PaddleSpeech You are warmly welcome to submit questions in [discussions](https://github.com/PaddlePaddle/PaddleSpeech/discussions) and bug reports in [issues](https://github.com/PaddlePaddle/PaddleSpeech/issues)! Also, we highly appreciate if you are willing to contribute to this project! ### Contributors

## Acknowledgement - Many thanks to [HighCWu](https://github.com/HighCWu) for adding [VITS-aishell3](./examples/aishell3/vits) and [VITS-VC](./examples/aishell3/vits-vc) examples. - Many thanks to [david-95](https://github.com/david-95) for fixing multi-punctuation bug、contributing to multiple program and data, and adding [SSML](https://github.com/PaddlePaddle/PaddleSpeech/discussions/2538) for TTS Chinese Text Frontend. - Many thanks to [BarryKCL](https://github.com/BarryKCL) for improving TTS Chinses Frontend based on [G2PW](https://github.com/GitYCC/g2pW). - Many thanks to [yeyupiaoling](https://github.com/yeyupiaoling)/[PPASR](https://github.com/yeyupiaoling/PPASR)/[PaddlePaddle-DeepSpeech](https://github.com/yeyupiaoling/PaddlePaddle-DeepSpeech)/[VoiceprintRecognition-PaddlePaddle](https://github.com/yeyupiaoling/VoiceprintRecognition-PaddlePaddle)/[AudioClassification-PaddlePaddle](https://github.com/yeyupiaoling/AudioClassification-PaddlePaddle) for years of attention, constructive advice and great help. - Many thanks to [mymagicpower](https://github.com/mymagicpower) for the Java implementation of ASR upon [short](https://github.com/mymagicpower/AIAS/tree/main/3_audio_sdks/asr_sdk) and [long](https://github.com/mymagicpower/AIAS/tree/main/3_audio_sdks/asr_long_audio_sdk) audio files. - Many thanks to [JiehangXie](https://github.com/JiehangXie)/[PaddleBoBo](https://github.com/JiehangXie/PaddleBoBo) for developing Virtual Uploader(VUP)/Virtual YouTuber(VTuber) with PaddleSpeech TTS function. - Many thanks to [745165806](https://github.com/745165806)/[PaddleSpeechTask](https://github.com/745165806/PaddleSpeechTask) for contributing Punctuation Restoration model. - Many thanks to [kslz](https://github.com/745165806) for supplementary Chinese documents. - Many thanks to [awmmmm](https://github.com/awmmmm) for contributing fastspeech2 aishell3 conformer pretrained model. - Many thanks to [phecda-xu](https://github.com/phecda-xu)/[PaddleDubbing](https://github.com/phecda-xu/PaddleDubbing) for developing a dubbing tool with GUI based on PaddleSpeech TTS model. - Many thanks to [jerryuhoo](https://github.com/jerryuhoo)/[VTuberTalk](https://github.com/jerryuhoo/VTuberTalk) for developing a GUI tool based on PaddleSpeech TTS and code for making datasets from videos based on PaddleSpeech ASR. - Many thanks to [vpegasus](https://github.com/vpegasus)/[xuesebot](https://github.com/vpegasus/xuesebot) for developing a rasa chatbot,which is able to speak and listen thanks to PaddleSpeech. - Many thanks to [chenkui164](https://github.com/chenkui164)/[FastASR](https://github.com/chenkui164/FastASR) for the C++ inference implementation of PaddleSpeech ASR. - Many thanks to [heyudage](https://github.com/heyudage)/[VoiceTyping](https://github.com/heyudage/VoiceTyping) for the real-time voice typing tool implementation of PaddleSpeech ASR streaming services. - Many thanks to [EscaticZheng](https://github.com/EscaticZheng)/[ps3.9wheel-install](https://github.com/EscaticZheng/ps3.9wheel-install) for the python3.9 prebuilt wheel for PaddleSpeech installation in Windows without Visual Studio. Besides, PaddleSpeech depends on a lot of open source repositories. See [references](./docs/source/reference.md) for more information. - Many thanks to [chinobing](https://github.com/chinobing)/[FastAPI-PaddleSpeech-Audio-To-Text](https://github.com/chinobing/FastAPI-PaddleSpeech-Audio-To-Text) for converting audio to text based on FastAPI and PaddleSpeech. - Many thanks to [MistEO](https://github.com/MistEO)/[Pallas-Bot](https://github.com/MistEO/Pallas-Bot) for QQ bot based on PaddleSpeech TTS. ## License PaddleSpeech is provided under the [Apache-2.0 License](./LICENSE). ## Stargazers over time [![Stargazers over time](https://starchart.cc/PaddlePaddle/PaddleSpeech.svg)](https://starchart.cc/PaddlePaddle/PaddleSpeech) ================================================ FILE: README_cn.md ================================================ (简体中文|[English](./README.md))

安装 | 快速开始 | 教程文档 | 模型列表 | AIStudio 课程 | NAACL2022 论文 | Gitee

------------------------------------------------------------------------------------ **PaddleSpeech** 是基于飞桨 [PaddlePaddle](https://github.com/PaddlePaddle/Paddle) 的语音方向的开源模型库,用于语音和音频中的各种关键任务的开发,包含大量基于深度学习前沿和有影响力的模型,一些典型的应用示例如下: **PaddleSpeech** 荣获 [NAACL2022 Best Demo Award](https://2022.naacl.org/blog/best-demo-award/), 请访问 [Arxiv](https://arxiv.org/abs/2205.12007) 论文。 ### 效果展示 ##### 语音识别
输入音频 识别结果

I knocked at the door on the ancient side of the building.

我认为跑步最重要的就是给我带来了身体健康。
##### 语音翻译 (英译中)
输入音频 翻译结果

我 在 这栋 建筑 的 古老 门上 敲门。
##### 语音合成
输入文本 合成音频
Life was like a box of chocolates, you never know what you're gonna get.
早上好,今天是2020/10/29,最低温度是-3°C。
季姬寂,集鸡,鸡即棘鸡。棘鸡饥叽,季姬及箕稷济鸡。鸡既济,跻姬笈,季姬忌,急咭鸡,鸡急,继圾几,季姬急,即籍箕击鸡,箕疾击几伎,伎即齑,鸡叽集几基,季姬急极屐击鸡,鸡既殛,季姬激,即记《季姬击鸡记》。
大家好,我是 parrot 虚拟老师,我们来读一首诗,我与春风皆过客,I and the spring breeze are passing by,你携秋水揽星河,you take the autumn water to take the galaxy。
宜家唔系事必要你讲,但系你所讲嘅说话将会变成呈堂证供。
各个国家有各个国家嘅国歌
更多合成音频,可以参考 [PaddleSpeech 语音合成音频示例](https://paddlespeech.readthedocs.io/en/latest/tts/demo.html)。 ##### 标点恢复
输入文本 输出文本
今天的天气真不错啊你下午有空吗我想约你一起去吃饭 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。
### 特性 本项目采用了易用、高效、灵活以及可扩展的实现,旨在为工业应用、学术研究提供更好的支持,实现的功能包含训练、推断以及测试模块,以及部署过程,主要包括 - 📦 **易用性**: 安装门槛低,可使用 [CLI](#quick-start) 快速开始。 - 🏆 **对标 SoTA**: 提供了高速、轻量级模型,且借鉴了最前沿的技术。 - 🏆 **流式 ASR 和 TTS 系统**:工业级的端到端流式识别、流式合成系统。 - 💯 **基于规则的中文前端**: 我们的前端包含文本正则化和字音转换(G2P)。此外,我们使用自定义语言规则来适应中文语境。 - **多种工业界以及学术界主流功能支持**: - 🛎️ 典型音频任务: 本工具包提供了音频任务如音频分类、语音翻译、自动语音识别、文本转语音、语音合成、声纹识别、KWS等任务的实现。 - 🔬 主流模型及数据集: 本工具包实现了参与整条语音任务流水线的各个模块,并且采用了主流数据集如 LibriSpeech、LJSpeech、AIShell、CSMSC,详情请见 [模型列表](#model-list)。 - 🧩 级联模型应用: 作为传统语音任务的扩展,我们结合了自然语言处理、计算机视觉等任务,实现更接近实际需求的产业级应用。 ### 近期更新 - 🎉 2025.09.01: 新增 [Whisper large v3 与 turbo 模型](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/demos/whisper). - 🤗 2025.08.11: 新增 [流式中英混合 tal_cs 识别模型](./examples/tal_cs/asr1/). - 👑 2023.05.31: 新增 [WavLM ASR-en](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/examples/librispeech/asr5), 基于WavLM的英语识别微调,使用LibriSpeech数据集 - 🎉 2023.05.18: 新增 [Squeezeformer](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/examples/aishell/asr1), 使用Squeezeformer进行训练,使用Aishell数据集 - 👑 2023.05.04: 新增 [HuBERT ASR-en](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/examples/librispeech/asr4), 基于HuBERT的英语识别微调,使用LibriSpeech数据集 - ⚡ 2023.04.28: 修正 [0-d tensor](https://github.com/PaddlePaddle/PaddleSpeech/pull/3214), 配合PaddlePaddle2.5升级修改了0-d tensor的问题。 - 👑 2023.04.25: 新增 [U2 conformer 的 AMP 训练](https://github.com/PaddlePaddle/PaddleSpeech/pull/3167). - 👑 2023.04.06: 新增 [srt格式字幕生成功能](./demos/streaming_asr_server)。 - 🔥 2023.03.14: 新增基于 Opencpop 数据集的 SVS (歌唱合成) 示例,包含 [DiffSinger](./examples/opencpop/svs1)、[PWGAN](./examples/opencpop/voc1) 和 [HiFiGAN](./examples/opencpop/voc5),效果持续优化中。 - 👑 2023.03.09: 新增 [Wav2vec2ASR-zh](./examples/aishell/asr3)。 - 🎉 2023.03.07: 新增 [TTS ARM Linux C++ 部署示例 (包含 C++ 中文文本前端模块)](./demos/TTSArmLinux)。 - 🔥 2023.03.03: 新增声音转换模型 [StarGANv2-VC 合成流程](./examples/vctk/vc3)。 - 🎉 2023.02.16: 新增[粤语语音合成](./examples/canton/tts3)。 - 🔥 2023.01.10: 新增[中英混合 ASR CLI 和 Demos](./demos/speech_recognition)。 - 👑 2023.01.06: 新增 [ASR 中英混合 tal_cs 训练推理流程](./examples/tal_cs/asr1/)。 - 🎉 2022.12.02: 新增[端到端韵律预测全流程](./examples/csmsc/tts3_rhy) (包含在声学模型中使用韵律标签)。 - 🎉 2022.11.30: 新增 [TTS Android 部署示例](./demos/TTSAndroid)。 - 🤗 2022.11.28: PP-TTS and PP-ASR 示例可在 [AIStudio](https://aistudio.baidu.com/aistudio/modelsoverview) 和[飞桨官网](https://www.paddlepaddle.org.cn/models)体验! - 👑 2022.11.18: 新增 [Whisper CLI 和 Demos](https://github.com/PaddlePaddle/PaddleSpeech/pull/2640), 支持多种语言的识别与翻译。 - 🔥 2022.11.18: 新增 [Wav2vec2 CLI 和 Demos](./demos/speech_ssl), 支持 ASR 和特征提取。 - 🎉 2022.11.17: TTS 新增[高质量男性音色](https://github.com/PaddlePaddle/PaddleSpeech/pull/2660)。 - 🔥 2022.11.07: 新增 [U2/U2++ 高性能流式 ASR C++ 部署](./speechx/examples/u2pp_ol/wenetspeech)。 - 👑 2022.11.01: [中英文混合 TTS](./examples/zh_en_tts/tts3) 新增 [Adversarial Loss](https://arxiv.org/pdf/1907.04448.pdf) 模块。 - 🔥 2022.10.26: TTS 新增[韵律预测](./develop/examples/other/rhy)功能。 - 🎉 2022.10.21: TTS 中文文本前端新增 [SSML](https://github.com/PaddlePaddle/PaddleSpeech/discussions/2538) 功能。 - 👑 2022.10.11: 新增 [Wav2vec2ASR-en](./examples/librispeech/asr3), 在 LibriSpeech 上针对 ASR 任务对 wav2vec2.0 的 finetuning。 - 🔥 2022.09.26: 新增 Voice Cloning, TTS finetune 和 [ERNIE-SAT](https://arxiv.org/abs/2211.03545) 到 [PaddleSpeech 网页应用](./demos/speech_web)。 - ⚡ 2022.09.09: 新增基于 ECAPA-TDNN 声纹模型的 AISHELL-3 Voice Cloning [示例](./examples/aishell3/vc2)。 - ⚡ 2022.08.25: 发布 TTS [finetune](./examples/other/tts_finetune/tts3) 示例。 - 🔥 2022.08.22: 新增 [ERNIE-SAT](https://arxiv.org/abs/2211.03545) 模型: [ERNIE-SAT-vctk](./examples/vctk/ernie_sat)、[ERNIE-SAT-aishell3](./examples/aishell3/ernie_sat)、[ERNIE-SAT-zh_en](./examples/aishell3_vctk/ernie_sat)。 - 🔥 2022.08.15: 将 [g2pW](https://github.com/GitYCC/g2pW) 引入 TTS 中文文本前端。 - 🔥 2022.08.09: 发布[中英文混合 TTS](./examples/zh_en_tts/tts3)。 - ⚡ 2022.08.03: TTS CLI 新增 ONNXRuntime 推理方式。 - 🎉 2022.07.18: 发布 VITS 模型: [VITS-csmsc](./examples/csmsc/vits)、[VITS-aishell3](./examples/aishell3/vits)、[VITS-VC](./examples/aishell3/vits-vc)。 - 🎉 2022.06.22: 所有 TTS 模型支持了 ONNX 格式。 - 🍀 2022.06.17: 新增 [PaddleSpeech 网页应用](./demos/speech_web)。 - 👑 2022.05.13: PaddleSpeech 发布 [PP-ASR](./docs/source/asr/PPASR_cn.md) 流式语音识别系统、[PP-TTS](./docs/source/tts/PPTTS_cn.md) 流式语音合成系统、[PP-VPR](docs/source/vpr/PPVPR_cn.md) 全链路声纹识别系统 - 👏🏻 2022.05.06: PaddleSpeech Streaming Server 上线!覆盖了语音识别(标点恢复、时间戳)和语音合成。 - 👏🏻 2022.05.06: PaddleSpeech Server 上线!覆盖了声音分类、语音识别、语音合成、声纹识别,标点恢复。 - 👏🏻 2022.03.28: PaddleSpeech CLI 覆盖声音分类、语音识别、语音翻译(英译中)、语音合成和声纹验证。 - 👏🏻 2021.12.10: PaddleSpeech CLI 支持语音分类, 语音识别, 语音翻译(英译中)和语音合成。 ### 🔥 加入技术交流群获取入群福利 - 3 日直播课链接: 深度解读 【一句话语音合成】【小样本语音合成】【定制化语音识别】语音交互技术 - 20G 学习大礼包:视频课程、前沿论文与学习资料 微信扫描二维码关注公众号,点击“马上报名”填写问卷加入官方交流群,获得更高效的问题答疑,与各行各业开发者充分交流,期待您的加入。
## 安装 我们强烈建议用户在 **Linux** 环境下,*3.8* 以上版本的 *python* 上安装 PaddleSpeech。 ### 相关依赖 + gcc >= 4.8.5 + paddlepaddle + python >= 3.8 + linux(推荐), mac, windows PaddleSpeech 依赖于 paddlepaddle,安装可以参考[ paddlepaddle 官网](https://www.paddlepaddle.org.cn/),根据自己机器的情况进行选择。这里给出 cpu 版本示例,其它版本大家可以根据自己机器的情况进行安装。 ```shell pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple ``` 你也可以安装指定版本的paddlepaddle,或者安装 develop 版本。 ```bash # 安装2.4.1版本. 注意:2.4.1只是一个示例,请按照对paddlepaddle的最小依赖进行选择。 pip install paddlepaddle==2.4.1 -i https://mirror.baidu.com/pypi/simple # 安装 develop 版本 pip install paddlepaddle==0.0.0 -f https://www.paddlepaddle.org.cn/whl/linux/cpu-mkl/develop.html ``` PaddleSpeech 快速安装方式有两种,一种是 pip 安装,一种是源码编译(推荐)。 ### pip 安装 ```shell pip install pytest-runner pip install paddlespeech ``` ### 源码编译 ```shell git clone https://github.com/PaddlePaddle/PaddleSpeech.git cd PaddleSpeech pip install pytest-runner pip install . # 如果需要在可编辑模式下安装,需要使用 --use-pep517,命令如下 # pip install -e . --use-pep517 ``` 更多关于安装问题,如 conda 环境,librosa 依赖的系统库,gcc 环境问题,kaldi 安装等,可以参考这篇[安装文档](docs/source/install_cn.md),如安装上遇到问题可以在 [#2150](https://github.com/PaddlePaddle/PaddleSpeech/issues/2150) 上留言以及查找相关问题 ## 快速开始 安装完成后,开发者可以通过命令行或者 Python 快速开始,命令行模式下改变 `--input` 可以尝试用自己的音频或文本测试,支持 16k wav 格式音频。 你也可以在 `aistudio` 中快速体验 👉🏻[一键预测,快速上手 Speech 开发任务](https://aistudio.baidu.com/aistudio/projectdetail/4353348?sUid=2470186&shared=1&ts=1660878142250)。 测试音频示例下载 ```shell wget -c https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav wget -c https://paddlespeech.cdn.bcebos.com/PaddleAudio/en.wav ``` ### 语音识别
 (点击可展开)开源中文语音识别 命令行一键体验 ```shell paddlespeech asr --lang zh --input zh.wav ``` Python API 一键预测 ```python >>> from paddlespeech.cli.asr.infer import ASRExecutor >>> asr = ASRExecutor() >>> result = asr(audio_file="zh.wav") >>> print(result) 我认为跑步最重要的就是给我带来了身体健康 ```
### 语音合成
 开源中文语音合成 输出 24k 采样率wav格式音频 命令行一键体验 ```shell paddlespeech tts --input "你好,欢迎使用百度飞桨深度学习框架!" --output output.wav ``` Python API 一键预测 ```python >>> from paddlespeech.cli.tts.infer import TTSExecutor >>> tts = TTSExecutor() >>> tts(text="今天天气十分不错。", output="output.wav") ``` - 语音合成的 web demo 已经集成进了 [Huggingface Spaces](https://huggingface.co/spaces). 请参考: [TTS Demo](https://huggingface.co/spaces/KPatrick/PaddleSpeechTTS)
### 声音分类
 适配多场景的开放领域声音分类工具 基于 AudioSet 数据集 527 个类别的声音分类模型 命令行一键体验 ```shell paddlespeech cls --input zh.wav ``` python API 一键预测 ```python >>> from paddlespeech.cli.cls.infer import CLSExecutor >>> cls = CLSExecutor() >>> result = cls(audio_file="zh.wav") >>> print(result) Speech 0.9027186632156372 ```
### 声纹提取
 工业级声纹提取工具 命令行一键体验 ```shell paddlespeech vector --task spk --input zh.wav ``` Python API 一键预测 ```python >>> from paddlespeech.cli.vector import VectorExecutor >>> vec = VectorExecutor() >>> result = vec(audio_file="zh.wav") >>> print(result) # 187维向量 [ -0.19083306 9.474295 -14.122263 -2.0916545 0.04848729 4.9295826 1.4780062 0.3733844 10.695862 3.2697146 -4.48199 -0.6617882 -9.170393 -11.1568775 -1.2358263 ...] ```
### 标点恢复
 一键恢复文本标点,可与ASR模型配合使用 命令行一键体验 ```shell paddlespeech text --task punc --input 今天的天气真不错啊你下午有空吗我想约你一起去吃饭 ``` Python API 一键预测 ```python >>> from paddlespeech.cli.text.infer import TextExecutor >>> text_punc = TextExecutor() >>> result = text_punc(text="今天的天气真不错啊你下午有空吗我想约你一起去吃饭") 今天的天气真不错啊!你下午有空吗?我想约你一起去吃饭。 ```
### 语音翻译
 端到端英译中语音翻译工具 使用预编译的 kaldi 相关工具,只支持在 Ubuntu 系统中体验 命令行一键体验 ```shell paddlespeech st --input en.wav ``` python API 一键预测 ```python >>> from paddlespeech.cli.st.infer import STExecutor >>> st = STExecutor() >>> result = st(audio_file="en.wav") ['我 在 这栋 建筑 的 古老 门上 敲门 。'] ```
## 快速使用服务 安装完成后,开发者可以通过命令行一键启动语音识别,语音合成,音频分类等多种服务。 你可以在 AI Studio 中快速体验:[SpeechServer 一键部署](https://aistudio.baidu.com/aistudio/projectdetail/4354592?sUid=2470186&shared=1&ts=1660878208266) **启动服务** ```shell paddlespeech_server start --config_file ./demos/speech_server/conf/application.yaml ``` **访问语音识别服务** ```shell paddlespeech_client asr --server_ip 127.0.0.1 --port 8090 --input input_16k.wav ``` **访问语音合成服务** ```shell paddlespeech_client tts --server_ip 127.0.0.1 --port 8090 --input "您好,欢迎使用百度飞桨语音合成服务。" --output output.wav ``` **访问音频分类服务** ```shell paddlespeech_client cls --server_ip 127.0.0.1 --port 8090 --input input.wav ``` 更多服务相关的命令行使用信息,请参考 [demos](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/demos/speech_server) ## 快速使用流式服务 开发者可以尝试 [流式 ASR](./demos/streaming_asr_server/README.md) 和 [流式 TTS](./demos/streaming_tts_server/README.md) 服务. **启动流式 ASR 服务** ``` paddlespeech_server start --config_file ./demos/streaming_asr_server/conf/application.yaml ``` **访问流式 ASR 服务** ``` paddlespeech_client asr_online --server_ip 127.0.0.1 --port 8090 --input input_16k.wav ``` **启动流式 TTS 服务** ``` paddlespeech_server start --config_file ./demos/streaming_tts_server/conf/tts_online_application.yaml ``` **访问流式 TTS 服务** ``` paddlespeech_client tts_online --server_ip 127.0.0.1 --port 8092 --protocol http --input "您好,欢迎使用百度飞桨语音合成服务。" --output output.wav ``` 更多信息参看: [流式 ASR](./demos/streaming_asr_server/README.md) 和 [流式 TTS](./demos/streaming_tts_server/README.md) ## 模型列表 PaddleSpeech 支持很多主流的模型,并提供了预训练模型,详情请见[模型列表](./docs/source/released_model.md)。 PaddleSpeech 的 **语音转文本** 包含语音识别声学模型、语音识别语言模型和语音翻译, 详情如下:
语音转文本模块类型 数据集 模型类型 脚本
语音识别 Aishell DeepSpeech2 RNN + Conv based Models deepspeech2-aishell
Transformer based Attention Models u2.transformer.conformer-aishell
Librispeech Transformer based Attention Models deepspeech2-librispeech / transformer.conformer.u2-librispeech / transformer.conformer.u2-kaldi-librispeech
TIMIT Unified Streaming & Non-streaming Two-pass u2-timit
对齐 THCHS30 MFA mfa-thchs30
语言模型 Ngram 语言模型 kenlm
语音翻译(英译中) TED En-Zh Transformer + ASR MTL transformer-ted
FAT + Transformer + ASR MTL fat-st-ted
PaddleSpeech 的 **语音合成** 主要包含三个模块:文本前端、声学模型和声码器。声学模型和声码器模型如下:
语音合成模块类型 模型类型 数据集 脚本
文本前端 tn / g2p
声学模型 Tacotron2 LJSpeech / CSMSC tacotron2-ljspeech / tacotron2-csmsc
Transformer TTS LJSpeech transformer-ljspeech
SpeedySpeech CSMSC speedyspeech-csmsc
FastSpeech2 LJSpeech / VCTK / CSMSC / AISHELL-3 / ZH_EN / finetune fastspeech2-ljspeech / fastspeech2-vctk / fastspeech2-csmsc / fastspeech2-aishell3 / fastspeech2-zh_en / fastspeech2-finetune
ERNIE-SAT VCTK / AISHELL-3 / ZH_EN ERNIE-SAT-vctk / ERNIE-SAT-aishell3 / ERNIE-SAT-zh_en
DiffSinger Opencpop DiffSinger-opencpop
声码器 WaveFlow LJSpeech waveflow-ljspeech
Parallel WaveGAN LJSpeech / VCTK / CSMSC / AISHELL-3 / Opencpop PWGAN-ljspeech / PWGAN-vctk / PWGAN-csmsc / PWGAN-aishell3 / PWGAN-opencpop
Multi Band MelGAN CSMSC Multi Band MelGAN-csmsc
Style MelGAN CSMSC Style MelGAN-csmsc
HiFiGAN LJSpeech / VCTK / CSMSC / AISHELL-3 / Opencpop HiFiGAN-ljspeech / HiFiGAN-vctk / HiFiGAN-csmsc / HiFiGAN-aishell3 / HiFiGAN-opencpop
WaveRNN CSMSC WaveRNN-csmsc
声音克隆 GE2E Librispeech, etc. GE2E
SV2TTS (GE2E + Tacotron2) AISHELL-3 VC0
SV2TTS (GE2E + FastSpeech2) AISHELL-3 VC1
SV2TTS (ECAPA-TDNN + FastSpeech2) AISHELL-3 VC2
GE2E + VITS AISHELL-3 VITS-VC
端到端 VITS CSMSC / AISHELL-3 VITS-csmsc / VITS-aishell3
**声音分类**
任务 数据集 模型类型 脚本
声音分类 ESC-50 PANN pann-esc50
**语音唤醒**
任务 数据集 模型类型 脚本
语音唤醒 hey-snips MDTC mdtc-hey-snips
**声纹识别**
任务 数据集 模型类型 脚本
声纹识别 VoxCeleb1/2 ECAPA-TDNN ecapa-tdnn-voxceleb12
**说话人日志**
任务 数据集 模型类型 脚本
说话人日志 AMI ECAPA-TDNN + AHC / SC ecapa-tdnn-ami
**标点恢复**
任务 数据集 模型类型 脚本
标点恢复 IWLST2012_zh Ernie Linear iwslt2012-punc0
## 教程文档 对于 PaddleSpeech 的所关注的任务,以下指南有助于帮助开发者快速入门,了解语音相关核心思想。 - [下载安装](./docs/source/install_cn.md) - [快速开始](#快速开始) - Notebook基础教程 - [声音分类](./docs/tutorial/cls/cls_tutorial.ipynb) - [语音识别](./docs/tutorial/asr/tutorial_transformer.ipynb) - [语音翻译](./docs/tutorial/st/st_tutorial.ipynb) - [声音合成](./docs/tutorial/tts/tts_tutorial.ipynb) - [示例Demo](./demos/README.md) - 进阶文档 - [语音识别自定义训练](./docs/source/asr/quick_start.md) - [简介](./docs/source/asr/models_introduction.md) - [数据准备](./docs/source/asr/data_preparation.md) - [Ngram 语言模型](./docs/source/asr/ngram_lm.md) - [语音合成自定义训练](./docs/source/tts/quick_start.md) - [简介](./docs/source/tts/models_introduction.md) - [进阶用法](./docs/source/tts/advanced_usage.md) - [中文文本前端](./docs/source/tts/zh_text_frontend.md) - [测试语音样本](https://paddlespeech.readthedocs.io/en/latest/tts/demo.html) - 声纹识别 - [声纹识别](./demos/speaker_verification/README_cn.md) - [音频检索](./demos/audio_searching/README_cn.md) - [声音分类](./demos/audio_tagging/README_cn.md) - [语音翻译](./demos/speech_translation/README_cn.md) - [服务化部署](./demos/speech_server/README_cn.md) - [模型列表](#模型列表) - [语音识别](#语音识别模型) - [语音合成](#语音合成模型) - [声音分类](#声音分类模型) - [声纹识别](#声纹识别模型) - [说话人日志](#说话人日志模型) - [标点恢复](#标点恢复模型) - [技术交流群](#技术交流群) - [欢迎贡献](#欢迎贡献) - [License](#License) 语音合成模块最初被称为 [Parakeet](https://github.com/PaddlePaddle/Parakeet),现在与此仓库合并。如果您对该任务的学术研究感兴趣,请参阅 [TTS 研究概述](https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/docs/source/tts#overview)。此外,[模型介绍](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/docs/source/tts/models_introduction.md) 是了解语音合成流程的一个很好的指南。 ## ⭐ 应用案例 - **[PaddleBoBo](https://github.com/JiehangXie/PaddleBoBo): 使用 PaddleSpeech 的语音合成模块生成虚拟人的声音。**
- [PaddleSpeech 示例视频](https://paddlespeech.readthedocs.io/en/latest/demo_video.html) - **[VTuberTalk](https://github.com/jerryuhoo/VTuberTalk): 使用 PaddleSpeech 的语音合成和语音识别从视频中克隆人声。**
## 引用 要引用 PaddleSpeech 进行研究,请使用以下格式进行引用。 ```text @InProceedings{pmlr-v162-bai22d, title = {{A}$^3${T}: Alignment-Aware Acoustic and Text Pretraining for Speech Synthesis and Editing}, author = {Bai, He and Zheng, Renjie and Chen, Junkun and Ma, Mingbo and Li, Xintong and Huang, Liang}, booktitle = {Proceedings of the 39th International Conference on Machine Learning}, pages = {1399--1411}, year = {2022}, volume = {162}, series = {Proceedings of Machine Learning Research}, month = {17--23 Jul}, publisher = {PMLR}, pdf = {https://proceedings.mlr.press/v162/bai22d/bai22d.pdf}, url = {https://proceedings.mlr.press/v162/bai22d.html}, } @inproceedings{zhang2022paddlespeech, title = {PaddleSpeech: An Easy-to-Use All-in-One Speech Toolkit}, author = {Hui Zhang, Tian Yuan, Junkun Chen, Xintong Li, Renjie Zheng, Yuxin Huang, Xiaojie Chen, Enlei Gong, Zeyu Chen, Xiaoguang Hu, dianhai yu, Yanjun Ma, Liang Huang}, booktitle = {Proceedings of the 2022 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies: Demonstrations}, year = {2022}, publisher = {Association for Computational Linguistics}, } @inproceedings{zheng2021fused, title={Fused acoustic and text encoding for multimodal bilingual pretraining and speech translation}, author={Zheng, Renjie and Chen, Junkun and Ma, Mingbo and Huang, Liang}, booktitle={International Conference on Machine Learning}, pages={12736--12746}, year={2021}, organization={PMLR} } ``` ## 参与 PaddleSpeech 的开发 热烈欢迎您在 [Discussions](https://github.com/PaddlePaddle/PaddleSpeech/discussions) 中提交问题,并在 [Issues](https://github.com/PaddlePaddle/PaddleSpeech/issues) 中指出发现的 bug。此外,我们非常希望您参与到 PaddleSpeech 的开发中! ### 贡献者

## 致谢 - 非常感谢 [HighCWu](https://github.com/HighCWu) 新增 [VITS-aishell3](./examples/aishell3/vits) 和 [VITS-VC](./examples/aishell3/vits-vc) 代码示例。 - 非常感谢 [david-95](https://github.com/david-95) 修复 TTS 句尾多标点符号出错的问题,贡献补充多条程序和数据。为 TTS 中文文本前端新增 [SSML](https://github.com/PaddlePaddle/PaddleSpeech/discussions/2538) 功能。 - 非常感谢 [BarryKCL](https://github.com/BarryKCL) 基于 [G2PW](https://github.com/GitYCC/g2pW) 对 TTS 中文文本前端的优化。 - 非常感谢 [yeyupiaoling](https://github.com/yeyupiaoling)/[PPASR](https://github.com/yeyupiaoling/PPASR)/[PaddlePaddle-DeepSpeech](https://github.com/yeyupiaoling/PaddlePaddle-DeepSpeech)/[VoiceprintRecognition-PaddlePaddle](https://github.com/yeyupiaoling/VoiceprintRecognition-PaddlePaddle)/[AudioClassification-PaddlePaddle](https://github.com/yeyupiaoling/AudioClassification-PaddlePaddle) 多年来的关注和建议,以及在诸多问题上的帮助。 - 非常感谢 [mymagicpower](https://github.com/mymagicpower) 采用PaddleSpeech 对 ASR 的[短语音](https://github.com/mymagicpower/AIAS/tree/main/3_audio_sdks/asr_sdk)及[长语音](https://github.com/mymagicpower/AIAS/tree/main/3_audio_sdks/asr_long_audio_sdk)进行 Java 实现。 - 非常感谢 [JiehangXie](https://github.com/JiehangXie)/[PaddleBoBo](https://github.com/JiehangXie/PaddleBoBo) 采用 PaddleSpeech 语音合成功能实现 Virtual Uploader(VUP)/Virtual YouTuber(VTuber) 虚拟主播。 - 非常感谢 [745165806](https://github.com/745165806)/[PaddleSpeechTask](https://github.com/745165806/PaddleSpeechTask) 贡献标点重建相关模型。 - 非常感谢 [kslz](https://github.com/kslz) 补充中文文档。 - 非常感谢 [awmmmm](https://github.com/awmmmm) 提供 fastspeech2 aishell3 conformer 预训练模型。 - 非常感谢 [phecda-xu](https://github.com/phecda-xu)/[PaddleDubbing](https://github.com/phecda-xu/PaddleDubbing) 基于 PaddleSpeech 的 TTS 模型搭建带 GUI 操作界面的配音工具。 - 非常感谢 [jerryuhoo](https://github.com/jerryuhoo)/[VTuberTalk](https://github.com/jerryuhoo/VTuberTalk) 基于 PaddleSpeech 的 TTS GUI 界面和基于 ASR 制作数据集的相关代码。 - 非常感谢 [vpegasus](https://github.com/vpegasus)/[xuesebot](https://github.com/vpegasus/xuesebot) 基于 PaddleSpeech 的 ASR 与 TTS 设计的可听、说对话机器人。 - 非常感谢 [chenkui164](https://github.com/chenkui164)/[FastASR](https://github.com/chenkui164/FastASR) 对 PaddleSpeech 的 ASR 进行 C++ 推理实现。 - 非常感谢 [heyudage](https://github.com/heyudage)/[VoiceTyping](https://github.com/heyudage/VoiceTyping) 基于 PaddleSpeech 的 ASR 流式服务实现的实时语音输入法工具。 - 非常感谢 [EscaticZheng](https://github.com/EscaticZheng)/[ps3.9wheel-install](https://github.com/EscaticZheng/ps3.9wheel-install) 对PaddleSpeech在Windows下的安装提供了无需Visua Studio,基于python3.9的预编译依赖安装包。 - 非常感谢 [chinobing](https://github.com/chinobing)/[FastAPI-PaddleSpeech-Audio-To-Text](https://github.com/chinobing/FastAPI-PaddleSpeech-Audio-To-Text) 利用 FastAPI 实现 PaddleSpeech 语音转文字,文件上传、分割、转换进度显示、后台更新任务并以 csv 格式输出。 - 非常感谢 [MistEO](https://github.com/MistEO)/[Pallas-Bot](https://github.com/MistEO/Pallas-Bot) 基于 PaddleSpeech TTS 的 QQ Bot 项目。 此外,PaddleSpeech 依赖于许多开源存储库。有关更多信息,请参阅 [references](./docs/source/reference.md)。 ## License PaddleSpeech 在 [Apache-2.0 许可](./LICENSE) 下提供。 ## Stargazers over time [![Stargazers over time](https://starchart.cc/PaddlePaddle/PaddleSpeech.svg)](https://starchart.cc/PaddlePaddle/PaddleSpeech) ================================================ FILE: audio/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) # Use compiler ID "AppleClang" instead of "Clang" for XCode. # Not setting this sometimes makes XCode C compiler gets detected as "Clang", # even when the C++ one is detected as "AppleClang". cmake_policy(SET CMP0010 NEW) cmake_policy(SET CMP0025 NEW) # Suppress warning flags in default MSVC configuration. It's not # mandatory that we do this (and we don't if cmake is old), but it's # nice when it's possible, and it's possible on our Windows configs. if(NOT CMAKE_VERSION VERSION_LESS 3.15.0) cmake_policy(SET CMP0092 NEW) endif() project(paddleaudio) # check and set CMAKE_CXX_STANDARD string(FIND "${CMAKE_CXX_FLAGS}" "-std=c++" env_cxx_standard) if(env_cxx_standard GREATER -1) message( WARNING "C++ standard version definition detected in environment variable." "paddleaudio requires -std=c++14. Please remove -std=c++ settings in your environment.") endif() set(CMAKE_CXX_STANDARD 14) set(CMAKE_C_STANDARD 11) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_VERBOSE_MAKEFILE ON) # Options option(BUILD_SOX "Build libsox statically" ON) option(BUILD_MAD "Enable libmad" ON) option(BUILD_KALDI "Build kaldi statically" ON) option(BUILD_PADDLEAUDIO_PYTHON_EXTENSION "Build Python extension" ON) # cmake set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}/cmake;${PROJECT_SOURCE_DIR}/cmake/external") # fc_patch dir set(FETCHCONTENT_QUIET off) get_filename_component(fc_patch "fc_patch" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") set(FETCHCONTENT_BASE_DIR ${fc_patch}) set(THIRD_PARTY_PATH ${fc_patch}) set(PYBIND11_PYTHON_VERSION ${PY_VERSION}) include(cmake/pybind.cmake) include_directories(${PYTHON_INCLUDE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/paddleaudio/third_party/) # packages find_package(Python3 COMPONENTS Interpreter Development) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -O0 -Wall -g") add_subdirectory(paddleaudio) # Summary include(cmake/summary.cmake) onnx_print_configuration_summary() ================================================ FILE: audio/README.md ================================================ # PaddleAudio 安装方式: pip install paddleaudio 目前支持的平台:Linux, Mac, Windows ## Environment ## Build wheel cmd: python setup.py bdist_wheel Linux test build whl environment: * os - Ubuntu 16.04.7 LTS * gcc/g++ - 8.2.0 * cmake - 3.18.0 (need install) MAC:test build whl environment: * os * gcc/g++ 12.2.0 * cpu Intel Xeon E5 x86_64 Windows: not support paddleaudio C++ extension lib (sox io, kaldi native fbank) ================================================ FILE: audio/cmake/FindGFortranLibs.cmake ================================================ #.rst: # FindGFortranLibs # -------- # https://github.com/Argonne-National-Laboratory/PIPS/blob/master/cmake/Modules/FindGFortranLibs.cmake # https://enccs.github.io/cmake-workshop/cxx-fortran/ # # Find gcc Fortran compiler & library paths # # The module defines the following variables: # # :: # # # GFORTRANLIBS_FOUND - true if system has gfortran # LIBGFORTRAN_LIBRARIES - path to libgfortran # LIBQUADMATH_LIBRARIES - path to libquadmath # GFORTRAN_LIBARIES_DIR - directory containing libgfortran, libquadmath # GFORTRAN_INCLUDE_DIR - directory containing gfortran/gcc headers # LIBGOMP_LIBRARIES - path to libgomp # LIBGOMP_INCLUDE_DIR - directory containing omp.h header # GFORTRAN_VERSION_STRING - version of gfortran found # set(CMAKE_REQUIRED_QUIET ${LIBIOMP_FIND_QUIETLY}) if(NOT CMAKE_REQUIRED_QUIET) message(STATUS "Looking for gfortran related libraries...") endif() enable_language(Fortran) if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") # Basically, call "gfortran -v" to dump compiler info to the string # GFORTRAN_VERBOSE_STR, which will be used to get necessary paths message(STATUS "Extracting library and header information by calling 'gfortran -v'...") execute_process(COMMAND "${CMAKE_Fortran_COMPILER}" "-v" ERROR_VARIABLE GFORTRAN_VERBOSE_STR RESULT_VARIABLE FLAG) # For debugging message(STATUS "'gfortran -v' returned:") message(STATUS "${GFORTRAN_VERBOSE_STR}") # Detect gfortran version string(REGEX MATCH "gcc version [^\t\n ]+" GFORTRAN_VER_STR "${GFORTRAN_VERBOSE_STR}") string(REGEX REPLACE "gcc version ([^\t\n ]+)" "\\1" GFORTRAN_VERSION_STRING "${GFORTRAN_VER_STR}") message(STATUS "Detected gfortran version ${GFORTRAN_VERSION_STRING}") unset(GFORTRAN_VER_STR) set(MATCH_REGEX "[^\t\n ]+[\t\n ]+") set(REPLACE_REGEX "([^\t\n ]+)") # Find architecture for compiler string(REGEX MATCH "Target: [^\t\n ]+" GFORTRAN_ARCH_STR "${GFORTRAN_VERBOSE_STR}") message(STATUS "Architecture string: ${GFORTRAN_ARCH_STR}") string(REGEX REPLACE "Target: ([^\t\n ]+)" "\\1" GFORTRAN_ARCH "${GFORTRAN_ARCH_STR}") message(STATUS "Detected gfortran architecture: ${GFORTRAN_ARCH}") unset(GFORTRAN_ARCH_STR) # Find install prefix, if it exists; if not, use default string(REGEX MATCH "--prefix=[^\t\n ]+[\t\n ]+" GFORTRAN_PREFIX_STR "${GFORTRAN_VERBOSE_STR}") if(NOT GFORTRAN_PREFIX_STR) message(STATUS "Detected default gfortran prefix") set(GFORTRAN_PREFIX_DIR "/usr/local") # default prefix for gcc install else() string(REGEX REPLACE "--prefix=([^\t\n ]+)" "\\1" GFORTRAN_PREFIX_DIR "${GFORTRAN_PREFIX_STR}") endif() message(STATUS "Detected gfortran prefix: ${GFORTRAN_PREFIX_DIR}") unset(GFORTRAN_PREFIX_STR) # Find install exec-prefix, if it exists; if not, use default string(REGEX MATCH "--exec-prefix=[^\t\n ]+[\t\n ]+" "\\1" GFORTRAN_EXEC_PREFIX_STR "${GFORTRAN_VERBOSE_STR}") if(NOT GFORTRAN_EXEC_PREFIX_STR) message(STATUS "Detected default gfortran exec-prefix") set(GFORTRAN_EXEC_PREFIX_DIR "${GFORTRAN_PREFIX_DIR}") else() string(REGEX REPLACE "--exec-prefix=([^\t\n ]+)" "\\1" GFORTRAN_EXEC_PREFIX_DIR "${GFORTRAN_EXEC_PREFIX_STR}") endif() message(STATUS "Detected gfortran exec-prefix: ${GFORTRAN_EXEC_PREFIX_DIR}") UNSET(GFORTRAN_EXEC_PREFIX_STR) # Find library directory and include directory, if library directory specified string(REGEX MATCH "--libdir=[^\t\n ]+" GFORTRAN_LIB_DIR_STR "${GFORTRAN_VERBOSE_STR}") if(NOT GFORTRAN_LIB_DIR_STR) message(STATUS "Found --libdir flag -- not found") message(STATUS "Using default gfortran library & include directory paths") string(STRIP ${GFORTRAN_PREFIX_DIR} TMPLIBDIR) set(GFORTRAN_LIBRARIES_DIR "${TMPLIBDIR}/lib64") set(GFORTRAN_INCLUDE_DIR "${TMPLIBDIR}/include") else() message(STATUS "Found --libdir flag -- yes") string(REGEX REPLACE "--libdir=([^\t\n ]+)" "\\1" GFORTRAN_LIBRARIES_DIR "${GFORTRAN_LIB_DIR_STR}") string(CONCAT GFORTRAN_INCLUDE_DIR "${GFORTRAN_LIBRARIES_DIR}" "/gcc/" "${GFORTRAN_ARCH}" "/" "${GFORTRAN_VERSION_STRING}" "/include") endif() message(STATUS "gfortran libraries path: ${GFORTRAN_LIBRARIES_DIR}") message(STATUS "gfortran include path dir: ${GFORTRAN_INCLUDE_DIR}") unset(GFORTRAN_LIB_DIR_STR) # There are lots of other build options for gcc & gfortran. For now, the # options implemented above should cover a lot of common use cases. # Clean up be deleting the output string from "gfortran -v" unset(GFORTRAN_VERBOSE_STR) # Find paths for libgfortran, libquadmath, libgomp # libgomp needed for OpenMP support without Clang find_library(LIBGFORTRAN_LIBRARIES NAMES gfortran libgfortran HINTS ${GFORTRAN_LIBRARIES_DIR}) find_library(LIBQUADMATH_LIBRARIES NAMES quadmath libquadmath HINTS ${GFORTRAN_LIBRARIES_DIR}) find_library(LIBGOMP_LIBRARIES NAMES gomp libgomp HINTS ${GFORTRAN_LIBRARIES_DIR}) # Find OpenMP headers find_path(LIBGOMP_INCLUDE_DIR NAMES omp.h HINTS ${GFORTRAN_INCLUDE_DIR}) else() message(STATUS "CMAKE_Fortran_COMPILER_ID does not match 'GNU'!") endif() include(FindPackageHandleStandardArgs) # Required: libgfortran, libquadmath, path for gfortran libraries # Optional: libgomp, path for OpenMP headers, path for gcc/gfortran headers find_package_handle_standard_args(GFortranLibs REQUIRED_VARS LIBGFORTRAN_LIBRARIES LIBQUADMATH_LIBRARIES GFORTRAN_LIBRARIES_DIR VERSION_VAR GFORTRAN_VERSION_STRING) if(GFORTRANLIBS_FOUND) message(STATUS "Looking for gfortran libraries -- found") message(STATUS "gfortran version: ${GFORTRAN_VERSION_STRING}") else() message(STATUS "Looking for gfortran libraries -- not found") endif() mark_as_advanced(LIBGFORTRAN_LIBRARIES LIBQUADMATH_LIBRARIES LIBGOMP_LIBRARIES LIBGOMP_INCLUDE_DIR GFORTRAN_LIBRARIES_DIR GFORTRAN_INCLUDE_DIR) # FindGFortranLIBS.cmake ends here message(STATUS LIBGFORTRAN_LIBRARIES= ${LIBGFORTRAN_LIBRARIES}) message(STATUS LIBQUADMATH_LIBRARIES= ${LIBQUADMATH_LIBRARIES}) message(STATUS LIBGOMP_LIBRARIES= ${LIBGOMP_LIBRARIES}) message(STATUS LIBGOMP_INCLUDE_DIR= ${LIBGOMP_INCLUDE_DIR}) message(STATUS GFORTRAN_LIBRARIES_DIR= ${GFORTRAN_LIBRARIES_DIR}) message(STATUS GFORTRAN_INCLUDE_DIR= ${GFORTRAN_INCLUDE_DIR}) ================================================ FILE: audio/cmake/external/openblas.cmake ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. include(ExternalProject) set(CBLAS_PREFIX_DIR ${THIRD_PARTY_PATH}/openblas) set(CBLAS_INSTALL_DIR ${THIRD_PARTY_PATH}/install/openblas) set(CBLAS_REPOSITORY https://github.com/xianyi/OpenBLAS.git) set(CBLAS_TAG v0.3.10) if(NOT WIN32) set(CBLAS_LIBRARIES "${CBLAS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}openblas${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE FILEPATH "openblas library." FORCE) set(CBLAS_INC_DIR "${CBLAS_INSTALL_DIR}/include" CACHE PATH "openblas include directory." FORCE) set(OPENBLAS_CC "${CMAKE_C_COMPILER} -Wno-unused-but-set-variable -Wno-unused-variable") if(APPLE) set(OPENBLAS_CC "${CMAKE_C_COMPILER} -isysroot ${CMAKE_OSX_SYSROOT}") endif() set(OPTIONAL_ARGS "") set(COMMON_ARGS "") if(APPLE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^x86(_64)?$") set(OPTIONAL_ARGS DYNAMIC_ARCH=1 NUM_THREADS=64) endif() set(COMMON_ARGS CC=${OPENBLAS_CC} NO_SHARED=1) endif() ExternalProject_Add( OPENBLAS URL "https://paddleaudio.bj.bcebos.com/build/OpenBLAS-0.3.10.zip" GIT_SHALLOW YES DOWNLOAD_DIR ${CBLAS_PREFIX_DIR} SOURCE_DIR ${CBLAS_PREFIX_DIR} INSTALL_DIR ${CBLAS_INSTALL_DIR} BUILD_IN_SOURCE 1 BUILD_COMMAND make -j${NPROC} ${COMMON_ARGS} ${OPTIONAL_ARGS} INSTALL_COMMAND make install PREFIX= UPDATE_COMMAND "" CONFIGURE_COMMAND "" BUILD_BYPRODUCTS ${CBLAS_LIBRARIES}) ExternalProject_Get_Property(OPENBLAS INSTALL_DIR) set(OpenBLAS_INSTALL_PREFIX ${INSTALL_DIR}) add_library(openblas STATIC IMPORTED) add_dependencies(openblas OPENBLAS) set_target_properties(openblas PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES Fortran) set_target_properties(openblas PROPERTIES IMPORTED_LOCATION ${OpenBLAS_INSTALL_PREFIX}/lib/libopenblas.a) link_directories(${OpenBLAS_INSTALL_PREFIX}/lib) include_directories(${OpenBLAS_INSTALL_PREFIX}/include) set(OPENBLAS_LIBRARIES ${OpenBLAS_INSTALL_PREFIX}/lib/libopenblas.a ) add_library(libopenblas INTERFACE) add_dependencies(libopenblas openblas) target_include_directories(libopenblas INTERFACE ${OpenBLAS_INSTALL_PREFIX}/include/openblas) target_link_libraries(libopenblas INTERFACE ${OPENBLAS_LIBRARIES}) else() set(CBLAS_LIBRARIES "${CBLAS_INSTALL_DIR}/lib/openblas${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE FILEPATH "openblas library." FORCE) set(CBLAS_INC_DIR "${CBLAS_INSTALL_DIR}/include/openblas" CACHE PATH "openblas include directory." FORCE) ExternalProject_Add( extern_openblas ${EXTERNAL_PROJECT_LOG_ARGS} GIT_REPOSITORY ${CBLAS_REPOSITORY} GIT_TAG ${CBLAS_TAG} PREFIX ${CBLAS_PREFIX_DIR} INSTALL_DIR ${CBLAS_INSTALL_DIR} BUILD_IN_SOURCE 0 UPDATE_COMMAND "" CMAKE_ARGS -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_INSTALL_PREFIX=${CBLAS_INSTALL_DIR} -DCMAKE_BUILD_TYPE=Release #${THIRD_PARTY_BUILD_TYPE} -DCMAKE_MT=mt -DUSE_THREAD=OFF -DBUILD_WITHOUT_LAPACK=NO -DCMAKE_Fortran_COMPILER=flang -DNOFORTRAN=0 -DDYNAMIC_ARCH=ON #${EXTERNAL_OPTIONAL_ARGS} CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${CBLAS_INSTALL_DIR} -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=Release #${THIRD_PARTY_BUILD_TYPE} # ninja need to know where openblas.lib comes from BUILD_BYPRODUCTS ${CBLAS_LIBRARIES}) set(OPENBLAS_SHARED_LIB ${CBLAS_INSTALL_DIR}/bin/openblas${CMAKE_SHARED_LIBRARY_SUFFIX}) add_library(openblas INTERFACE) add_dependencies(openblas extern_openblas) include_directories(${CBLAS_INC_DIR}) link_libraries(${CBLAS_LIBRARIES}) endif() ================================================ FILE: audio/cmake/pybind.cmake ================================================ #the pybind11 is from:https://github.com/pybind/pybind11 # Copyright (c) 2016 Wenzel Jakob , All rights reserved. SET(PYBIND_ZIP "v2.10.0.zip") SET(LOCAL_PYBIND_ZIP ${FETCHCONTENT_BASE_DIR}/${PYBIND_ZIP}) SET(PYBIND_SRC ${FETCHCONTENT_BASE_DIR}/pybind11) SET(DOWNLOAD_URL "https://paddleaudio.bj.bcebos.com/build/v2.10.0.zip") SET(PYBIND_TIMEOUT 600 CACHE STRING "Timeout in seconds when downloading pybind.") IF(NOT EXISTS ${LOCAL_PYBIND_ZIP}) FILE(DOWNLOAD ${DOWNLOAD_URL} ${LOCAL_PYBIND_ZIP} TIMEOUT ${PYBIND_TIMEOUT} STATUS ERR SHOW_PROGRESS ) IF(ERR EQUAL 0) MESSAGE(STATUS "download pybind success") ELSE() MESSAGE(FATAL_ERROR "download pybind fail") ENDIF() ENDIF() IF(NOT EXISTS ${PYBIND_SRC}) EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E tar xfz ${LOCAL_PYBIND_ZIP} WORKING_DIRECTORY ${FETCHCONTENT_BASE_DIR} RESULT_VARIABLE tar_result ) file(RENAME ${FETCHCONTENT_BASE_DIR}/pybind11-2.10.0 ${PYBIND_SRC}) IF (tar_result MATCHES 0) MESSAGE(STATUS "unzip pybind success") ELSE() MESSAGE(FATAL_ERROR "unzip pybind fail") ENDIF() ENDIF() include_directories(${PYBIND_SRC}/include) ================================================ FILE: audio/cmake/summary.cmake ================================================ # SPDX-License-Identifier: Apache-2.0 # Prints accumulated ONNX configuration summary function (onnx_print_configuration_summary) message(STATUS "") message(STATUS "******** Summary ********") message(STATUS " CMake version : ${CMAKE_VERSION}") message(STATUS " CMake command : ${CMAKE_COMMAND}") message(STATUS " System : ${CMAKE_SYSTEM_NAME}") message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}") message(STATUS " C++ compiler version : ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS " CXX flags : ${CMAKE_CXX_FLAGS}") message(STATUS " Build type : ${CMAKE_BUILD_TYPE}") get_directory_property(tmp DIRECTORY ${PROJECT_SOURCE_DIR} COMPILE_DEFINITIONS) message(STATUS " Compile definitions : ${tmp}") message(STATUS " CMAKE_PREFIX_PATH : ${CMAKE_PREFIX_PATH}") message(STATUS " CMAKE_INSTALL_PREFIX : ${CMAKE_INSTALL_PREFIX}") message(STATUS " CMAKE_MODULE_PATH : ${CMAKE_MODULE_PATH}") message(STATUS "") message(STATUS " ONNX version : ${ONNX_VERSION}") message(STATUS " ONNX NAMESPACE : ${ONNX_NAMESPACE}") message(STATUS " ONNX_USE_LITE_PROTO : ${ONNX_USE_LITE_PROTO}") message(STATUS " USE_PROTOBUF_SHARED_LIBS : ${ONNX_USE_PROTOBUF_SHARED_LIBS}") message(STATUS " Protobuf_USE_STATIC_LIBS : ${Protobuf_USE_STATIC_LIBS}") message(STATUS " ONNX_DISABLE_EXCEPTIONS : ${ONNX_DISABLE_EXCEPTIONS}") message(STATUS " ONNX_WERROR : ${ONNX_WERROR}") message(STATUS " ONNX_BUILD_TESTS : ${ONNX_BUILD_TESTS}") message(STATUS " ONNX_BUILD_BENCHMARKS : ${ONNX_BUILD_BENCHMARKS}") message(STATUS " ONNXIFI_DUMMY_BACKEND : ${ONNXIFI_DUMMY_BACKEND}") message(STATUS " ONNXIFI_ENABLE_EXT : ${ONNXIFI_ENABLE_EXT}") message(STATUS "") message(STATUS " Protobuf compiler : ${PROTOBUF_PROTOC_EXECUTABLE}") message(STATUS " Protobuf includes : ${PROTOBUF_INCLUDE_DIRS}") message(STATUS " Protobuf libraries : ${PROTOBUF_LIBRARIES}") message(STATUS " BUILD_ONNX_PYTHON : ${BUILD_ONNX_PYTHON}") message(STATUS " Python version : ${Python_VERSION}") message(STATUS " Python executable : ${Python_EXECUTABLE}") message(STATUS " Python includes : ${Python_INCLUDE_DIR}") message(STATUS " Python libraries : ${Python_LIBRARY}") message(STATUS " PYBIND11 : ${pybind11_FOUND}") message(STATUS " Pybind11 version : ${pybind11_VERSION}") message(STATUS " Pybind11 include : ${pybind11_INCLUDE_DIR}") message(STATUS " Pybind11 includes : ${pybind11_INCLUDE_DIRS}") message(STATUS " Pybind11 libraries : ${pybind11_LIBRARIES}") endfunction() ================================================ FILE: audio/paddleaudio/CMakeLists.txt ================================================ add_subdirectory(third_party) add_subdirectory(src) ================================================ FILE: audio/paddleaudio/__init__.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from . import _extension from . import backends from . import compliance from . import datasets from . import features from . import functional from . import metric from . import sox_effects from . import utils ================================================ FILE: audio/paddleaudio/_extension.py ================================================ import contextlib import ctypes import os import sys import types import warnings from pathlib import Path from ._internal import module_utils as _mod_utils # noqa: F401 # Query `hasattr` only once. _SET_GLOBAL_FLAGS = hasattr(sys, 'getdlopenflags') and hasattr(sys, 'setdlopenflags') @contextlib.contextmanager def dl_open_guard(): """ # https://manpages.debian.org/bullseye/manpages-dev/dlopen.3.en.html Context manager to set the RTLD_GLOBAL dynamic linker flag while we open a shared library to load custom operators. """ if _SET_GLOBAL_FLAGS: old_flags = sys.getdlopenflags() sys.setdlopenflags(old_flags | ctypes.RTLD_GLOBAL) yield if _SET_GLOBAL_FLAGS: sys.setdlopenflags(old_flags) def resolve_library_path(path: str) -> str: return os.path.realpath(path) class _Ops(types.ModuleType): #__file__ = '_ops.py' def __init__(self): super(_Ops, self).__init__('paddleaudio.ops') self.loaded_libraries = set() def load_library(self, path): """ Loads a shared library from the given path into the current process. This allows dynamically loading custom operators. For this, you should compile your operator and the static registration code into a shared library object, and then call ``paddleaudio.ops.load_library('path/to/libcustom.so')`` to load the shared object. After the library is loaded, it is added to the ``paddleaudio.ops.loaded_libraries`` attribute, a set that may be inspected for the paths of all libraries loaded using this function. Args: path (str): A path to a shared library to load. """ path = resolve_library_path(path) with dl_open_guard(): # https://docs.python.org/3/library/ctypes.html?highlight=ctypes#loading-shared-libraries # Import the shared library into the process, thus running its # static (global) initialization code in order to register custom # operators with the JIT. ctypes.CDLL(path) self.loaded_libraries.add(path) _LIB_DIR = Path(__file__).parent / "lib" def _get_lib_path(lib: str): suffix = "pyd" if os.name == "nt" else "so" path = _LIB_DIR / f"{lib}.{suffix}" return path def _load_lib(lib: str) -> bool: """Load extension module Note: In case `paddleaudio` is deployed with `pex` format, the library file is not in a standard location. In this case, we expect that `libpaddlleaudio` is available somewhere in the search path of dynamic loading mechanism, so that importing `_paddlleaudio` will have library loader find and load `libpaddlleaudio`. This is the reason why the function should not raising an error when the library file is not found. Returns: bool: True if the library file is found AND the library loaded without failure. False if the library file is not found (like in the case where paddlleaudio is deployed with pex format, thus the shared library file is in a non-standard location.). If the library file is found but there is an issue loading the library, (such as missing dependency) then this function raises the exception as-is. Raises: Exception: If the library file is found, but there is an issue loading the library file, (when underlying `ctype.DLL` throws an exception), this function will pass the exception as-is, instead of catching it and returning bool. The expected case is `OSError` thrown by `ctype.DLL` when a dynamic dependency is not found. This behavior was chosen because the expected failure case is not recoverable. If a dependency is missing, then users have to install it. """ path = _get_lib_path(lib) if not path.exists(): warnings.warn("lib path is not exists:" + str(path)) return False ops.load_library(path) return True _FFMPEG_INITIALIZED = False def _init_ffmpeg(): global _FFMPEG_INITIALIZED if _FFMPEG_INITIALIZED: return if not paddleaudio._paddlleaudio.is_ffmpeg_available(): raise RuntimeError( "paddlleaudio is not compiled with FFmpeg integration. Please set USE_FFMPEG=1 when compiling paddlleaudio." ) try: _load_lib("libpaddlleaudio_ffmpeg") except OSError as err: raise ImportError( "FFmpeg libraries are not found. Please install FFmpeg.") from err import paddllespeech.audio._paddlleaudio_ffmpeg # noqa paddleaudio._paddlleaudio.ffmpeg_init() if paddleaudio._paddlleaudio.ffmpeg_get_log_level() > 8: paddleaudio._paddlleaudio.ffmpeg_set_log_level(8) _FFMPEG_INITIALIZED = True def _init_extension(): if not _mod_utils.is_module_available("paddleaudio._paddleaudio"): warnings.warn( "paddleaudio C++ extension is not available. sox_io, sox_effect, kaldi raw feature is not supported!!!") return _load_lib("libpaddleaudio") # This import is for initializing the methods registered via PyBind11 # This has to happen after the base library is loaded try: from paddleaudio import _paddleaudio # noqa except Exception: warnings.warn( "paddleaudio C++ extension is not available. sox_io, sox_effect, kaldi raw feature is not supported!!!") return # Because this part is executed as part of `import torchaudio`, we ignore the # initialization failure. # If the FFmpeg integration is not properly initialized, then detailed error # will be raised when client code attempts to import the dedicated feature. try: _init_ffmpeg() except Exception: pass ops = _Ops() _init_extension() ================================================ FILE: audio/paddleaudio/_internal/__init__.py ================================================ ================================================ FILE: audio/paddleaudio/_internal/module_utils.py ================================================ import importlib.util import platform import warnings from functools import wraps from typing import Optional #code is from https://github.com/pytorch/audio/blob/main/torchaudio/_internal/module_utils.py with modification. def is_module_available(*modules: str) -> bool: r"""Returns if a top-level module with :attr:`name` exists *without** importing it. This is generally safer than try-catch block around a `import X`. It avoids third party libraries breaking assumptions of some of our tests, e.g., setting multiprocessing start method when imported (see librosa/#747, torchvision/#544). """ return all(importlib.util.find_spec(m) is not None for m in modules) def requires_module(*modules: str): """Decorate function to give error message if invoked without required optional modules. This decorator is to give better error message to users rather than raising ``NameError: name 'module' is not defined`` at random places. """ missing = [m for m in modules if not is_module_available(m)] if not missing: # fall through. If all the modules are available, no need to decorate def decorator(func): return func else: req = f"module: {missing[0]}" if len( missing) == 1 else f"modules: {missing}" def decorator(func): @wraps(func) def wrapped(*args, **kwargs): raise RuntimeError( f"{func.__module__}.{func.__name__} requires {req}") return wrapped return decorator def deprecated(direction: str, version: Optional[str]=None): """Decorator to add deprecation message Args: direction (str): Migration steps to be given to users. version (str or int): The version when the object will be removed """ def decorator(func): @wraps(func) def wrapped(*args, **kwargs): message = ( f"{func.__module__}.{func.__name__} has been deprecated " f'and will be removed from {"future" if version is None else version} release. ' f"{direction}") warnings.warn(message, stacklevel=2) return func(*args, **kwargs) return wrapped return decorator def is_kaldi_available(): try: from paddleaudio import _paddleaudio return True except Exception: return False def requires_kaldi(): if is_kaldi_available(): def decorator(func): return func else: def decorator(func): @wraps(func) def wrapped(*args, **kwargs): raise RuntimeError( f"{func.__module__}.{func.__name__} requires libpaddleaudio build with kaldi") return wrapped return decorator def _check_soundfile_importable(): if not is_module_available("soundfile"): return False try: import soundfile # noqa: F401 return True except Exception: warnings.warn( "Failed to import soundfile. 'soundfile' backend is not available.") return False _is_soundfile_importable = _check_soundfile_importable() def is_soundfile_available(): return _is_soundfile_importable def requires_soundfile(): if is_soundfile_available(): def decorator(func): return func else: def decorator(func): @wraps(func) def wrapped(*args, **kwargs): raise RuntimeError( f"{func.__module__}.{func.__name__} requires soundfile") return wrapped return decorator def is_sox_available(): try: from paddleaudio import _paddleaudio return True except Exception: return False def requires_sox(): if is_sox_available(): def decorator(func): return func else: def decorator(func): @wraps(func) def wrapped(*args, **kwargs): raise RuntimeError( f"{func.__module__}.{func.__name__} requires libpaddleaudio build with sox") return wrapped return decorator ================================================ FILE: audio/paddleaudio/backends/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from . import utils from .soundfile_backend import depth_convert from .soundfile_backend import normalize from .soundfile_backend import resample from .soundfile_backend import soundfile_load from .soundfile_backend import soundfile_save from .soundfile_backend import to_mono from .utils import get_audio_backend from .utils import list_audio_backends from .utils import set_audio_backend utils._init_audio_backend() ================================================ FILE: audio/paddleaudio/backends/common.py ================================================ # Token from https://github.com/pytorch/audio/blob/main/torchaudio/backend/common.py with modification. class AudioInfo: """return of info function. This class is used by :ref:`"sox_io" backend` and :ref:`"soundfile" backend with the new interface`. :ivar int sample_rate: Sample rate :ivar int num_frames: The number of frames :ivar int num_channels: The number of channels :ivar int bits_per_sample: The number of bits per sample. This is 0 for lossy formats, or when it cannot be accurately inferred. :ivar str encoding: Audio encoding The values encoding can take are one of the following: * ``PCM_S``: Signed integer linear PCM * ``PCM_U``: Unsigned integer linear PCM * ``PCM_F``: Floating point linear PCM * ``FLAC``: Flac, Free Lossless Audio Codec * ``ULAW``: Mu-law * ``ALAW``: A-law * ``MP3`` : MP3, MPEG-1 Audio Layer III * ``VORBIS``: OGG Vorbis * ``AMR_WB``: Adaptive Multi-Rate * ``AMR_NB``: Adaptive Multi-Rate Wideband * ``OPUS``: Opus * ``HTK``: Single channel 16-bit PCM * ``UNKNOWN`` : None of above """ def __init__( self, sample_rate: int, num_frames: int, num_channels: int, bits_per_sample: int, encoding: str, ): self.sample_rate = sample_rate self.num_frames = num_frames self.num_channels = num_channels self.bits_per_sample = bits_per_sample self.encoding = encoding def __str__(self): return (f"AudioMetaData(" f"sample_rate={self.sample_rate}, " f"num_frames={self.num_frames}, " f"num_channels={self.num_channels}, " f"bits_per_sample={self.bits_per_sample}, " f"encoding={self.encoding}" f")") ================================================ FILE: audio/paddleaudio/backends/no_backend.py ================================================ from pathlib import Path from typing import Callable from typing import Optional from typing import Tuple from typing import Union from paddle import Tensor #code is from: https://github.com/pytorch/audio/blob/main/torchaudio/backend/no_backend.py def load( filepath: Union[str, Path], out: Optional[Tensor]=None, normalization: Union[bool, float, Callable]=True, channels_first: bool=True, num_frames: int=0, offset: int=0, filetype: Optional[str]=None, ) -> Tuple[Tensor, int]: raise RuntimeError("No audio I/O backend is available.") def save(filepath: str, src: Tensor, sample_rate: int, precision: int=16, channels_first: bool=True) -> None: raise RuntimeError("No audio I/O backend is available.") def info(filepath: str) -> None: raise RuntimeError("No audio I/O backend is available.") ================================================ FILE: audio/paddleaudio/backends/soundfile_backend.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import warnings from typing import Optional from typing import Tuple import numpy as np import paddle import resampy import soundfile from scipy.io import wavfile from ..utils import depth_convert from ..utils import ParameterError from .common import AudioInfo __all__ = [ 'resample', 'to_mono', 'normalize', 'save', 'soundfile_save', 'load', 'soundfile_load', 'info', ] NORMALMIZE_TYPES = ['linear', 'gaussian'] MERGE_TYPES = ['ch0', 'ch1', 'random', 'average'] RESAMPLE_MODES = ['kaiser_best', 'kaiser_fast'] EPS = 1e-8 def resample(y: np.ndarray, src_sr: int, target_sr: int, mode: str='kaiser_fast') -> np.ndarray: """Audio resampling. Args: y (np.ndarray): Input waveform array in 1D or 2D. src_sr (int): Source sample rate. target_sr (int): Target sample rate. mode (str, optional): The resampling filter to use. Defaults to 'kaiser_fast'. Returns: np.ndarray: `y` resampled to `target_sr` """ if mode == 'kaiser_best': warnings.warn( f'Using resampy in kaiser_best to {src_sr}=>{target_sr}. This function is pretty slow, \ we recommend the mode kaiser_fast in large scale audio training') if not isinstance(y, np.ndarray): raise ParameterError( 'Only support numpy np.ndarray, but received y in {type(y)}') if mode not in RESAMPLE_MODES: raise ParameterError(f'resample mode must in {RESAMPLE_MODES}') return resampy.resample(y, src_sr, target_sr, filter=mode) def to_mono(y: np.ndarray, merge_type: str='average') -> np.ndarray: """Convert sterior audio to mono. Args: y (np.ndarray): Input waveform array in 1D or 2D. merge_type (str, optional): Merge type to generate mono waveform. Defaults to 'average'. Returns: np.ndarray: `y` with mono channel. """ if merge_type not in MERGE_TYPES: raise ParameterError( f'Unsupported merge type {merge_type}, available types are {MERGE_TYPES}' ) if y.ndim > 2: raise ParameterError( f'Unsupported audio array, y.ndim > 2, the shape is {y.shape}') if y.ndim == 1: # nothing to merge return y if merge_type == 'ch0': return y[0] if merge_type == 'ch1': return y[1] if merge_type == 'random': return y[np.random.randint(0, 2)] # need to do averaging according to dtype if y.dtype == 'float32': y_out = (y[0] + y[1]) * 0.5 elif y.dtype == 'int16': y_out = y.astype('int32') y_out = (y_out[0] + y_out[1]) // 2 y_out = np.clip(y_out, np.iinfo(y.dtype).min, np.iinfo(y.dtype).max).astype(y.dtype) elif y.dtype == 'int8': y_out = y.astype('int16') y_out = (y_out[0] + y_out[1]) // 2 y_out = np.clip(y_out, np.iinfo(y.dtype).min, np.iinfo(y.dtype).max).astype(y.dtype) else: raise ParameterError(f'Unsupported dtype: {y.dtype}') return y_out def soundfile_load_(file: os.PathLike, offset: Optional[float]=None, dtype: str='int16', duration: Optional[int]=None) -> Tuple[np.ndarray, int]: """Load audio using soundfile library. This function load audio file using libsndfile. Args: file (os.PathLike): File of waveform. offset (Optional[float], optional): Offset to the start of waveform. Defaults to None. dtype (str, optional): Data type of waveform. Defaults to 'int16'. duration (Optional[int], optional): Duration of waveform to read. Defaults to None. Returns: Tuple[np.ndarray, int]: Waveform in ndarray and its samplerate. """ with soundfile.SoundFile(file) as sf_desc: sr_native = sf_desc.samplerate if offset: sf_desc.seek(int(offset * sr_native)) if duration is not None: frame_duration = int(duration * sr_native) else: frame_duration = -1 y = sf_desc.read(frames=frame_duration, dtype=dtype, always_2d=False).T return y, sf_desc.samplerate def normalize(y: np.ndarray, norm_type: str='linear', mul_factor: float=1.0) -> np.ndarray: """Normalize an input audio with additional multiplier. Args: y (np.ndarray): Input waveform array in 1D or 2D. norm_type (str, optional): Type of normalization. Defaults to 'linear'. mul_factor (float, optional): Scaling factor. Defaults to 1.0. Returns: np.ndarray: `y` after normalization. """ if norm_type == 'linear': amax = np.max(np.abs(y)) factor = 1.0 / (amax + EPS) y = y * factor * mul_factor elif norm_type == 'gaussian': amean = np.mean(y) astd = np.std(y) astd = max(astd, EPS) y = mul_factor * (y - amean) / astd else: raise NotImplementedError(f'norm_type should be in {NORMALMIZE_TYPES}') return y def soundfile_save(y: np.ndarray, sr: int, file: os.PathLike) -> None: """Save audio file to disk. This function saves audio to disk using scipy.io.wavfile, with additional step to convert input waveform to int16. Args: y (np.ndarray): Input waveform array in 1D or 2D. sr (int): Sample rate. file (os.PathLike): Path of audio file to save. """ if not file.endswith('.wav'): raise ParameterError( f'only .wav file supported, but dst file name is: {file}') if sr <= 0: raise ParameterError( f'Sample rate should be larger than 0, received sr = {sr}') if y.dtype not in ['int16', 'int8']: warnings.warn( f'input data type is {y.dtype}, will convert data to int16 format before saving' ) y_out = depth_convert(y, 'int16') else: y_out = y wavfile.write(file, sr, y_out) def soundfile_load( file: os.PathLike, sr: Optional[int]=None, mono: bool=True, merge_type: str='average', # ch0,ch1,random,average normal: bool=True, norm_type: str='linear', norm_mul_factor: float=1.0, offset: float=0.0, duration: Optional[int]=None, dtype: str='float32', resample_mode: str='kaiser_fast') -> Tuple[np.ndarray, int]: """Load audio file from disk. This function loads audio from disk using using audio backend. Args: file (os.PathLike): Path of audio file to load. sr (Optional[int], optional): Sample rate of loaded waveform. Defaults to None. mono (bool, optional): Return waveform with mono channel. Defaults to True. merge_type (str, optional): Merge type of multi-channels waveform. Defaults to 'average'. normal (bool, optional): Waveform normalization. Defaults to True. norm_type (str, optional): Type of normalization. Defaults to 'linear'. norm_mul_factor (float, optional): Scaling factor. Defaults to 1.0. offset (float, optional): Offset to the start of waveform. Defaults to 0.0. duration (Optional[int], optional): Duration of waveform to read. Defaults to None. dtype (str, optional): Data type of waveform. Defaults to 'float32'. resample_mode (str, optional): The resampling filter to use. Defaults to 'kaiser_fast'. Returns: Tuple[np.ndarray, int]: Waveform in ndarray and its samplerate. """ y, r = soundfile_load_(file, offset=offset, dtype=dtype, duration=duration) if not ((y.ndim == 1 and len(y) > 0) or (y.ndim == 2 and len(y[0]) > 0)): raise ParameterError(f'audio file {file} looks empty') if mono: y = to_mono(y, merge_type) if sr is not None and sr != r: y = resample(y, r, sr, mode=resample_mode) r = sr if normal: y = normalize(y, norm_type, norm_mul_factor) elif dtype in ['int8', 'int16']: # still need to do normalization, before depth conversion y = normalize(y, 'linear', 1.0) y = depth_convert(y, dtype) return y, r #The code below is taken from: https://github.com/pytorch/audio/blob/main/torchaudio/backend/soundfile_backend.py, with some modifications. def _get_subtype_for_wav(dtype: paddle.dtype, encoding: str, bits_per_sample: int): if not encoding: if not bits_per_sample: subtype = { paddle.uint8: "PCM_U8", paddle.int16: "PCM_16", paddle.int32: "PCM_32", paddle.float32: "FLOAT", paddle.float64: "DOUBLE", }.get(dtype) if not subtype: raise ValueError(f"Unsupported dtype for wav: {dtype}") return subtype if bits_per_sample == 8: return "PCM_U8" return f"PCM_{bits_per_sample}" if encoding == "PCM_S": if not bits_per_sample: return "PCM_32" if bits_per_sample == 8: raise ValueError("wav does not support 8-bit signed PCM encoding.") return f"PCM_{bits_per_sample}" if encoding == "PCM_U": if bits_per_sample in (None, 8): return "PCM_U8" raise ValueError("wav only supports 8-bit unsigned PCM encoding.") if encoding == "PCM_F": if bits_per_sample in (None, 32): return "FLOAT" if bits_per_sample == 64: return "DOUBLE" raise ValueError("wav only supports 32/64-bit float PCM encoding.") if encoding == "ULAW": if bits_per_sample in (None, 8): return "ULAW" raise ValueError("wav only supports 8-bit mu-law encoding.") if encoding == "ALAW": if bits_per_sample in (None, 8): return "ALAW" raise ValueError("wav only supports 8-bit a-law encoding.") raise ValueError(f"wav does not support {encoding}.") def _get_subtype_for_sphere(encoding: str, bits_per_sample: int): if encoding in (None, "PCM_S"): return f"PCM_{bits_per_sample}" if bits_per_sample else "PCM_32" if encoding in ("PCM_U", "PCM_F"): raise ValueError(f"sph does not support {encoding} encoding.") if encoding == "ULAW": if bits_per_sample in (None, 8): return "ULAW" raise ValueError("sph only supports 8-bit for mu-law encoding.") if encoding == "ALAW": return "ALAW" raise ValueError(f"sph does not support {encoding}.") def _get_subtype(dtype: paddle.dtype, format: str, encoding: str, bits_per_sample: int): if format == "wav": return _get_subtype_for_wav(dtype, encoding, bits_per_sample) if format == "flac": if encoding: raise ValueError("flac does not support encoding.") if not bits_per_sample: return "PCM_16" if bits_per_sample > 24: raise ValueError("flac does not support bits_per_sample > 24.") return "PCM_S8" if bits_per_sample == 8 else f"PCM_{bits_per_sample}" if format in ("ogg", "vorbis"): if encoding or bits_per_sample: raise ValueError( "ogg/vorbis does not support encoding/bits_per_sample.") return "VORBIS" if format == "sph": return _get_subtype_for_sphere(encoding, bits_per_sample) if format in ("nis", "nist"): return "PCM_16" raise ValueError(f"Unsupported format: {format}") def save( filepath: str, src: paddle.Tensor, sample_rate: int, channels_first: bool=True, compression: Optional[float]=None, format: Optional[str]=None, encoding: Optional[str]=None, bits_per_sample: Optional[int]=None, ): """Save audio data to file. Note: The formats this function can handle depend on the soundfile installation. This function is tested on the following formats; * WAV * 32-bit floating-point * 32-bit signed integer * 16-bit signed integer * 8-bit unsigned integer * FLAC * OGG/VORBIS * SPHERE Note: ``filepath`` argument is intentionally annotated as ``str`` only, even though it accepts ``pathlib.Path`` object as well. This is for the consistency with ``"sox_io"`` backend, Args: filepath (str or pathlib.Path): Path to audio file. src (paddle.Tensor): Audio data to save. must be 2D tensor. sample_rate (int): sampling rate channels_first (bool, optional): If ``True``, the given tensor is interpreted as `[channel, time]`, otherwise `[time, channel]`. compression (float of None, optional): Not used. It is here only for interface compatibility reason with "sox_io" backend. format (str or None, optional): Override the audio format. When ``filepath`` argument is path-like object, audio format is inferred from file extension. If the file extension is missing or different, you can specify the correct format with this argument. When ``filepath`` argument is file-like object, this argument is required. Valid values are ``"wav"``, ``"ogg"``, ``"vorbis"``, ``"flac"`` and ``"sph"``. encoding (str or None, optional): Changes the encoding for supported formats. This argument is effective only for supported formats, such as ``"wav"``, ``""flac"`` and ``"sph"``. Valid values are: - ``"PCM_S"`` (signed integer Linear PCM) - ``"PCM_U"`` (unsigned integer Linear PCM) - ``"PCM_F"`` (floating point PCM) - ``"ULAW"`` (mu-law) - ``"ALAW"`` (a-law) bits_per_sample (int or None, optional): Changes the bit depth for the supported formats. When ``format`` is one of ``"wav"``, ``"flac"`` or ``"sph"``, you can change the bit depth. Valid values are ``8``, ``16``, ``24``, ``32`` and ``64``. Supported formats/encodings/bit depth/compression are: ``"wav"`` - 32-bit floating-point PCM - 32-bit signed integer PCM - 24-bit signed integer PCM - 16-bit signed integer PCM - 8-bit unsigned integer PCM - 8-bit mu-law - 8-bit a-law Note: Default encoding/bit depth is determined by the dtype of the input Tensor. ``"flac"`` - 8-bit - 16-bit (default) - 24-bit ``"ogg"``, ``"vorbis"`` - Doesn't accept changing configuration. ``"sph"`` - 8-bit signed integer PCM - 16-bit signed integer PCM - 24-bit signed integer PCM - 32-bit signed integer PCM (default) - 8-bit mu-law - 8-bit a-law - 16-bit a-law - 24-bit a-law - 32-bit a-law """ if src.ndim != 2: raise ValueError(f"Expected 2D Tensor, got {src.ndim}D.") if compression is not None: warnings.warn( '`save` function of "soundfile" backend does not support "compression" parameter. ' "The argument is silently ignored.") if hasattr(filepath, "write"): if format is None: raise RuntimeError( "`format` is required when saving to file object.") ext = format.lower() else: ext = str(filepath).split(".")[-1].lower() if bits_per_sample not in (None, 8, 16, 24, 32, 64): raise ValueError("Invalid bits_per_sample.") if bits_per_sample == 24: warnings.warn( "Saving audio with 24 bits per sample might warp samples near -1. " "Using 16 bits per sample might be able to avoid this.") subtype = _get_subtype(src.dtype, ext, encoding, bits_per_sample) # sph is a extension used in TED-LIUM but soundfile does not recognize it as NIST format, # so we extend the extensions manually here if ext in ["nis", "nist", "sph"] and format is None: format = "NIST" if channels_first: src = src.t() soundfile.write( file=filepath, data=src, samplerate=sample_rate, subtype=subtype, format=format) _SUBTYPE2DTYPE = { "PCM_S8": "int8", "PCM_U8": "uint8", "PCM_16": "int16", "PCM_32": "int32", "FLOAT": "float32", "DOUBLE": "float64", } def load( filepath: str, frame_offset: int=0, num_frames: int=-1, normalize: bool=True, channels_first: bool=True, format: Optional[str]=None, ) -> Tuple[paddle.Tensor, int]: """Load audio data from file. Note: The formats this function can handle depend on the soundfile installation. This function is tested on the following formats; * WAV * 32-bit floating-point * 32-bit signed integer * 16-bit signed integer * 8-bit unsigned integer * FLAC * OGG/VORBIS * SPHERE By default (``normalize=True``, ``channels_first=True``), this function returns Tensor with ``float32`` dtype and the shape of `[channel, time]`. The samples are normalized to fit in the range of ``[-1.0, 1.0]``. When the input format is WAV with integer type, such as 32-bit signed integer, 16-bit signed integer and 8-bit unsigned integer (24-bit signed integer is not supported), by providing ``normalize=False``, this function can return integer Tensor, where the samples are expressed within the whole range of the corresponding dtype, that is, ``int32`` tensor for 32-bit signed PCM, ``int16`` for 16-bit signed PCM and ``uint8`` for 8-bit unsigned PCM. ``normalize`` parameter has no effect on 32-bit floating-point WAV and other formats, such as ``flac`` and ``mp3``. For these formats, this function always returns ``float32`` Tensor with values normalized to ``[-1.0, 1.0]``. Note: ``filepath`` argument is intentionally annotated as ``str`` only, even though it accepts ``pathlib.Path`` object as well. This is for the consistency with ``"sox_io"`` backend. Args: filepath (path-like object or file-like object): Source of audio data. frame_offset (int, optional): Number of frames to skip before start reading data. num_frames (int, optional): Maximum number of frames to read. ``-1`` reads all the remaining samples, starting from ``frame_offset``. This function may return the less number of frames if there is not enough frames in the given file. normalize (bool, optional): When ``True``, this function always return ``float32``, and sample values are normalized to ``[-1.0, 1.0]``. If input file is integer WAV, giving ``False`` will change the resulting Tensor type to integer type. This argument has no effect for formats other than integer WAV type. channels_first (bool, optional): When True, the returned Tensor has dimension `[channel, time]`. Otherwise, the returned Tensor's dimension is `[time, channel]`. format (str or None, optional): Not used. PySoundFile does not accept format hint. Returns: (paddle.Tensor, int): Resulting Tensor and sample rate. If the input file has integer wav format and normalization is off, then it has integer type, else ``float32`` type. If ``channels_first=True``, it has `[channel, time]` else `[time, channel]`. """ with soundfile.SoundFile(filepath, "r") as file_: if file_.format != "WAV" or normalize: dtype = "float32" elif file_.subtype not in _SUBTYPE2DTYPE: raise ValueError(f"Unsupported subtype: {file_.subtype}") else: dtype = _SUBTYPE2DTYPE[file_.subtype] frames = file_._prepare_read(frame_offset, None, num_frames) waveform = file_.read(frames, dtype, always_2d=True) sample_rate = file_.samplerate waveform = paddle.to_tensor(waveform) if channels_first: waveform = paddle.transpose(waveform, perm=[1, 0]) return waveform, sample_rate # Mapping from soundfile subtype to number of bits per sample. # This is mostly heuristical and the value is set to 0 when it is irrelevant # (lossy formats) or when it can't be inferred. # For ADPCM (and G72X) subtypes, it's hard to infer the bit depth because it's not part of the standard: # According to https://en.wikipedia.org/wiki/Adaptive_differential_pulse-code_modulation#In_telephony, # the default seems to be 8 bits but it can be compressed further to 4 bits. # The dict is inspired from # https://github.com/bastibe/python-soundfile/blob/744efb4b01abc72498a96b09115b42a4cabd85e4/soundfile.py#L66-L94 _SUBTYPE_TO_BITS_PER_SAMPLE = { "PCM_S8": 8, # Signed 8 bit data "PCM_16": 16, # Signed 16 bit data "PCM_24": 24, # Signed 24 bit data "PCM_32": 32, # Signed 32 bit data "PCM_U8": 8, # Unsigned 8 bit data (WAV and RAW only) "FLOAT": 32, # 32 bit float data "DOUBLE": 64, # 64 bit float data "ULAW": 8, # U-Law encoded. See https://en.wikipedia.org/wiki/G.711#Types "ALAW": 8, # A-Law encoded. See https://en.wikipedia.org/wiki/G.711#Types "IMA_ADPCM": 0, # IMA ADPCM. "MS_ADPCM": 0, # Microsoft ADPCM. "GSM610": 0, # GSM 6.10 encoding. (Wikipedia says 1.625 bit depth?? https://en.wikipedia.org/wiki/Full_Rate) "VOX_ADPCM": 0, # OKI / Dialogix ADPCM "G721_32": 0, # 32kbs G721 ADPCM encoding. "G723_24": 0, # 24kbs G723 ADPCM encoding. "G723_40": 0, # 40kbs G723 ADPCM encoding. "DWVW_12": 12, # 12 bit Delta Width Variable Word encoding. "DWVW_16": 16, # 16 bit Delta Width Variable Word encoding. "DWVW_24": 24, # 24 bit Delta Width Variable Word encoding. "DWVW_N": 0, # N bit Delta Width Variable Word encoding. "DPCM_8": 8, # 8 bit differential PCM (XI only) "DPCM_16": 16, # 16 bit differential PCM (XI only) "VORBIS": 0, # Xiph Vorbis encoding. (lossy) "ALAC_16": 16, # Apple Lossless Audio Codec (16 bit). "ALAC_20": 20, # Apple Lossless Audio Codec (20 bit). "ALAC_24": 24, # Apple Lossless Audio Codec (24 bit). "ALAC_32": 32, # Apple Lossless Audio Codec (32 bit). } def _get_bit_depth(subtype): if subtype not in _SUBTYPE_TO_BITS_PER_SAMPLE: warnings.warn( f"The {subtype} subtype is unknown to PaddleAudio. As a result, the bits_per_sample " "attribute will be set to 0. If you are seeing this warning, please " "report by opening an issue on github (after checking for existing/closed ones). " "You may otherwise ignore this warning.") return _SUBTYPE_TO_BITS_PER_SAMPLE.get(subtype, 0) _SUBTYPE_TO_ENCODING = { "PCM_S8": "PCM_S", "PCM_16": "PCM_S", "PCM_24": "PCM_S", "PCM_32": "PCM_S", "PCM_U8": "PCM_U", "FLOAT": "PCM_F", "DOUBLE": "PCM_F", "ULAW": "ULAW", "ALAW": "ALAW", "VORBIS": "VORBIS", } def _get_encoding(format: str, subtype: str): if format == "FLAC": return "FLAC" return _SUBTYPE_TO_ENCODING.get(subtype, "UNKNOWN") def info(filepath: str, format: Optional[str]=None) -> AudioInfo: """Get signal information of an audio file. Note: ``filepath`` argument is intentionally annotated as ``str`` only, even though it accepts ``pathlib.Path`` object as well. This is for the consistency with ``"sox_io"`` backend, Args: filepath (path-like object or file-like object): Source of audio data. format (str or None, optional): Not used. PySoundFile does not accept format hint. Returns: AudioInfo: meta data of the given audio. """ sinfo = soundfile.info(filepath) return AudioInfo( sinfo.samplerate, sinfo.frames, sinfo.channels, bits_per_sample=_get_bit_depth(sinfo.subtype), encoding=_get_encoding(sinfo.format, sinfo.subtype), ) ================================================ FILE: audio/paddleaudio/backends/sox_io_backend.py ================================================ import os from typing import Optional from typing import Tuple import paddle import paddleaudio from paddle import Tensor from paddleaudio._internal import module_utils as _mod_utils from .common import AudioInfo #https://github.com/pytorch/audio/blob/main/torchaudio/backend/sox_io_backend.py def _fail_info(filepath: str, format: Optional[str]) -> AudioInfo: raise RuntimeError("Failed to fetch metadata from {}".format(filepath)) def _fail_info_fileobj(fileobj, format: Optional[str]) -> AudioInfo: raise RuntimeError("Failed to fetch metadata from {}".format(fileobj)) # Note: need to comply TorchScript syntax -- need annotation and no f-string def _fail_load( filepath: str, frame_offset: int=0, num_frames: int=-1, normalize: bool=True, channels_first: bool=True, format: Optional[str]=None, ) -> Tuple[Tensor, int]: raise RuntimeError("Failed to load audio from {}".format(filepath)) def _fail_load_fileobj(fileobj, *args, **kwargs): raise RuntimeError(f"Failed to load audio from {fileobj}") _fallback_info = _fail_info _fallback_info_fileobj = _fail_info_fileobj _fallback_load = _fail_load _fallback_load_filebj = _fail_load_fileobj @_mod_utils.requires_sox() def load( filepath: str, frame_offset: int=0, num_frames: int=-1, normalize: bool=True, channels_first: bool=True, format: Optional[str]=None, ) -> Tuple[Tensor, int]: if hasattr(filepath, "read"): ret = paddleaudio._paddleaudio.load_audio_fileobj( filepath, frame_offset, num_frames, normalize, channels_first, format) if ret is not None: audio_tensor = paddle.to_tensor(ret[0]) return (audio_tensor, ret[1]) return _fallback_load_fileobj(filepath, frame_offset, num_frames, normalize, channels_first, format) filepath = os.fspath(filepath) ret = paddleaudio._paddleaudio.sox_io_load_audio_file( filepath, frame_offset, num_frames, normalize, channels_first, format) if ret is not None: audio_tensor = paddle.to_tensor(ret[0]) return (audio_tensor, ret[1]) return _fallback_load(filepath, frame_offset, num_frames, normalize, channels_first, format) @_mod_utils.requires_sox() def save( filepath: str, src: Tensor, sample_rate: int, channels_first: bool=True, compression: Optional[float]=None, format: Optional[str]=None, encoding: Optional[str]=None, bits_per_sample: Optional[int]=None, ): src_arr = src.numpy() if hasattr(filepath, "write"): paddleaudio._paddleaudio.save_audio_fileobj( filepath, src_arr, sample_rate, channels_first, compression, format, encoding, bits_per_sample) return filepath = os.fspath(filepath) paddleaudio._paddleaudio.sox_io_save_audio_file( filepath, src_arr, sample_rate, channels_first, compression, format, encoding, bits_per_sample) @_mod_utils.requires_sox() def info( filepath: str, format: Optional[str]=None, ) -> AudioInfo: if hasattr(filepath, "read"): sinfo = paddleaudio._paddleaudio.get_info_fileobj(filepath, format) if sinfo is not None: return AudioInfo(*sinfo) return _fallback_info_fileobj(filepath, format) filepath = os.fspath(filepath) sinfo = paddleaudio._paddleaudio.get_info_file(filepath, format) if sinfo is not None: return AudioInfo(*sinfo) return _fallback_info(filepath, format) ================================================ FILE: audio/paddleaudio/backends/utils.py ================================================ """Defines utilities for switching audio backends""" #code is from: https://github.com/pytorch/audio/blob/main/torchaudio/backend/utils.py import warnings from typing import List from typing import Optional import paddleaudio from paddleaudio._internal import module_utils as _mod_utils from . import no_backend from . import soundfile_backend from . import sox_io_backend __all__ = [ "list_audio_backends", "get_audio_backend", "set_audio_backend", ] def list_audio_backends() -> List[str]: """List available backends Returns: List[str]: The list of available backends. """ backends = [] if _mod_utils.is_module_available("soundfile"): backends.append("soundfile") if _mod_utils.is_sox_available(): backends.append("sox_io") return backends def set_audio_backend(backend: Optional[str]): """Set the backend for I/O operation Args: backend (str or None): Name of the backend. One of ``"sox_io"`` or ``"soundfile"`` based on availability of the system. If ``None`` is provided the current backend is unassigned. """ if backend is not None and backend not in list_audio_backends(): raise RuntimeError(f'Backend "{backend}" is not one of ' f"available backends: {list_audio_backends()}.") if backend is None: module = no_backend elif backend == "sox_io": module = sox_io_backend elif backend == "soundfile": module = soundfile_backend else: raise NotImplementedError(f'Unexpected backend "{backend}"') for func in ["save", "load", "info"]: setattr(paddleaudio, func, getattr(module, func)) def _init_audio_backend(): backends = list_audio_backends() if "soundfile" in backends: set_audio_backend("soundfile") elif "sox_io" in backends: set_audio_backend("sox_io") else: warnings.warn("No audio backend is available.") set_audio_backend(None) def get_audio_backend() -> Optional[str]: """Get the name of the current backend Returns: Optional[str]: The name of the current backend or ``None`` if no backend is assigned. """ if paddleaudio.load == no_backend.load: return None if paddleaudio.load == sox_io_backend.load: return "sox_io" if paddleaudio.load == soundfile_backend.load: return "soundfile" raise ValueError("Unknown backend.") ================================================ FILE: audio/paddleaudio/compliance/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from . import kaldi from . import librosa ================================================ FILE: audio/paddleaudio/compliance/kaldi.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. # Modified from torchaudio(https://github.com/pytorch/audio) import math from typing import Tuple import paddle from paddle import Tensor from ..functional import create_dct from ..functional.window import get_window __all__ = [ 'spectrogram', 'fbank', 'mfcc', ] # window types HANNING = 'hann' HAMMING = 'hamming' POVEY = 'povey' RECTANGULAR = 'rect' BLACKMAN = 'blackman' def _get_epsilon(dtype): return paddle.to_tensor(1e-07, dtype=dtype) def _next_power_of_2(x: int) -> int: return 1 if x == 0 else 2**(x - 1).bit_length() def _get_strided(waveform: Tensor, window_size: int, window_shift: int, snip_edges: bool) -> Tensor: assert waveform.dim() == 1 num_samples = waveform.shape[0] if snip_edges: if num_samples < window_size: return paddle.empty((0, 0), dtype=waveform.dtype) else: m = 1 + (num_samples - window_size) // window_shift else: reversed_waveform = paddle.flip(waveform, [0]) m = (num_samples + (window_shift // 2)) // window_shift pad = window_size // 2 - window_shift // 2 pad_right = reversed_waveform if pad > 0: pad_left = reversed_waveform[-pad:] waveform = paddle.concat((pad_left, waveform, pad_right), axis=0) else: waveform = paddle.concat((waveform[-pad:], pad_right), axis=0) return paddle.signal.frame(waveform, window_size, window_shift)[:, :m].T def _feature_window_function( window_type: str, window_size: int, blackman_coeff: float, dtype: int, ) -> Tensor: if window_type == "hann": return get_window('hann', window_size, fftbins=False, dtype=dtype) elif window_type == "hamming": return get_window('hamming', window_size, fftbins=False, dtype=dtype) elif window_type == "povey": return get_window( 'hann', window_size, fftbins=False, dtype=dtype).pow(0.85) elif window_type == "rect": return paddle.ones([window_size], dtype=dtype) elif window_type == "blackman": a = 2 * math.pi / (window_size - 1) window_function = paddle.arange(window_size, dtype=dtype) return (blackman_coeff - 0.5 * paddle.cos(a * window_function) + (0.5 - blackman_coeff) * paddle.cos(2 * a * window_function) ).astype(dtype) else: raise Exception('Invalid window type ' + window_type) def _get_log_energy(strided_input: Tensor, epsilon: Tensor, energy_floor: float) -> Tensor: log_energy = paddle.maximum(strided_input.pow(2).sum(1), epsilon).log() if energy_floor == 0.0: return log_energy return paddle.maximum( log_energy, paddle.to_tensor(math.log(energy_floor), dtype=strided_input.dtype)) def _get_waveform_and_window_properties( waveform: Tensor, channel: int, sr: int, frame_shift: float, frame_length: float, round_to_power_of_two: bool, preemphasis_coefficient: float) -> Tuple[Tensor, int, int, int]: channel = max(channel, 0) assert channel < waveform.shape[0], ( 'Invalid channel {} for size {}'.format(channel, waveform.shape[0])) waveform = waveform[channel, :] # size (n) window_shift = int( sr * frame_shift * 0.001) # pass frame_shift and frame_length in milliseconds window_size = int(sr * frame_length * 0.001) padded_window_size = _next_power_of_2( window_size) if round_to_power_of_two else window_size assert 2 <= window_size <= len(waveform), ( 'choose a window size {} that is [2, {}]'.format(window_size, len(waveform))) assert 0 < window_shift, '`window_shift` must be greater than 0' assert padded_window_size % 2 == 0, 'the padded `window_size` must be divisible by two.' \ ' use `round_to_power_of_two` or change `frame_length`' assert 0. <= preemphasis_coefficient <= 1.0, '`preemphasis_coefficient` must be between [0,1]' assert sr > 0, '`sr` must be greater than zero' return waveform, window_shift, window_size, padded_window_size def _get_window(waveform: Tensor, padded_window_size: int, window_size: int, window_shift: int, window_type: str, blackman_coeff: float, snip_edges: bool, raw_energy: bool, energy_floor: float, dither: float, remove_dc_offset: bool, preemphasis_coefficient: float) -> Tuple[Tensor, Tensor]: dtype = waveform.dtype epsilon = _get_epsilon(dtype) # (m, window_size) strided_input = _get_strided(waveform, window_size, window_shift, snip_edges) if dither != 0.0: x = paddle.maximum(epsilon, paddle.rand(strided_input.shape, dtype=dtype)) rand_gauss = paddle.sqrt(-2 * x.log()) * paddle.cos(2 * math.pi * x) strided_input = strided_input + rand_gauss * dither if remove_dc_offset: row_means = paddle.mean(strided_input, axis=1).unsqueeze(1) # (m, 1) strided_input = strided_input - row_means if raw_energy: signal_log_energy = _get_log_energy(strided_input, epsilon, energy_floor) # (m) if preemphasis_coefficient != 0.0: offset_strided_input = paddle.nn.functional.pad( strided_input.unsqueeze(0), (1, 0), data_format='NCL', mode='replicate').squeeze(0) # (m, window_size + 1) strided_input = strided_input - preemphasis_coefficient * offset_strided_input[:, : -1] window_function = _feature_window_function( window_type, window_size, blackman_coeff, dtype).unsqueeze(0) # (1, window_size) strided_input = strided_input * window_function # (m, window_size) # (m, padded_window_size) if padded_window_size != window_size: padding_right = padded_window_size - window_size strided_input = paddle.nn.functional.pad( strided_input.unsqueeze(0), (0, padding_right), data_format='NCL', mode='constant', value=0).squeeze(0) if not raw_energy: signal_log_energy = _get_log_energy(strided_input, epsilon, energy_floor) # size (m) return strided_input, signal_log_energy def _subtract_column_mean(tensor: Tensor, subtract_mean: bool) -> Tensor: if subtract_mean: col_means = paddle.mean(tensor, axis=0).unsqueeze(0) tensor = tensor - col_means return tensor def spectrogram(waveform: Tensor, blackman_coeff: float=0.42, channel: int=-1, dither: float=0.0, energy_floor: float=1.0, frame_length: float=25.0, frame_shift: float=10.0, preemphasis_coefficient: float=0.97, raw_energy: bool=True, remove_dc_offset: bool=True, round_to_power_of_two: bool=True, sr: int=16000, snip_edges: bool=True, subtract_mean: bool=False, window_type: str="povey") -> Tensor: """Compute and return a spectrogram from a waveform. The output is identical to Kaldi's. Args: waveform (Tensor): A waveform tensor with shape `(C, T)`. blackman_coeff (float, optional): Coefficient for Blackman window.. Defaults to 0.42. channel (int, optional): Select the channel of waveform. Defaults to -1. dither (float, optional): Dithering constant . Defaults to 0.0. energy_floor (float, optional): Floor on energy of the output Spectrogram. Defaults to 1.0. frame_length (float, optional): Frame length in milliseconds. Defaults to 25.0. frame_shift (float, optional): Shift between adjacent frames in milliseconds. Defaults to 10.0. preemphasis_coefficient (float, optional): Preemphasis coefficient for input waveform. Defaults to 0.97. raw_energy (bool, optional): Whether to compute before preemphasis and windowing. Defaults to True. remove_dc_offset (bool, optional): Whether to subtract mean from waveform on frames. Defaults to True. round_to_power_of_two (bool, optional): If True, round window size to power of two by zero-padding input to FFT. Defaults to True. sr (int, optional): Sample rate of input waveform. Defaults to 16000. snip_edges (bool, optional): Drop samples in the end of waveform that can't fit a signal frame when it is set True. Otherwise performs reflect padding to the end of waveform. Defaults to True. subtract_mean (bool, optional): Whether to subtract mean of feature files. Defaults to False. window_type (str, optional): Choose type of window for FFT computation. Defaults to "povey". Returns: Tensor: A spectrogram tensor with shape `(m, padded_window_size // 2 + 1)` where m is the number of frames depends on frame_length and frame_shift. """ dtype = waveform.dtype epsilon = _get_epsilon(dtype) waveform, window_shift, window_size, padded_window_size = _get_waveform_and_window_properties( waveform, channel, sr, frame_shift, frame_length, round_to_power_of_two, preemphasis_coefficient) strided_input, signal_log_energy = _get_window( waveform, padded_window_size, window_size, window_shift, window_type, blackman_coeff, snip_edges, raw_energy, energy_floor, dither, remove_dc_offset, preemphasis_coefficient) # (m, padded_window_size // 2 + 1, 2) fft = paddle.fft.rfft(strided_input) power_spectrum = paddle.maximum( fft.abs().pow(2.), epsilon).log() # (m, padded_window_size // 2 + 1) power_spectrum[:, 0] = signal_log_energy power_spectrum = _subtract_column_mean(power_spectrum, subtract_mean) return power_spectrum def _inverse_mel_scale_scalar(mel_freq: float) -> float: return 700.0 * (math.exp(mel_freq / 1127.0) - 1.0) def _inverse_mel_scale(mel_freq: Tensor) -> Tensor: return 700.0 * ((mel_freq / 1127.0).exp() - 1.0) def _mel_scale_scalar(freq: float) -> float: return 1127.0 * math.log(1.0 + freq / 700.0) def _mel_scale(freq: Tensor) -> Tensor: return 1127.0 * (1.0 + freq / 700.0).log() def _vtln_warp_freq(vtln_low_cutoff: float, vtln_high_cutoff: float, low_freq: float, high_freq: float, vtln_warp_factor: float, freq: Tensor) -> Tensor: assert vtln_low_cutoff > low_freq, 'be sure to set the vtln_low option higher than low_freq' assert vtln_high_cutoff < high_freq, 'be sure to set the vtln_high option lower than high_freq [or negative]' l = vtln_low_cutoff * max(1.0, vtln_warp_factor) h = vtln_high_cutoff * min(1.0, vtln_warp_factor) scale = 1.0 / vtln_warp_factor Fl = scale * l Fh = scale * h assert l > low_freq and h < high_freq scale_left = (Fl - low_freq) / (l - low_freq) scale_right = (high_freq - Fh) / (high_freq - h) res = paddle.empty_like(freq) outside_low_high_freq = paddle.less_than(freq, paddle.to_tensor(low_freq)) \ | paddle.greater_than(freq, paddle.to_tensor(high_freq)) before_l = paddle.less_than(freq, paddle.to_tensor(l)) before_h = paddle.less_than(freq, paddle.to_tensor(h)) after_h = paddle.greater_equal(freq, paddle.to_tensor(h)) res[after_h] = high_freq + scale_right * (freq[after_h] - high_freq) res[before_h] = scale * freq[before_h] res[before_l] = low_freq + scale_left * (freq[before_l] - low_freq) res[outside_low_high_freq] = freq[outside_low_high_freq] return res def _vtln_warp_mel_freq(vtln_low_cutoff: float, vtln_high_cutoff: float, low_freq, high_freq: float, vtln_warp_factor: float, mel_freq: Tensor) -> Tensor: return _mel_scale( _vtln_warp_freq(vtln_low_cutoff, vtln_high_cutoff, low_freq, high_freq, vtln_warp_factor, _inverse_mel_scale(mel_freq))) def _get_mel_banks(num_bins: int, window_length_padded: int, sample_freq: float, low_freq: float, high_freq: float, vtln_low: float, vtln_high: float, vtln_warp_factor: float) -> Tuple[Tensor, Tensor]: assert num_bins > 3, 'Must have at least 3 mel bins' assert window_length_padded % 2 == 0 num_fft_bins = window_length_padded / 2 nyquist = 0.5 * sample_freq if high_freq <= 0.0: high_freq += nyquist assert (0.0 <= low_freq < nyquist) and (0.0 < high_freq <= nyquist) and (low_freq < high_freq), \ ('Bad values in options: low-freq {} and high-freq {} vs. nyquist {}'.format(low_freq, high_freq, nyquist)) fft_bin_width = sample_freq / window_length_padded mel_low_freq = _mel_scale_scalar(low_freq) mel_high_freq = _mel_scale_scalar(high_freq) mel_freq_delta = (mel_high_freq - mel_low_freq) / (num_bins + 1) if vtln_high < 0.0: vtln_high += nyquist assert vtln_warp_factor == 1.0 or ((low_freq < vtln_low < high_freq) and (0.0 < vtln_high < high_freq) and (vtln_low < vtln_high)), \ ('Bad values in options: vtln-low {} and vtln-high {}, versus ' 'low-freq {} and high-freq {}'.format(vtln_low, vtln_high, low_freq, high_freq)) bin = paddle.arange(num_bins, dtype=paddle.float32).unsqueeze(1) # left_mel = mel_low_freq + bin * mel_freq_delta # (num_bins, 1) # center_mel = mel_low_freq + (bin + 1.0) * mel_freq_delta # (num_bins, 1) # right_mel = mel_low_freq + (bin + 2.0) * mel_freq_delta # (num_bins, 1) left_mel = mel_low_freq + bin * mel_freq_delta # (num_bins, 1) center_mel = left_mel + mel_freq_delta right_mel = center_mel + mel_freq_delta if vtln_warp_factor != 1.0: left_mel = _vtln_warp_mel_freq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, left_mel) center_mel = _vtln_warp_mel_freq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, center_mel) right_mel = _vtln_warp_mel_freq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, right_mel) center_freqs = _inverse_mel_scale(center_mel) # (num_bins) # (1, num_fft_bins) mel = _mel_scale(fft_bin_width * paddle.arange( num_fft_bins, dtype=paddle.float32)).unsqueeze(0) # (num_bins, num_fft_bins) up_slope = (mel - left_mel) / (center_mel - left_mel) down_slope = (right_mel - mel) / (right_mel - center_mel) if vtln_warp_factor == 1.0: bins = paddle.maximum( paddle.zeros([1]), paddle.minimum(up_slope, down_slope)) else: bins = paddle.zeros_like(up_slope) up_idx = paddle.greater_than(mel, left_mel) & paddle.less_than( mel, center_mel) down_idx = paddle.greater_than(mel, center_mel) & paddle.less_than( mel, right_mel) bins[up_idx] = up_slope[up_idx] bins[down_idx] = down_slope[down_idx] return bins, center_freqs def fbank(waveform: Tensor, blackman_coeff: float=0.42, channel: int=-1, dither: float=0.0, energy_floor: float=1.0, frame_length: float=25.0, frame_shift: float=10.0, high_freq: float=0.0, htk_compat: bool=False, low_freq: float=20.0, n_mels: int=23, preemphasis_coefficient: float=0.97, raw_energy: bool=True, remove_dc_offset: bool=True, round_to_power_of_two: bool=True, sr: int=16000, snip_edges: bool=True, subtract_mean: bool=False, use_energy: bool=False, use_log_fbank: bool=True, use_power: bool=True, vtln_high: float=-500.0, vtln_low: float=100.0, vtln_warp: float=1.0, window_type: str="povey") -> Tensor: """Compute and return filter banks from a waveform. The output is identical to Kaldi's. Args: waveform (Tensor): A waveform tensor with shape `(C, T)`. `C` is in the range [0,1]. blackman_coeff (float, optional): Coefficient for Blackman window.. Defaults to 0.42. channel (int, optional): Select the channel of waveform. Defaults to -1. dither (float, optional): Dithering constant . Defaults to 0.0. energy_floor (float, optional): Floor on energy of the output Spectrogram. Defaults to 1.0. frame_length (float, optional): Frame length in milliseconds. Defaults to 25.0. frame_shift (float, optional): Shift between adjacent frames in milliseconds. Defaults to 10.0. high_freq (float, optional): The upper cut-off frequency. Defaults to 0.0. htk_compat (bool, optional): Put energy to the last when it is set True. Defaults to False. low_freq (float, optional): The lower cut-off frequency. Defaults to 20.0. n_mels (int, optional): Number of output mel bins. Defaults to 23. preemphasis_coefficient (float, optional): Preemphasis coefficient for input waveform. Defaults to 0.97. raw_energy (bool, optional): Whether to compute before preemphasis and windowing. Defaults to True. remove_dc_offset (bool, optional): Whether to subtract mean from waveform on frames. Defaults to True. round_to_power_of_two (bool, optional): If True, round window size to power of two by zero-padding input to FFT. Defaults to True. sr (int, optional): Sample rate of input waveform. Defaults to 16000. snip_edges (bool, optional): Drop samples in the end of waveform that can't fit a signal frame when it is set True. Otherwise performs reflect padding to the end of waveform. Defaults to True. subtract_mean (bool, optional): Whether to subtract mean of feature files. Defaults to False. use_energy (bool, optional): Add an dimension with energy of spectrogram to the output. Defaults to False. use_log_fbank (bool, optional): Return log fbank when it is set True. Defaults to True. use_power (bool, optional): Whether to use power instead of magnitude. Defaults to True. vtln_high (float, optional): High inflection point in piecewise linear VTLN warping function. Defaults to -500.0. vtln_low (float, optional): Low inflection point in piecewise linear VTLN warping function. Defaults to 100.0. vtln_warp (float, optional): Vtln warp factor. Defaults to 1.0. window_type (str, optional): Choose type of window for FFT computation. Defaults to "povey". Returns: Tensor: A filter banks tensor with shape `(m, n_mels)`. """ dtype = waveform.dtype waveform, window_shift, window_size, padded_window_size = _get_waveform_and_window_properties( waveform, channel, sr, frame_shift, frame_length, round_to_power_of_two, preemphasis_coefficient) strided_input, signal_log_energy = _get_window( waveform, padded_window_size, window_size, window_shift, window_type, blackman_coeff, snip_edges, raw_energy, energy_floor, dither, remove_dc_offset, preemphasis_coefficient) # (m, padded_window_size // 2 + 1) spectrum = paddle.fft.rfft(strided_input).abs() if use_power: spectrum = spectrum.pow(2.) # (n_mels, padded_window_size // 2) mel_energies, _ = _get_mel_banks(n_mels, padded_window_size, sr, low_freq, high_freq, vtln_low, vtln_high, vtln_warp) # mel_energies = mel_energies.astype(dtype) assert mel_energies.dtype == dtype # (n_mels, padded_window_size // 2 + 1) mel_energies = paddle.nn.functional.pad( mel_energies.unsqueeze(0), (0, 1), data_format='NCL', mode='constant', value=0).squeeze(0) # (m, n_mels) mel_energies = paddle.mm(spectrum, mel_energies.T) if use_log_fbank: mel_energies = paddle.maximum(mel_energies, _get_epsilon(dtype)).log() if use_energy: signal_log_energy = signal_log_energy.unsqueeze(1) if htk_compat: mel_energies = paddle.concat( (mel_energies, signal_log_energy), axis=1) else: mel_energies = paddle.concat( (signal_log_energy, mel_energies), axis=1) # (m, n_mels + 1) mel_energies = _subtract_column_mean(mel_energies, subtract_mean) return mel_energies def _get_dct_matrix(n_mfcc: int, n_mels: int) -> Tensor: dct_matrix = create_dct(n_mels, n_mels, 'ortho') dct_matrix[:, 0] = math.sqrt(1 / float(n_mels)) dct_matrix = dct_matrix[:, :n_mfcc] # (n_mels, n_mfcc) return dct_matrix def _get_lifter_coeffs(n_mfcc: int, cepstral_lifter: float) -> Tensor: i = paddle.arange(n_mfcc) return 1.0 + 0.5 * cepstral_lifter * paddle.sin(math.pi * i / cepstral_lifter) def mfcc(waveform: Tensor, blackman_coeff: float=0.42, cepstral_lifter: float=22.0, channel: int=-1, dither: float=0.0, energy_floor: float=1.0, frame_length: float=25.0, frame_shift: float=10.0, high_freq: float=0.0, htk_compat: bool=False, low_freq: float=20.0, n_mfcc: int=13, n_mels: int=23, preemphasis_coefficient: float=0.97, raw_energy: bool=True, remove_dc_offset: bool=True, round_to_power_of_two: bool=True, sr: int=16000, snip_edges: bool=True, subtract_mean: bool=False, use_energy: bool=False, vtln_high: float=-500.0, vtln_low: float=100.0, vtln_warp: float=1.0, window_type: str="povey") -> Tensor: """Compute and return mel frequency cepstral coefficients from a waveform. The output is identical to Kaldi's. Args: waveform (Tensor): A waveform tensor with shape `(C, T)`. blackman_coeff (float, optional): Coefficient for Blackman window.. Defaults to 0.42. cepstral_lifter (float, optional): Scaling of output mfccs. Defaults to 22.0. channel (int, optional): Select the channel of waveform. Defaults to -1. dither (float, optional): Dithering constant . Defaults to 0.0. energy_floor (float, optional): Floor on energy of the output Spectrogram. Defaults to 1.0. frame_length (float, optional): Frame length in milliseconds. Defaults to 25.0. frame_shift (float, optional): Shift between adjacent frames in milliseconds. Defaults to 10.0. high_freq (float, optional): The upper cut-off frequency. Defaults to 0.0. htk_compat (bool, optional): Put energy to the last when it is set True. Defaults to False. low_freq (float, optional): The lower cut-off frequency. Defaults to 20.0. n_mfcc (int, optional): Number of cepstra in MFCC. Defaults to 13. n_mels (int, optional): Number of output mel bins. Defaults to 23. preemphasis_coefficient (float, optional): Preemphasis coefficient for input waveform. Defaults to 0.97. raw_energy (bool, optional): Whether to compute before preemphasis and windowing. Defaults to True. remove_dc_offset (bool, optional): Whether to subtract mean from waveform on frames. Defaults to True. round_to_power_of_two (bool, optional): If True, round window size to power of two by zero-padding input to FFT. Defaults to True. sr (int, optional): Sample rate of input waveform. Defaults to 16000. snip_edges (bool, optional): Drop samples in the end of waveform that can't fit a signal frame when it is set True. Otherwise performs reflect padding to the end of waveform. Defaults to True. subtract_mean (bool, optional): Whether to subtract mean of feature files. Defaults to False. use_energy (bool, optional): Add an dimension with energy of spectrogram to the output. Defaults to False. vtln_high (float, optional): High inflection point in piecewise linear VTLN warping function. Defaults to -500.0. vtln_low (float, optional): Low inflection point in piecewise linear VTLN warping function. Defaults to 100.0. vtln_warp (float, optional): Vtln warp factor. Defaults to 1.0. window_type (str, optional): Choose type of window for FFT computation. Defaults to POVEY. Returns: Tensor: A mel frequency cepstral coefficients tensor with shape `(m, n_mfcc)`. """ assert n_mfcc <= n_mels, 'n_mfcc cannot be larger than n_mels: %d vs %d' % ( n_mfcc, n_mels) dtype = waveform.dtype # (m, n_mels + use_energy) feature = fbank( waveform=waveform, blackman_coeff=blackman_coeff, channel=channel, dither=dither, energy_floor=energy_floor, frame_length=frame_length, frame_shift=frame_shift, high_freq=high_freq, htk_compat=htk_compat, low_freq=low_freq, n_mels=n_mels, preemphasis_coefficient=preemphasis_coefficient, raw_energy=raw_energy, remove_dc_offset=remove_dc_offset, round_to_power_of_two=round_to_power_of_two, sr=sr, snip_edges=snip_edges, subtract_mean=False, use_energy=use_energy, use_log_fbank=True, use_power=True, vtln_high=vtln_high, vtln_low=vtln_low, vtln_warp=vtln_warp, window_type=window_type) if use_energy: # (m) signal_log_energy = feature[:, n_mels if htk_compat else 0] mel_offset = int(not htk_compat) feature = feature[:, mel_offset:(n_mels + mel_offset)] # (n_mels, n_mfcc) dct_matrix = _get_dct_matrix(n_mfcc, n_mels).astype(dtype=dtype) # (m, n_mfcc) feature = feature.matmul(dct_matrix) if cepstral_lifter != 0.0: # (1, n_mfcc) lifter_coeffs = _get_lifter_coeffs(n_mfcc, cepstral_lifter).unsqueeze(0) feature *= lifter_coeffs.astype(dtype=dtype) if use_energy: feature[:, 0] = signal_log_energy if htk_compat: energy = feature[:, 0].unsqueeze(1) # (m, 1) feature = feature[:, 1:] # (m, n_mfcc - 1) if not use_energy: energy *= math.sqrt(2) feature = paddle.concat((feature, energy), axis=1) feature = _subtract_column_mean(feature, subtract_mean) return feature ================================================ FILE: audio/paddleaudio/compliance/librosa.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. # Modified from librosa(https://github.com/librosa/librosa) import warnings from typing import List from typing import Optional from typing import Union import numpy as np import scipy from numpy.lib.stride_tricks import as_strided from scipy import signal from ..backends import depth_convert from ..utils import ParameterError __all__ = [ # dsp 'stft', 'mfcc', 'hz_to_mel', 'mel_to_hz', 'mel_frequencies', 'power_to_db', 'compute_fbank_matrix', 'melspectrogram', 'spectrogram', 'mu_encode', 'mu_decode', # augmentation 'depth_augment', 'spect_augment', 'random_crop1d', 'random_crop2d', 'adaptive_spect_augment', ] def _pad_center(data: np.ndarray, size: int, axis: int=-1, **kwargs) -> np.ndarray: """Pad an array to a target length along a target axis. This differs from `np.pad` by centering the data prior to padding, analogous to `str.center` """ kwargs.setdefault("mode", "constant") n = data.shape[axis] lpad = int((size - n) // 2) lengths = [(0, 0)] * data.ndim lengths[axis] = (lpad, int(size - n - lpad)) if lpad < 0: raise ParameterError(("Target size ({size:d}) must be " "at least input size ({n:d})")) return np.pad(data, lengths, **kwargs) def _split_frames(x: np.ndarray, frame_length: int, hop_length: int, axis: int=-1) -> np.ndarray: """Slice a data array into (overlapping) frames. This function is aligned with librosa.frame """ if not isinstance(x, np.ndarray): raise ParameterError( f"Input must be of type numpy.ndarray, given type(x)={type(x)}") if x.shape[axis] < frame_length: raise ParameterError(f"Input is too short (n={x.shape[axis]:d})" f" for frame_length={frame_length:d}") if hop_length < 1: raise ParameterError(f"Invalid hop_length: {hop_length:d}") if axis == -1 and not x.flags["F_CONTIGUOUS"]: warnings.warn(f"librosa.util.frame called with axis={axis} " "on a non-contiguous input. This will result in a copy.") x = np.asfortranarray(x) elif axis == 0 and not x.flags["C_CONTIGUOUS"]: warnings.warn(f"librosa.util.frame called with axis={axis} " "on a non-contiguous input. This will result in a copy.") x = np.ascontiguousarray(x) n_frames = 1 + (x.shape[axis] - frame_length) // hop_length strides = np.asarray(x.strides) new_stride = np.prod(strides[strides > 0] // x.itemsize) * x.itemsize if axis == -1: shape = list(x.shape)[:-1] + [frame_length, n_frames] strides = list(strides) + [hop_length * new_stride] elif axis == 0: shape = [n_frames, frame_length] + list(x.shape)[1:] strides = [hop_length * new_stride] + list(strides) else: raise ParameterError(f"Frame axis={axis} must be either 0 or -1") return as_strided(x, shape=shape, strides=strides) def _check_audio(y, mono=True) -> bool: """Determine whether a variable contains valid audio data. The audio y must be a np.ndarray, ether 1-channel or two channel """ if not isinstance(y, np.ndarray): raise ParameterError("Audio data must be of type numpy.ndarray") if y.ndim > 2: raise ParameterError( f"Invalid shape for audio ndim={y.ndim:d}, shape={y.shape}") if mono and y.ndim == 2: raise ParameterError( f"Invalid shape for mono audio ndim={y.ndim:d}, shape={y.shape}") if (mono and len(y) == 0) or (not mono and y.shape[1] < 0): raise ParameterError(f"Audio is empty ndim={y.ndim:d}, shape={y.shape}") if not np.issubdtype(y.dtype, np.floating): raise ParameterError("Audio data must be floating-point") if not np.isfinite(y).all(): raise ParameterError("Audio buffer is not finite everywhere") return True def hz_to_mel(frequencies: Union[float, List[float], np.ndarray], htk: bool=False) -> np.ndarray: """Convert Hz to Mels. Args: frequencies (Union[float, List[float], np.ndarray]): Frequencies in Hz. htk (bool, optional): Use htk scaling. Defaults to False. Returns: np.ndarray: Frequency in mels. """ freq = np.asanyarray(frequencies) if htk: return 2595.0 * np.log10(1.0 + freq / 700.0) # Fill in the linear part f_min = 0.0 f_sp = 200.0 / 3 mels = (freq - f_min) / f_sp # Fill in the log-scale part min_log_hz = 1000.0 # beginning of log region (Hz) min_log_mel = (min_log_hz - f_min) / f_sp # same (Mels) logstep = np.log(6.4) / 27.0 # step size for log region if freq.ndim: # If we have array data, vectorize log_t = freq >= min_log_hz mels[log_t] = min_log_mel + \ np.log(freq[log_t] / min_log_hz) / logstep elif freq >= min_log_hz: # If we have scalar data, heck directly mels = min_log_mel + np.log(freq / min_log_hz) / logstep return mels def mel_to_hz(mels: Union[float, List[float], np.ndarray], htk: int=False) -> np.ndarray: """Convert mel bin numbers to frequencies. Args: mels (Union[float, List[float], np.ndarray]): Frequency in mels. htk (bool, optional): Use htk scaling. Defaults to False. Returns: np.ndarray: Frequencies in Hz. """ mel_array = np.asanyarray(mels) if htk: return 700.0 * (10.0**(mel_array / 2595.0) - 1.0) # Fill in the linear scale f_min = 0.0 f_sp = 200.0 / 3 freqs = f_min + f_sp * mel_array # And now the nonlinear scale min_log_hz = 1000.0 # beginning of log region (Hz) min_log_mel = (min_log_hz - f_min) / f_sp # same (Mels) logstep = np.log(6.4) / 27.0 # step size for log region if mel_array.ndim: # If we have vector data, vectorize log_t = mel_array >= min_log_mel freqs[log_t] = min_log_hz * \ np.exp(logstep * (mel_array[log_t] - min_log_mel)) elif mel_array >= min_log_mel: # If we have scalar data, check directly freqs = min_log_hz * np.exp(logstep * (mel_array - min_log_mel)) return freqs def mel_frequencies(n_mels: int=128, fmin: float=0.0, fmax: float=11025.0, htk: bool=False) -> np.ndarray: """Compute mel frequencies. Args: n_mels (int, optional): Number of mel bins. Defaults to 128. fmin (float, optional): Minimum frequency in Hz. Defaults to 0.0. fmax (float, optional): Maximum frequency in Hz. Defaults to 11025.0. htk (bool, optional): Use htk scaling. Defaults to False. Returns: np.ndarray: Vector of n_mels frequencies in Hz with shape `(n_mels,)`. """ # 'Center freqs' of mel bands - uniformly spaced between limits min_mel = hz_to_mel(fmin, htk=htk) max_mel = hz_to_mel(fmax, htk=htk) mels = np.linspace(min_mel, max_mel, n_mels) return mel_to_hz(mels, htk=htk) def fft_frequencies(sr: int, n_fft: int) -> np.ndarray: """Compute fourier frequencies. Args: sr (int): Sample rate. n_fft (int): FFT size. Returns: np.ndarray: FFT frequencies in Hz with shape `(n_fft//2 + 1,)`. """ return np.linspace(0, float(sr) / 2, int(1 + n_fft // 2), endpoint=True) def compute_fbank_matrix(sr: int, n_fft: int, n_mels: int=128, fmin: float=0.0, fmax: Optional[float]=None, htk: bool=False, norm: str="slaney", dtype: type=np.float32) -> np.ndarray: """Compute fbank matrix. Args: sr (int): Sample rate. n_fft (int): FFT size. n_mels (int, optional): Number of mel bins. Defaults to 128. fmin (float, optional): Minimum frequency in Hz. Defaults to 0.0. fmax (Optional[float], optional): Maximum frequency in Hz. Defaults to None. htk (bool, optional): Use htk scaling. Defaults to False. norm (str, optional): Type of normalization. Defaults to "slaney". dtype (type, optional): Data type. Defaults to np.float32. Returns: np.ndarray: Mel transform matrix with shape `(n_mels, n_fft//2 + 1)`. """ if norm != "slaney": raise ParameterError('norm must set to slaney') if fmax is None: fmax = float(sr) / 2 # Initialize the weights n_mels = int(n_mels) weights = np.zeros((n_mels, int(1 + n_fft // 2)), dtype=dtype) # Center freqs of each FFT bin fftfreqs = fft_frequencies(sr=sr, n_fft=n_fft) # 'Center freqs' of mel bands - uniformly spaced between limits mel_f = mel_frequencies(n_mels + 2, fmin=fmin, fmax=fmax, htk=htk) fdiff = np.diff(mel_f) ramps = np.subtract.outer(mel_f, fftfreqs) for i in range(n_mels): # lower and upper slopes for all bins lower = -ramps[i] / fdiff[i] upper = ramps[i + 2] / fdiff[i + 1] # .. then intersect them with each other and zero weights[i] = np.maximum(0, np.minimum(lower, upper)) if norm == "slaney": # Slaney-style mel is scaled to be approx constant energy per channel enorm = 2.0 / (mel_f[2:n_mels + 2] - mel_f[:n_mels]) weights *= enorm[:, np.newaxis] # Only check weights if f_mel[0] is positive if not np.all((mel_f[:-2] == 0) | (weights.max(axis=1) > 0)): # This means we have an empty channel somewhere warnings.warn("Empty filters detected in mel frequency basis. " "Some channels will produce empty responses. " "Try increasing your sampling rate (and fmax) or " "reducing n_mels.") return weights def stft(x: np.ndarray, n_fft: int=2048, hop_length: Optional[int]=None, win_length: Optional[int]=None, window: str="hann", center: bool=True, dtype: type=np.complex64, pad_mode: str="reflect") -> np.ndarray: """Short-time Fourier transform (STFT). Args: x (np.ndarray): Input waveform in one dimension. n_fft (int, optional): FFT size. Defaults to 2048. hop_length (Optional[int], optional): Number of steps to advance between adjacent windows. Defaults to None. win_length (Optional[int], optional): The size of window. Defaults to None. window (str, optional): A string of window specification. Defaults to "hann". center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. dtype (type, optional): Data type of STFT results. Defaults to np.complex64. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to "reflect". Returns: np.ndarray: The complex STFT output with shape `(n_fft//2 + 1, num_frames)`. """ _check_audio(x) # By default, use the entire frame if win_length is None: win_length = n_fft # Set the default hop, if it's not already specified if hop_length is None: hop_length = int(win_length // 4) fft_window = signal.get_window(window, win_length, fftbins=True) # Pad the window out to n_fft size fft_window = _pad_center(fft_window, n_fft) # Reshape so that the window can be broadcast fft_window = fft_window.reshape((-1, 1)) # Pad the time series so that frames are centered if center: if n_fft > x.shape[-1]: warnings.warn( f"n_fft={n_fft} is too small for input signal of length={x.shape[-1]}" ) x = np.pad(x, int(n_fft // 2), mode=pad_mode) elif n_fft > x.shape[-1]: raise ParameterError( f"n_fft={n_fft} is too small for input signal of length={x.shape[-1]}" ) # Window the time series. x_frames = _split_frames(x, frame_length=n_fft, hop_length=hop_length) # Pre-allocate the STFT matrix stft_matrix = np.empty( (int(1 + n_fft // 2), x_frames.shape[1]), dtype=dtype, order="F") fft = np.fft # use numpy fft as default # Constrain STFT block sizes to 256 KB MAX_MEM_BLOCK = 2**8 * 2**10 # how many columns can we fit within MAX_MEM_BLOCK? n_columns = MAX_MEM_BLOCK // (stft_matrix.shape[0] * stft_matrix.itemsize) n_columns = max(n_columns, 1) for bl_s in range(0, stft_matrix.shape[1], n_columns): bl_t = min(bl_s + n_columns, stft_matrix.shape[1]) stft_matrix[:, bl_s:bl_t] = fft.rfft( fft_window * x_frames[:, bl_s:bl_t], axis=0) return stft_matrix def power_to_db(spect: np.ndarray, ref: float=1.0, amin: float=1e-10, top_db: Optional[float]=80.0) -> np.ndarray: """Convert a power spectrogram (amplitude squared) to decibel (dB) units. The function computes the scaling `10 * log10(x / ref)` in a numerically stable way. Args: spect (np.ndarray): STFT power spectrogram of an input waveform. ref (float, optional): The reference value. If smaller than 1.0, the db level of the signal will be pulled up accordingly. Otherwise, the db level is pushed down. Defaults to 1.0. amin (float, optional): Minimum threshold. Defaults to 1e-10. top_db (Optional[float], optional): Threshold the output at `top_db` below the peak. Defaults to 80.0. Returns: np.ndarray: Power spectrogram in db scale. """ spect = np.asarray(spect) if amin <= 0: raise ParameterError("amin must be strictly positive") if np.issubdtype(spect.dtype, np.complexfloating): warnings.warn( "power_to_db was called on complex input so phase " "information will be discarded. To suppress this warning, " "call power_to_db(np.abs(D)**2) instead.") magnitude = np.abs(spect) else: magnitude = spect if callable(ref): # User supplied a function to calculate reference power ref_value = ref(magnitude) else: ref_value = np.abs(ref) log_spec = 10.0 * np.log10(np.maximum(amin, magnitude)) log_spec -= 10.0 * np.log10(np.maximum(amin, ref_value)) if top_db is not None: if top_db < 0: raise ParameterError("top_db must be non-negative") log_spec = np.maximum(log_spec, log_spec.max() - top_db) return log_spec def mfcc(x: np.ndarray, sr: int=16000, spect: Optional[np.ndarray]=None, n_mfcc: int=20, dct_type: int=2, norm: str="ortho", lifter: int=0, **kwargs) -> np.ndarray: """Mel-frequency cepstral coefficients (MFCCs) Args: x (np.ndarray): Input waveform in one dimension. sr (int, optional): Sample rate. Defaults to 16000. spect (Optional[np.ndarray], optional): Input log-power Mel spectrogram. Defaults to None. n_mfcc (int, optional): Number of cepstra in MFCC. Defaults to 20. dct_type (int, optional): Discrete cosine transform (DCT) type. Defaults to 2. norm (str, optional): Type of normalization. Defaults to "ortho". lifter (int, optional): Cepstral filtering. Defaults to 0. Returns: np.ndarray: Mel frequency cepstral coefficients array with shape `(n_mfcc, num_frames)`. """ if spect is None: spect = melspectrogram(x, sr=sr, **kwargs) M = scipy.fftpack.dct(spect, axis=0, type=dct_type, norm=norm)[:n_mfcc] if lifter > 0: factor = np.sin(np.pi * np.arange(1, 1 + n_mfcc, dtype=M.dtype) / lifter) return M * factor[:, np.newaxis] elif lifter == 0: return M else: raise ParameterError( f"MFCC lifter={lifter} must be a non-negative number") def melspectrogram(x: np.ndarray, sr: int=16000, window_size: int=512, hop_length: int=320, n_mels: int=64, fmin: float=50.0, fmax: Optional[float]=None, window: str='hann', center: bool=True, pad_mode: str='reflect', power: float=2.0, to_db: bool=True, ref: float=1.0, amin: float=1e-10, top_db: Optional[float]=None) -> np.ndarray: """Compute mel-spectrogram. Args: x (np.ndarray): Input waveform in one dimension. sr (int, optional): Sample rate. Defaults to 16000. window_size (int, optional): Size of FFT and window length. Defaults to 512. hop_length (int, optional): Number of steps to advance between adjacent windows. Defaults to 320. n_mels (int, optional): Number of mel bins. Defaults to 64. fmin (float, optional): Minimum frequency in Hz. Defaults to 50.0. fmax (Optional[float], optional): Maximum frequency in Hz. Defaults to None. window (str, optional): A string of window specification. Defaults to "hann". center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to "reflect". power (float, optional): Exponent for the magnitude melspectrogram. Defaults to 2.0. to_db (bool, optional): Enable db scale. Defaults to True. ref (float, optional): The reference value. If smaller than 1.0, the db level of the signal will be pulled up accordingly. Otherwise, the db level is pushed down. Defaults to 1.0. amin (float, optional): Minimum threshold. Defaults to 1e-10. top_db (Optional[float], optional): Threshold the output at `top_db` below the peak. Defaults to None. Returns: np.ndarray: The mel-spectrogram in power scale or db scale with shape `(n_mels, num_frames)`. """ _check_audio(x, mono=True) if len(x) <= 0: raise ParameterError('The input waveform is empty') if fmax is None: fmax = sr // 2 if fmin < 0 or fmin >= fmax: raise ParameterError('fmin and fmax must satisfy 0 np.ndarray: """Compute spectrogram. Args: x (np.ndarray): Input waveform in one dimension. sr (int, optional): Sample rate. Defaults to 16000. window_size (int, optional): Size of FFT and window length. Defaults to 512. hop_length (int, optional): Number of steps to advance between adjacent windows. Defaults to 320. window (str, optional): A string of window specification. Defaults to "hann". center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to "reflect". power (float, optional): Exponent for the magnitude melspectrogram. Defaults to 2.0. Returns: np.ndarray: The STFT spectrogram in power scale `(n_fft//2 + 1, num_frames)`. """ s = stft( x, n_fft=window_size, hop_length=hop_length, win_length=window_size, window=window, center=center, pad_mode=pad_mode) return np.abs(s)**power def mu_encode(x: np.ndarray, mu: int=255, quantized: bool=True) -> np.ndarray: """Mu-law encoding. Encode waveform based on mu-law companding. When quantized is True, the result will be converted to integer in range `[0,mu-1]`. Otherwise, the resulting waveform is in range `[-1,1]`. Args: x (np.ndarray): The input waveform to encode. mu (int, optional): The endoceding parameter. Defaults to 255. quantized (bool, optional): If `True`, quantize the encoded values into `1 + mu` distinct integer values. Defaults to True. Returns: np.ndarray: The mu-law encoded waveform. """ mu = 255 y = np.sign(x) * np.log1p(mu * np.abs(x)) / np.log1p(mu) if quantized: y = np.floor((y + 1) / 2 * mu + 0.5) # convert to [0 , mu-1] return y def mu_decode(y: np.ndarray, mu: int=255, quantized: bool=True) -> np.ndarray: """Mu-law decoding. Compute the mu-law decoding given an input code. It assumes that the input `y` is in range `[0,mu-1]` when quantize is True and `[-1,1]` otherwise. Args: y (np.ndarray): The encoded waveform. mu (int, optional): The endoceding parameter. Defaults to 255. quantized (bool, optional): If `True`, the input is assumed to be quantized to `1 + mu` distinct integer values. Defaults to True. Returns: np.ndarray: The mu-law decoded waveform. """ if mu < 1: raise ParameterError('mu is typically set as 2**k-1, k=1, 2, 3,...') mu = mu - 1 if quantized: # undo the quantization y = y * 2 / mu - 1 x = np.sign(y) / mu * ((1 + mu)**np.abs(y) - 1) return x def _randint(high: int) -> int: """Generate one random integer in range [0 high) This is a helper function for random data augmentation """ return int(np.random.randint(0, high=high)) def depth_augment(y: np.ndarray, choices: List=['int8', 'int16'], probs: List[float]=[0.5, 0.5]) -> np.ndarray: """ Audio depth augmentation. Do audio depth augmentation to simulate the distortion brought by quantization. Args: y (np.ndarray): Input waveform array in 1D or 2D. choices (List, optional): A list of data type to depth conversion. Defaults to ['int8', 'int16']. probs (List[float], optional): Probabilities to depth conversion. Defaults to [0.5, 0.5]. Returns: np.ndarray: The augmented waveform. """ assert len(probs) == len( choices ), 'number of choices {} must be equal to size of probs {}'.format( len(choices), len(probs)) depth = np.random.choice(choices, p=probs) src_depth = y.dtype y1 = depth_convert(y, depth) y2 = depth_convert(y1, src_depth) return y2 def adaptive_spect_augment(spect: np.ndarray, tempo_axis: int=0, level: float=0.1) -> np.ndarray: """Do adaptive spectrogram augmentation. The level of the augmentation is govern by the parameter level, ranging from 0 to 1, with 0 represents no augmentation. Args: spect (np.ndarray): Input spectrogram. tempo_axis (int, optional): Indicate the tempo axis. Defaults to 0. level (float, optional): The level factor of masking. Defaults to 0.1. Returns: np.ndarray: The augmented spectrogram. """ assert spect.ndim == 2., 'only supports 2d tensor or numpy array' if tempo_axis == 0: nt, nf = spect.shape else: nf, nt = spect.shape time_mask_width = int(nt * level * 0.5) freq_mask_width = int(nf * level * 0.5) num_time_mask = int(10 * level) num_freq_mask = int(10 * level) if tempo_axis == 0: for _ in range(num_time_mask): start = _randint(nt - time_mask_width) spect[start:start + time_mask_width, :] = 0 for _ in range(num_freq_mask): start = _randint(nf - freq_mask_width) spect[:, start:start + freq_mask_width] = 0 else: for _ in range(num_time_mask): start = _randint(nt - time_mask_width) spect[:, start:start + time_mask_width] = 0 for _ in range(num_freq_mask): start = _randint(nf - freq_mask_width) spect[start:start + freq_mask_width, :] = 0 return spect def spect_augment(spect: np.ndarray, tempo_axis: int=0, max_time_mask: int=3, max_freq_mask: int=3, max_time_mask_width: int=30, max_freq_mask_width: int=20) -> np.ndarray: """Do spectrogram augmentation in both time and freq axis. Args: spect (np.ndarray): Input spectrogram. tempo_axis (int, optional): Indicate the tempo axis. Defaults to 0. max_time_mask (int, optional): Maximum number of time masking. Defaults to 3. max_freq_mask (int, optional): Maximum number of frequency masking. Defaults to 3. max_time_mask_width (int, optional): Maximum width of time masking. Defaults to 30. max_freq_mask_width (int, optional): Maximum width of frequency masking. Defaults to 20. Returns: np.ndarray: The augmented spectrogram. """ assert spect.ndim == 2., 'only supports 2d tensor or numpy array' if tempo_axis == 0: nt, nf = spect.shape else: nf, nt = spect.shape num_time_mask = _randint(max_time_mask) num_freq_mask = _randint(max_freq_mask) time_mask_width = _randint(max_time_mask_width) freq_mask_width = _randint(max_freq_mask_width) if tempo_axis == 0: for _ in range(num_time_mask): start = _randint(nt - time_mask_width) spect[start:start + time_mask_width, :] = 0 for _ in range(num_freq_mask): start = _randint(nf - freq_mask_width) spect[:, start:start + freq_mask_width] = 0 else: for _ in range(num_time_mask): start = _randint(nt - time_mask_width) spect[:, start:start + time_mask_width] = 0 for _ in range(num_freq_mask): start = _randint(nf - freq_mask_width) spect[start:start + freq_mask_width, :] = 0 return spect def random_crop1d(y: np.ndarray, crop_len: int) -> np.ndarray: """ Random cropping on a input waveform. Args: y (np.ndarray): Input waveform array in 1D. crop_len (int): Length of waveform to crop. Returns: np.ndarray: The cropped waveform. """ if y.ndim != 1: 'only accept 1d tensor or numpy array' n = len(y) idx = _randint(n - crop_len) return y[idx:idx + crop_len] def random_crop2d(s: np.ndarray, crop_len: int, tempo_axis: int=0) -> np.ndarray: """ Random cropping on a spectrogram. Args: s (np.ndarray): Input spectrogram in 2D. crop_len (int): Length of spectrogram to crop. tempo_axis (int, optional): Indicate the tempo axis. Defaults to 0. Returns: np.ndarray: The cropped spectrogram. """ if tempo_axis >= s.ndim: raise ParameterError('axis out of range') n = s.shape[tempo_axis] idx = _randint(high=n - crop_len) sli = [slice(None) for i in range(s.ndim)] sli[tempo_axis] = slice(idx, idx + crop_len) out = s[tuple(sli)] return out ================================================ FILE: audio/paddleaudio/datasets/__init__.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from .esc50 import ESC50 from .gtzan import GTZAN from .hey_snips import HeySnips from .rirs_noises import OpenRIRNoise from .tess import TESS from .urban_sound import UrbanSound8K from .voxceleb import VoxCeleb ================================================ FILE: audio/paddleaudio/datasets/dataset.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from typing import List import numpy as np import paddle from ..backends.soundfile_backend import soundfile_load as load_audio from ..compliance.kaldi import fbank as kaldi_fbank from ..compliance.kaldi import mfcc as kaldi_mfcc from ..compliance.librosa import melspectrogram from ..compliance.librosa import mfcc feat_funcs = { 'raw': None, 'melspectrogram': melspectrogram, 'mfcc': mfcc, 'kaldi_fbank': kaldi_fbank, 'kaldi_mfcc': kaldi_mfcc, } class AudioClassificationDataset(paddle.io.Dataset): """ Base class of audio classification dataset. """ def __init__(self, files: List[str], labels: List[int], feat_type: str='raw', sample_rate: int=None, **kwargs): """ Args: files (:obj:`List[str]`): A list of absolute path of audio files. labels (:obj:`List[int]`): Labels of audio files. feat_type (:obj:`str`, `optional`, defaults to `raw`): It identifies the feature type that user wants to extract of an audio file. """ super(AudioClassificationDataset, self).__init__() if feat_type not in feat_funcs.keys(): raise RuntimeError( f"Unknown feat_type: {feat_type}, it must be one in {list(feat_funcs.keys())}" ) self.files = files self.labels = labels self.feat_type = feat_type self.sample_rate = sample_rate self.feat_config = kwargs # Pass keyword arguments to customize feature config def _get_data(self, input_file: str): raise NotImplementedError def _convert_to_record(self, idx): file, label = self.files[idx], self.labels[idx] if self.sample_rate is None: waveform, sample_rate = load_audio(file) else: waveform, sample_rate = load_audio(file, sr=self.sample_rate) feat_func = feat_funcs[self.feat_type] record = {} if self.feat_type in ['kaldi_fbank', 'kaldi_mfcc']: waveform = paddle.to_tensor(waveform).unsqueeze(0) # (C, T) record['feat'] = feat_func( waveform=waveform, sr=self.sample_rate, **self.feat_config) else: record['feat'] = feat_func( waveform, sample_rate, **self.feat_config) if feat_func else waveform record['label'] = label return record def __getitem__(self, idx): record = self._convert_to_record(idx) if self.feat_type in ['kaldi_fbank', 'kaldi_mfcc']: return self.keys[idx], record['feat'], record['label'] else: return np.array(record['feat']).transpose(), np.array( record['label'], dtype=np.int64) def __len__(self): return len(self.files) ================================================ FILE: audio/paddleaudio/datasets/esc50.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import os from typing import List from typing import Tuple from ..utils.download import download_and_decompress from ..utils.env import DATA_HOME from .dataset import AudioClassificationDataset __all__ = ['ESC50'] class ESC50(AudioClassificationDataset): """ The ESC-50 dataset is a labeled collection of 2000 environmental audio recordings suitable for benchmarking methods of environmental sound classification. The dataset consists of 5-second-long recordings organized into 50 semantical classes (with 40 examples per class) Reference: ESC: Dataset for Environmental Sound Classification http://dx.doi.org/10.1145/2733373.2806390 """ archives = [ { 'url': 'https://paddleaudio.bj.bcebos.com/datasets/ESC-50-master.zip', 'md5': '7771e4b9d86d0945acce719c7a59305a', }, ] label_list = [ # Animals 'Dog', 'Rooster', 'Pig', 'Cow', 'Frog', 'Cat', 'Hen', 'Insects (flying)', 'Sheep', 'Crow', # Natural soundscapes & water sounds 'Rain', 'Sea waves', 'Crackling fire', 'Crickets', 'Chirping birds', 'Water drops', 'Wind', 'Pouring water', 'Toilet flush', 'Thunderstorm', # Human, non-speech sounds 'Crying baby', 'Sneezing', 'Clapping', 'Breathing', 'Coughing', 'Footsteps', 'Laughing', 'Brushing teeth', 'Snoring', 'Drinking, sipping', # Interior/domestic sounds 'Door knock', 'Mouse click', 'Keyboard typing', 'Door, wood creaks', 'Can opening', 'Washing machine', 'Vacuum cleaner', 'Clock alarm', 'Clock tick', 'Glass breaking', # Exterior/urban noises 'Helicopter', 'Chainsaw', 'Siren', 'Car horn', 'Engine', 'Train', 'Church bells', 'Airplane', 'Fireworks', 'Hand saw', ] meta = os.path.join('ESC-50-master', 'meta', 'esc50.csv') meta_info = collections.namedtuple( 'META_INFO', ('filename', 'fold', 'target', 'category', 'esc10', 'src_file', 'take')) audio_path = os.path.join('ESC-50-master', 'audio') def __init__(self, mode: str='train', split: int=1, feat_type: str='raw', **kwargs): """ Args: mode (:obj:`str`, `optional`, defaults to `train`): It identifies the dataset mode (train or dev). split (:obj:`int`, `optional`, defaults to 1): It specify the fold of dev dataset. feat_type (:obj:`str`, `optional`, defaults to `raw`): It identifies the feature type that user wants to extract of an audio file. """ files, labels = self._get_data(mode, split) super(ESC50, self).__init__( files=files, labels=labels, feat_type=feat_type, **kwargs) def _get_meta_info(self) -> List[collections.namedtuple]: ret = [] with open(os.path.join(DATA_HOME, self.meta), 'r') as rf: for line in rf.readlines()[1:]: ret.append(self.meta_info(*line.strip().split(','))) return ret def _get_data(self, mode: str, split: int) -> Tuple[List[str], List[int]]: if not os.path.isdir(os.path.join(DATA_HOME, self.audio_path)) or \ not os.path.isfile(os.path.join(DATA_HOME, self.meta)): download_and_decompress(self.archives, DATA_HOME) meta_info = self._get_meta_info() files = [] labels = [] for sample in meta_info: filename, fold, target, _, _, _, _ = sample if mode == 'train' and int(fold) != split: files.append(os.path.join(DATA_HOME, self.audio_path, filename)) labels.append(int(target)) if mode != 'train' and int(fold) == split: files.append(os.path.join(DATA_HOME, self.audio_path, filename)) labels.append(int(target)) return files, labels ================================================ FILE: audio/paddleaudio/datasets/gtzan.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import os import random from typing import List from typing import Tuple from ..utils.download import download_and_decompress from ..utils.env import DATA_HOME from .dataset import AudioClassificationDataset __all__ = ['GTZAN'] class GTZAN(AudioClassificationDataset): """ The GTZAN dataset consists of 1000 audio tracks each 30 seconds long. It contains 10 genres, each represented by 100 tracks. The dataset is the most-used public dataset for evaluation in machine listening research for music genre recognition (MGR). Reference: Musical genre classification of audio signals https://ieeexplore.ieee.org/document/1021072/ """ archives = [ { 'url': 'http://opihi.cs.uvic.ca/sound/genres.tar.gz', 'md5': '5b3d6dddb579ab49814ab86dba69e7c7', }, ] label_list = [ 'blues', 'classical', 'country', 'disco', 'hiphop', 'jazz', 'metal', 'pop', 'reggae', 'rock' ] meta = os.path.join('genres', 'input.mf') meta_info = collections.namedtuple('META_INFO', ('file_path', 'label')) audio_path = 'genres' def __init__(self, mode='train', seed=0, n_folds=5, split=1, feat_type='raw', **kwargs): """ Args: mode (:obj:`str`, `optional`, defaults to `train`): It identifies the dataset mode (train or dev). seed (:obj:`int`, `optional`, defaults to 0): Set the random seed to shuffle samples. n_folds (:obj:`int`, `optional`, defaults to 5): Split the dataset into n folds. 1 fold for dev dataset and n-1 for train dataset. split (:obj:`int`, `optional`, defaults to 1): It specify the fold of dev dataset. feat_type (:obj:`str`, `optional`, defaults to `raw`): It identifies the feature type that user wants to extract of an audio file. """ assert split <= n_folds, f'The selected split should not be larger than n_fold, but got {split} > {n_folds}' files, labels = self._get_data(mode, seed, n_folds, split) super(GTZAN, self).__init__( files=files, labels=labels, feat_type=feat_type, **kwargs) def _get_meta_info(self) -> List[collections.namedtuple]: ret = [] with open(os.path.join(DATA_HOME, self.meta), 'r') as rf: for line in rf.readlines(): ret.append(self.meta_info(*line.strip().split('\t'))) return ret def _get_data(self, mode, seed, n_folds, split) -> Tuple[List[str], List[int]]: if not os.path.isdir(os.path.join(DATA_HOME, self.audio_path)) or \ not os.path.isfile(os.path.join(DATA_HOME, self.meta)): download_and_decompress(self.archives, DATA_HOME) meta_info = self._get_meta_info() random.seed(seed) # shuffle samples to split data random.shuffle( meta_info ) # make sure using the same seed to create train and dev dataset files = [] labels = [] n_samples_per_fold = len(meta_info) // n_folds for idx, sample in enumerate(meta_info): file_path, label = sample filename = os.path.basename(file_path) target = self.label_list.index(label) fold = idx // n_samples_per_fold + 1 if mode == 'train' and int(fold) != split: files.append( os.path.join(DATA_HOME, self.audio_path, label, filename)) labels.append(target) if mode != 'train' and int(fold) == split: files.append( os.path.join(DATA_HOME, self.audio_path, label, filename)) labels.append(target) return files, labels ================================================ FILE: audio/paddleaudio/datasets/hey_snips.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import json import os from typing import List from typing import Tuple from .dataset import AudioClassificationDataset __all__ = ['HeySnips'] class HeySnips(AudioClassificationDataset): meta_info = collections.namedtuple('META_INFO', ('key', 'label', 'duration', 'wav')) def __init__(self, data_dir: os.PathLike, mode: str='train', feat_type: str='kaldi_fbank', sample_rate: int=16000, **kwargs): self.data_dir = data_dir files, labels = self._get_data(mode) super(HeySnips, self).__init__( files=files, labels=labels, feat_type=feat_type, sample_rate=sample_rate, **kwargs) def _get_meta_info(self, mode) -> List[collections.namedtuple]: ret = [] with open(os.path.join(self.data_dir, '{}.json'.format(mode)), 'r') as f: data = json.load(f) for item in data: sample = collections.OrderedDict() if item['duration'] > 0: sample['key'] = item['id'] sample['label'] = 0 if item['is_hotword'] == 1 else -1 sample['duration'] = item['duration'] sample['wav'] = os.path.join(self.data_dir, item['audio_file_path']) ret.append(self.meta_info(*sample.values())) return ret def _get_data(self, mode: str) -> Tuple[List[str], List[int]]: meta_info = self._get_meta_info(mode) files = [] labels = [] self.keys = [] self.durations = [] for sample in meta_info: key, target, duration, wav = sample files.append(wav) labels.append(int(target)) self.keys.append(key) self.durations.append(float(duration)) return files, labels ================================================ FILE: audio/paddleaudio/datasets/rirs_noises.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import csv import os import random from typing import List from paddle.io import Dataset from tqdm import tqdm from ..backends.soundfile_backend import soundfile_load as load_audio from ..backends.soundfile_backend import soundfile_save as save_wav from ..utils import DATA_HOME from ..utils.download import download_and_decompress from .dataset import feat_funcs __all__ = ['OpenRIRNoise'] class OpenRIRNoise(Dataset): archives = [ { 'url': 'http://www.openslr.org/resources/28/rirs_noises.zip', 'md5': 'e6f48e257286e05de56413b4779d8ffb', }, ] sample_rate = 16000 meta_info = collections.namedtuple('META_INFO', ('id', 'duration', 'wav')) base_path = os.path.join(DATA_HOME, 'open_rir_noise') wav_path = os.path.join(base_path, 'RIRS_NOISES') csv_path = os.path.join(base_path, 'csv') subsets = ['rir', 'noise'] def __init__(self, subset: str='rir', feat_type: str='raw', target_dir=None, random_chunk: bool=True, chunk_duration: float=3.0, seed: int=0, **kwargs): assert subset in self.subsets, \ 'Dataset subset must be one in {}, but got {}'.format(self.subsets, subset) self.subset = subset self.feat_type = feat_type self.feat_config = kwargs self.random_chunk = random_chunk self.chunk_duration = chunk_duration OpenRIRNoise.csv_path = os.path.join( target_dir, "open_rir_noise", "csv") if target_dir else self.csv_path self._data = self._get_data() super(OpenRIRNoise, self).__init__() # Set up a seed to reproduce training or predicting result. # random.seed(seed) def _get_data(self): # Download audio files. print(f"rirs noises base path: {self.base_path}") if not os.path.isdir(self.base_path): download_and_decompress( self.archives, self.base_path, decompress=True) else: print( f"{self.base_path} already exists, we will not download and decompress again" ) # Data preparation. print(f"prepare the csv to {self.csv_path}") if not os.path.isdir(self.csv_path): os.makedirs(self.csv_path) self.prepare_data() data = [] with open(os.path.join(self.csv_path, f'{self.subset}.csv'), 'r') as rf: for line in rf.readlines()[1:]: audio_id, duration, wav = line.strip().split(',') data.append(self.meta_info(audio_id, float(duration), wav)) random.shuffle(data) return data def _convert_to_record(self, idx: int): sample = self._data[idx] record = {} # To show all fields in a namedtuple: `type(sample)._fields` for field in type(sample)._fields: record[field] = getattr(sample, field) waveform, sr = load_audio(record['wav']) assert self.feat_type in feat_funcs.keys(), \ f"Unknown feat_type: {self.feat_type}, it must be one in {list(feat_funcs.keys())}" feat_func = feat_funcs[self.feat_type] feat = feat_func( waveform, sr=sr, **self.feat_config) if feat_func else waveform record.update({'feat': feat}) return record @staticmethod def _get_chunks(seg_dur, audio_id, audio_duration): num_chunks = int(audio_duration / seg_dur) # all in milliseconds chunk_lst = [ audio_id + "_" + str(i * seg_dur) + "_" + str(i * seg_dur + seg_dur) for i in range(num_chunks) ] return chunk_lst def _get_audio_info(self, wav_file: str, split_chunks: bool) -> List[List[str]]: waveform, sr = load_audio(wav_file) audio_id = wav_file.split("/open_rir_noise/")[-1].split(".")[0] audio_duration = waveform.shape[0] / sr ret = [] if split_chunks and audio_duration > self.chunk_duration: # Split into pieces of self.chunk_duration seconds. uniq_chunks_list = self._get_chunks(self.chunk_duration, audio_id, audio_duration) for idx, chunk in enumerate(uniq_chunks_list): s, e = chunk.split("_")[-2:] # Timestamps of start and end start_sample = int(float(s) * sr) end_sample = int(float(e) * sr) new_wav_file = os.path.join(self.base_path, audio_id + f'_chunk_{idx+1:02}.wav') save_wav(waveform[start_sample:end_sample], sr, new_wav_file) # id, duration, new_wav ret.append([chunk, self.chunk_duration, new_wav_file]) else: # Keep whole audio. ret.append([audio_id, audio_duration, wav_file]) return ret def generate_csv(self, wav_files: List[str], output_file: str, split_chunks: bool=True): print(f'Generating csv: {output_file}') header = ["id", "duration", "wav"] infos = list( tqdm( map(self._get_audio_info, wav_files, [split_chunks] * len( wav_files)), total=len(wav_files))) csv_lines = [] for info in infos: csv_lines.extend(info) with open(output_file, mode="w") as csv_f: csv_writer = csv.writer( csv_f, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL) csv_writer.writerow(header) for line in csv_lines: csv_writer.writerow(line) def prepare_data(self): rir_list = os.path.join(self.wav_path, "real_rirs_isotropic_noises", "rir_list") rir_files = [] with open(rir_list, 'r') as f: for line in f.readlines(): rir_file = line.strip().split(' ')[-1] rir_files.append(os.path.join(self.base_path, rir_file)) noise_list = os.path.join(self.wav_path, "pointsource_noises", "noise_list") noise_files = [] with open(noise_list, 'r') as f: for line in f.readlines(): noise_file = line.strip().split(' ')[-1] noise_files.append(os.path.join(self.base_path, noise_file)) self.generate_csv(rir_files, os.path.join(self.csv_path, 'rir.csv')) self.generate_csv(noise_files, os.path.join(self.csv_path, 'noise.csv')) def __getitem__(self, idx): return self._convert_to_record(idx) def __len__(self): return len(self._data) ================================================ FILE: audio/paddleaudio/datasets/tess.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import os import random from typing import List from typing import Tuple from ..utils.download import download_and_decompress from ..utils.env import DATA_HOME from .dataset import AudioClassificationDataset __all__ = ['TESS'] class TESS(AudioClassificationDataset): """ TESS is a set of 200 target words were spoken in the carrier phrase "Say the word _____' by two actresses (aged 26 and 64 years) and recordings were made of the set portraying each of seven emotions(anger, disgust, fear, happiness, pleasant surprise, sadness, and neutral). There are 2800 stimuli in total. Reference: Toronto emotional speech set (TESS) https://doi.org/10.5683/SP2/E8H2MF """ archives = [ { 'url': 'https://bj.bcebos.com/paddleaudio/datasets/TESS_Toronto_emotional_speech_set.zip', 'md5': '1465311b24d1de704c4c63e4ccc470c7', }, ] label_list = [ 'angry', 'disgust', 'fear', 'happy', 'neutral', 'ps', # pleasant surprise 'sad', ] meta_info = collections.namedtuple('META_INFO', ('speaker', 'word', 'emotion')) audio_path = 'TESS_Toronto_emotional_speech_set' def __init__(self, mode='train', seed=0, n_folds=5, split=1, feat_type='raw', **kwargs): """ Args: mode (:obj:`str`, `optional`, defaults to `train`): It identifies the dataset mode (train or dev). seed (:obj:`int`, `optional`, defaults to 0): Set the random seed to shuffle samples. n_folds (:obj:`int`, `optional`, defaults to 5): Split the dataset into n folds. 1 fold for dev dataset and n-1 for train dataset. split (:obj:`int`, `optional`, defaults to 1): It specify the fold of dev dataset. feat_type (:obj:`str`, `optional`, defaults to `raw`): It identifies the feature type that user wants to extract of an audio file. """ assert split <= n_folds, f'The selected split should not be larger than n_fold, but got {split} > {n_folds}' files, labels = self._get_data(mode, seed, n_folds, split) super(TESS, self).__init__( files=files, labels=labels, feat_type=feat_type, **kwargs) def _get_meta_info(self, files) -> List[collections.namedtuple]: ret = [] for file in files: basename_without_extend = os.path.basename(file)[:-4] ret.append(self.meta_info(*basename_without_extend.split('_'))) return ret def _get_data(self, mode, seed, n_folds, split) -> Tuple[List[str], List[int]]: if not os.path.isdir(os.path.join(DATA_HOME, self.audio_path)): download_and_decompress(self.archives, DATA_HOME) wav_files = [] for root, _, files in os.walk(os.path.join(DATA_HOME, self.audio_path)): for file in files: if file.endswith('.wav'): wav_files.append(os.path.join(root, file)) random.seed(seed) # shuffle samples to split data random.shuffle( wav_files ) # make sure using the same seed to create train and dev dataset meta_info = self._get_meta_info(wav_files) files = [] labels = [] n_samples_per_fold = len(meta_info) // n_folds for idx, sample in enumerate(meta_info): _, _, emotion = sample target = self.label_list.index(emotion) fold = idx // n_samples_per_fold + 1 if mode == 'train' and int(fold) != split: files.append(wav_files[idx]) labels.append(target) if mode != 'train' and int(fold) == split: files.append(wav_files[idx]) labels.append(target) return files, labels ================================================ FILE: audio/paddleaudio/datasets/urban_sound.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import os from typing import List from typing import Tuple from ..utils.download import download_and_decompress from ..utils.env import DATA_HOME from .dataset import AudioClassificationDataset __all__ = ['UrbanSound8K'] class UrbanSound8K(AudioClassificationDataset): """ UrbanSound8K dataset contains 8732 labeled sound excerpts (<=4s) of urban sounds from 10 classes: air_conditioner, car_horn, children_playing, dog_bark, drilling, enginge_idling, gun_shot, jackhammer, siren, and street_music. The classes are drawn from the urban sound taxonomy. Reference: A Dataset and Taxonomy for Urban Sound Research https://dl.acm.org/doi/10.1145/2647868.2655045 """ archives = [ { 'url': 'https://zenodo.org/record/1203745/files/UrbanSound8K.tar.gz', 'md5': '9aa69802bbf37fb986f71ec1483a196e', }, ] label_list = [ "air_conditioner", "car_horn", "children_playing", "dog_bark", "drilling", "engine_idling", "gun_shot", "jackhammer", "siren", "street_music" ] meta = os.path.join('UrbanSound8K', 'metadata', 'UrbanSound8K.csv') meta_info = collections.namedtuple( 'META_INFO', ('filename', 'fsid', 'start', 'end', 'salience', 'fold', 'class_id', 'label')) audio_path = os.path.join('UrbanSound8K', 'audio') def __init__(self, mode: str='train', split: int=1, feat_type: str='raw', **kwargs): files, labels = self._get_data(mode, split) super(UrbanSound8K, self).__init__( files=files, labels=labels, feat_type=feat_type, **kwargs) """ Args: mode (:obj:`str`, `optional`, defaults to `train`): It identifies the dataset mode (train or dev). split (:obj:`int`, `optional`, defaults to 1): It specify the fold of dev dataset. feat_type (:obj:`str`, `optional`, defaults to `raw`): It identifies the feature type that user wants to extract of an audio file. """ def _get_meta_info(self): ret = [] with open(os.path.join(DATA_HOME, self.meta), 'r') as rf: for line in rf.readlines()[1:]: ret.append(self.meta_info(*line.strip().split(','))) return ret def _get_data(self, mode: str, split: int) -> Tuple[List[str], List[int]]: if not os.path.isdir(os.path.join(DATA_HOME, self.audio_path)) or \ not os.path.isfile(os.path.join(DATA_HOME, self.meta)): download_and_decompress(self.archives, DATA_HOME) meta_info = self._get_meta_info() files = [] labels = [] for sample in meta_info: filename, _, _, _, _, fold, target, _ = sample if mode == 'train' and int(fold) != split: files.append( os.path.join(DATA_HOME, self.audio_path, f'fold{fold}', filename)) labels.append(int(target)) if mode != 'train' and int(fold) == split: files.append( os.path.join(DATA_HOME, self.audio_path, f'fold{fold}', filename)) labels.append(int(target)) return files, labels ================================================ FILE: audio/paddleaudio/datasets/voxceleb.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import collections import csv import glob import os import random from multiprocessing import cpu_count from typing import List from paddle.io import Dataset from pathos.multiprocessing import Pool from tqdm import tqdm from ..backends.soundfile_backend import soundfile_load as load_audio from ..utils import DATA_HOME from ..utils import decompress from ..utils.download import download_and_decompress from .dataset import feat_funcs __all__ = ['VoxCeleb'] class VoxCeleb(Dataset): source_url = 'https://thor.robots.ox.ac.uk/~vgg/data/voxceleb/vox1a/' archives_audio_dev = [ { 'url': source_url + 'vox1_dev_wav_partaa', 'md5': 'e395d020928bc15670b570a21695ed96', }, { 'url': source_url + 'vox1_dev_wav_partab', 'md5': 'bbfaaccefab65d82b21903e81a8a8020', }, { 'url': source_url + 'vox1_dev_wav_partac', 'md5': '017d579a2a96a077f40042ec33e51512', }, { 'url': source_url + 'vox1_dev_wav_partad', 'md5': '7bb1e9f70fddc7a678fa998ea8b3ba19', }, ] archives_audio_test = [ { 'url': source_url + 'vox1_test_wav.zip', 'md5': '185fdc63c3c739954633d50379a3d102', }, ] archives_meta = [ { 'url': 'https://www.robots.ox.ac.uk/~vgg/data/voxceleb/meta/veri_test2.txt', 'md5': 'b73110731c9223c1461fe49cb48dddfc', }, ] num_speakers = 1211 # 1211 vox1, 5994 vox2, 7205 vox1+2, test speakers: 41 sample_rate = 16000 meta_info = collections.namedtuple( 'META_INFO', ('id', 'duration', 'wav', 'start', 'stop', 'spk_id')) base_path = os.path.join(DATA_HOME, 'vox1') wav_path = os.path.join(base_path, 'wav') meta_path = os.path.join(base_path, 'meta') veri_test_file = os.path.join(meta_path, 'veri_test2.txt') csv_path = os.path.join(base_path, 'csv') subsets = ['train', 'dev', 'enroll', 'test'] def __init__( self, subset: str='train', feat_type: str='raw', random_chunk: bool=True, chunk_duration: float=3.0, # seconds split_ratio: float=0.9, # train split ratio seed: int=0, target_dir: str=None, vox2_base_path=None, **kwargs): """VoxCeleb data prepare and get the specific dataset audio info Args: subset (str, optional): dataset name, such as train, dev, enroll or test. Defaults to 'train'. feat_type (str, optional): feat type, such raw, melspectrogram(fbank) or mfcc . Defaults to 'raw'. random_chunk (bool, optional): random select a duration from audio. Defaults to True. chunk_duration (float, optional): chunk duration if random_chunk flag is set. Defaults to 3.0. target_dir (str, optional): data dir, audio info will be stored in this directory. Defaults to None. vox2_base_path (_type_, optional): vox2 directory. vox2 data must be converted from m4a to wav. Defaults to None. """ assert subset in self.subsets, \ 'Dataset subset must be one in {}, but got {}'.format(self.subsets, subset) self.subset = subset self.spk_id2label = {} self.feat_type = feat_type self.feat_config = kwargs self.random_chunk = random_chunk self.chunk_duration = chunk_duration self.split_ratio = split_ratio self.target_dir = target_dir if target_dir else VoxCeleb.base_path self.vox2_base_path = vox2_base_path # if we set the target dir, we will change the vox data info data from base path to target dir VoxCeleb.csv_path = os.path.join( target_dir, "voxceleb", 'csv') if target_dir else VoxCeleb.csv_path VoxCeleb.meta_path = os.path.join( target_dir, "voxceleb", 'meta') if target_dir else VoxCeleb.meta_path VoxCeleb.veri_test_file = os.path.join(VoxCeleb.meta_path, 'veri_test2.txt') # self._data = self._get_data()[:1000] # KP: Small dataset test. self._data = self._get_data() super(VoxCeleb, self).__init__() # Set up a seed to reproduce training or predicting result. # random.seed(seed) def _get_data(self): # Download audio files. # We need the users to decompress all vox1/dev/wav and vox1/test/wav/ to vox1/wav/ dir # so, we check the vox1/wav dir status print(f"wav base path: {self.wav_path}") if not os.path.isdir(self.wav_path): print("start to download the voxceleb1 dataset") download_and_decompress( # multi-zip parts concatenate to vox1_dev_wav.zip self.archives_audio_dev, self.base_path, decompress=False) download_and_decompress( # download the vox1_test_wav.zip and unzip self.archives_audio_test, self.base_path, decompress=True) # Download all parts and concatenate the files into one zip file. dev_zipfile = os.path.join(self.base_path, 'vox1_dev_wav.zip') print(f'Concatenating all parts to: {dev_zipfile}') os.system( f'cat {os.path.join(self.base_path, "vox1_dev_wav_parta*")} > {dev_zipfile}' ) # Extract all audio files of dev and test set. decompress(dev_zipfile, self.base_path) # Download meta files. if not os.path.isdir(self.meta_path): print("prepare the meta data") download_and_decompress( self.archives_meta, self.meta_path, decompress=False) # Data preparation. if not os.path.isdir(self.csv_path): os.makedirs(self.csv_path) self.prepare_data() data = [] print( f"read the {self.subset} from {os.path.join(self.csv_path, f'{self.subset}.csv')}" ) with open(os.path.join(self.csv_path, f'{self.subset}.csv'), 'r') as rf: for line in rf.readlines()[1:]: audio_id, duration, wav, start, stop, spk_id = line.strip( ).split(',') data.append( self.meta_info(audio_id, float(duration), wav, int(start), int(stop), spk_id)) with open(os.path.join(self.meta_path, 'spk_id2label.txt'), 'r') as f: for line in f.readlines(): spk_id, label = line.strip().split(' ') self.spk_id2label[spk_id] = int(label) return data def _convert_to_record(self, idx: int): sample = self._data[idx] record = {} # To show all fields in a namedtuple: `type(sample)._fields` for field in type(sample)._fields: record[field] = getattr(sample, field) waveform, sr = load_audio(record['wav']) # random select a chunk audio samples from the audio if self.random_chunk: num_wav_samples = waveform.shape[0] num_chunk_samples = int(self.chunk_duration * sr) start = random.randint(0, num_wav_samples - num_chunk_samples - 1) stop = start + num_chunk_samples else: start = record['start'] stop = record['stop'] waveform = waveform[start:stop] assert self.feat_type in feat_funcs.keys(), \ f"Unknown feat_type: {self.feat_type}, it must be one in {list(feat_funcs.keys())}" feat_func = feat_funcs[self.feat_type] feat = feat_func( waveform, sr=sr, **self.feat_config) if feat_func else waveform record.update({'feat': feat}) if self.subset in ['train', 'dev']: # Labels are available in train and dev. record.update({'label': self.spk_id2label[record['spk_id']]}) return record @staticmethod def _get_chunks(seg_dur, audio_id, audio_duration): num_chunks = int(audio_duration / seg_dur) # all in milliseconds chunk_lst = [ audio_id + "_" + str(i * seg_dur) + "_" + str(i * seg_dur + seg_dur) for i in range(num_chunks) ] return chunk_lst def _get_audio_info(self, wav_file: str, split_chunks: bool) -> List[List[str]]: waveform, sr = load_audio(wav_file) spk_id, sess_id, utt_id = wav_file.split("/")[-3:] audio_id = '-'.join([spk_id, sess_id, utt_id.split(".")[0]]) audio_duration = waveform.shape[0] / sr ret = [] if split_chunks: # Split into pieces of self.chunk_duration seconds. uniq_chunks_list = self._get_chunks(self.chunk_duration, audio_id, audio_duration) for chunk in uniq_chunks_list: s, e = chunk.split("_")[-2:] # Timestamps of start and end start_sample = int(float(s) * sr) end_sample = int(float(e) * sr) # id, duration, wav, start, stop, spk_id ret.append([ chunk, audio_duration, wav_file, start_sample, end_sample, spk_id ]) else: # Keep whole audio. ret.append([ audio_id, audio_duration, wav_file, 0, waveform.shape[0], spk_id ]) return ret def generate_csv(self, wav_files: List[str], output_file: str, split_chunks: bool=True): print(f'Generating csv: {output_file}') header = ["id", "duration", "wav", "start", "stop", "spk_id"] # Note: this may occurs c++ exception, but the program will execute fine # so we can ignore the exception with Pool(cpu_count()) as p: infos = list( tqdm( p.imap(lambda x: self._get_audio_info(x, split_chunks), wav_files), total=len(wav_files))) csv_lines = [] for info in infos: csv_lines.extend(info) with open(output_file, mode="w") as csv_f: csv_writer = csv.writer( csv_f, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL) csv_writer.writerow(header) for line in csv_lines: csv_writer.writerow(line) def prepare_data(self): # Audio of speakers in veri_test_file should not be included in training set. print("start to prepare the data csv file") enroll_files = set() test_files = set() # get the enroll and test audio file path with open(self.veri_test_file, 'r') as f: for line in f.readlines(): _, enrol_file, test_file = line.strip().split(' ') enroll_files.add(os.path.join(self.wav_path, enrol_file)) test_files.add(os.path.join(self.wav_path, test_file)) enroll_files = sorted(enroll_files) test_files = sorted(test_files) # get the enroll and test speakers test_spks = set() for file in (enroll_files + test_files): spk = file.split('/wav/')[1].split('/')[0] test_spks.add(spk) # get all the train and dev audios file path audio_files = [] speakers = set() print("Getting file list...") for path in [self.wav_path, self.vox2_base_path]: # if vox2 directory is not set and vox2 is not a directory # we will not process this directory if not path or not os.path.exists(path): print(f"{path} is an invalid path, please check again, " "and we will ignore the vox2 base path") continue for file in glob.glob( os.path.join(path, "**", "*.wav"), recursive=True): spk = file.split('/wav/')[1].split('/')[0] if spk in test_spks: continue speakers.add(spk) audio_files.append(file) print( f"start to generate the {os.path.join(self.meta_path, 'spk_id2label.txt')}" ) # encode the train and dev speakers label to spk_id2label.txt with open(os.path.join(self.meta_path, 'spk_id2label.txt'), 'w') as f: for label, spk_id in enumerate( sorted(speakers)): # 1211 vox1, 5994 vox2, 7205 vox1+2 f.write(f'{spk_id} {label}\n') audio_files = sorted(audio_files) random.shuffle(audio_files) split_idx = int(self.split_ratio * len(audio_files)) # split_ratio to train train_files, dev_files = audio_files[:split_idx], audio_files[ split_idx:] self.generate_csv(train_files, os.path.join(self.csv_path, 'train.csv')) self.generate_csv(dev_files, os.path.join(self.csv_path, 'dev.csv')) self.generate_csv( enroll_files, os.path.join(self.csv_path, 'enroll.csv'), split_chunks=False) self.generate_csv( test_files, os.path.join(self.csv_path, 'test.csv'), split_chunks=False) def __getitem__(self, idx): return self._convert_to_record(idx) def __len__(self): return len(self._data) ================================================ FILE: audio/paddleaudio/features/__init__.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from .layers import LogMelSpectrogram from .layers import MelSpectrogram from .layers import MFCC from .layers import Spectrogram ================================================ FILE: audio/paddleaudio/features/layers.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from functools import partial from typing import Optional from typing import Union import paddle import paddle.nn as nn from paddle import Tensor from ..functional import compute_fbank_matrix from ..functional import create_dct from ..functional import power_to_db from ..functional.window import get_window __all__ = [ 'Spectrogram', 'MelSpectrogram', 'LogMelSpectrogram', 'MFCC', ] class Spectrogram(nn.Layer): """Compute spectrogram of given signals, typically audio waveforms. The spectrogram is defined as the complex norm of the short-time Fourier transformation. Args: n_fft (int, optional): The number of frequency components of the discrete Fourier transform. Defaults to 512. hop_length (Optional[int], optional): The hop length of the short time FFT. If `None`, it is set to `win_length//4`. Defaults to None. win_length (Optional[int], optional): The window length of the short time FFT. If `None`, it is set to same as `n_fft`. Defaults to None. window (str, optional): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'. Defaults to 'hann'. power (float, optional): Exponent for the magnitude spectrogram. Defaults to 2.0. center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to 'reflect'. dtype (str, optional): Data type of input and window. Defaults to 'float32'. """ def __init__(self, n_fft: int=512, hop_length: Optional[int]=None, win_length: Optional[int]=None, window: str='hann', power: float=2.0, center: bool=True, pad_mode: str='reflect', dtype: str='float32') -> None: super(Spectrogram, self).__init__() assert power > 0, 'Power of spectrogram must be > 0.' self.power = power if win_length is None: win_length = n_fft self.fft_window = get_window( window, win_length, fftbins=True, dtype=dtype) self._stft = partial( paddle.signal.stft, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=self.fft_window, center=center, pad_mode=pad_mode) self.register_buffer('fft_window', self.fft_window) def forward(self, x: Tensor) -> Tensor: """ Args: x (Tensor): Tensor of waveforms with shape `(N, T)` Returns: Tensor: Spectrograms with shape `(N, n_fft//2 + 1, num_frames)`. """ stft = self._stft(x) spectrogram = paddle.pow(paddle.abs(stft), self.power) return spectrogram class MelSpectrogram(nn.Layer): """Compute the melspectrogram of given signals, typically audio waveforms. It is computed by multiplying spectrogram with Mel filter bank matrix. Args: sr (int, optional): Sample rate. Defaults to 22050. n_fft (int, optional): The number of frequency components of the discrete Fourier transform. Defaults to 512. hop_length (Optional[int], optional): The hop length of the short time FFT. If `None`, it is set to `win_length//4`. Defaults to None. win_length (Optional[int], optional): The window length of the short time FFT. If `None`, it is set to same as `n_fft`. Defaults to None. window (str, optional): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'. Defaults to 'hann'. power (float, optional): Exponent for the magnitude spectrogram. Defaults to 2.0. center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to 'reflect'. n_mels (int, optional): Number of mel bins. Defaults to 64. f_min (float, optional): Minimum frequency in Hz. Defaults to 50.0. f_max (Optional[float], optional): Maximum frequency in Hz. Defaults to None. htk (bool, optional): Use HTK formula in computing fbank matrix. Defaults to False. norm (Union[str, float], optional): Type of normalization in computing fbank matrix. Slaney-style is used by default. You can specify norm=1.0/2.0 to use customized p-norm normalization. Defaults to 'slaney'. dtype (str, optional): Data type of input and window. Defaults to 'float32'. """ def __init__(self, sr: int=22050, n_fft: int=512, hop_length: Optional[int]=None, win_length: Optional[int]=None, window: str='hann', power: float=2.0, center: bool=True, pad_mode: str='reflect', n_mels: int=64, f_min: float=50.0, f_max: Optional[float]=None, htk: bool=False, norm: Union[str, float]='slaney', dtype: str='float32') -> None: super(MelSpectrogram, self).__init__() self._spectrogram = Spectrogram( n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, power=power, center=center, pad_mode=pad_mode, dtype=dtype) self.n_mels = n_mels self.f_min = f_min self.f_max = f_max self.htk = htk self.norm = norm if f_max is None: f_max = sr // 2 self.fbank_matrix = compute_fbank_matrix( sr=sr, n_fft=n_fft, n_mels=n_mels, f_min=f_min, f_max=f_max, htk=htk, norm=norm, dtype=dtype) # float64 for better numerical results self.register_buffer('fbank_matrix', self.fbank_matrix) def forward(self, x: Tensor) -> Tensor: """ Args: x (Tensor): Tensor of waveforms with shape `(N, T)` Returns: Tensor: Mel spectrograms with shape `(N, n_mels, num_frames)`. """ spect_feature = self._spectrogram(x) mel_feature = paddle.matmul(self.fbank_matrix, spect_feature) return mel_feature class LogMelSpectrogram(nn.Layer): """Compute log-mel-spectrogram feature of given signals, typically audio waveforms. Args: sr (int, optional): Sample rate. Defaults to 22050. n_fft (int, optional): The number of frequency components of the discrete Fourier transform. Defaults to 512. hop_length (Optional[int], optional): The hop length of the short time FFT. If `None`, it is set to `win_length//4`. Defaults to None. win_length (Optional[int], optional): The window length of the short time FFT. If `None`, it is set to same as `n_fft`. Defaults to None. window (str, optional): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'. Defaults to 'hann'. power (float, optional): Exponent for the magnitude spectrogram. Defaults to 2.0. center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to 'reflect'. n_mels (int, optional): Number of mel bins. Defaults to 64. f_min (float, optional): Minimum frequency in Hz. Defaults to 50.0. f_max (Optional[float], optional): Maximum frequency in Hz. Defaults to None. htk (bool, optional): Use HTK formula in computing fbank matrix. Defaults to False. norm (Union[str, float], optional): Type of normalization in computing fbank matrix. Slaney-style is used by default. You can specify norm=1.0/2.0 to use customized p-norm normalization. Defaults to 'slaney'. ref_value (float, optional): The reference value. If smaller than 1.0, the db level of the signal will be pulled up accordingly. Otherwise, the db level is pushed down. Defaults to 1.0. amin (float, optional): The minimum value of input magnitude. Defaults to 1e-10. top_db (Optional[float], optional): The maximum db value of spectrogram. Defaults to None. dtype (str, optional): Data type of input and window. Defaults to 'float32'. """ def __init__(self, sr: int=22050, n_fft: int=512, hop_length: Optional[int]=None, win_length: Optional[int]=None, window: str='hann', power: float=2.0, center: bool=True, pad_mode: str='reflect', n_mels: int=64, f_min: float=50.0, f_max: Optional[float]=None, htk: bool=False, norm: Union[str, float]='slaney', ref_value: float=1.0, amin: float=1e-10, top_db: Optional[float]=None, dtype: str='float32') -> None: super(LogMelSpectrogram, self).__init__() self._melspectrogram = MelSpectrogram( sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, power=power, center=center, pad_mode=pad_mode, n_mels=n_mels, f_min=f_min, f_max=f_max, htk=htk, norm=norm, dtype=dtype) self.ref_value = ref_value self.amin = amin self.top_db = top_db def forward(self, x: Tensor) -> Tensor: """ Args: x (Tensor): Tensor of waveforms with shape `(N, T)` Returns: Tensor: Log mel spectrograms with shape `(N, n_mels, num_frames)`. """ mel_feature = self._melspectrogram(x) log_mel_feature = power_to_db( mel_feature, ref_value=self.ref_value, amin=self.amin, top_db=self.top_db) return log_mel_feature class MFCC(nn.Layer): """Compute mel frequency cepstral coefficients(MFCCs) feature of given waveforms. Args: sr (int, optional): Sample rate. Defaults to 22050. n_mfcc (int, optional): [description]. Defaults to 40. n_fft (int, optional): The number of frequency components of the discrete Fourier transform. Defaults to 512. hop_length (Optional[int], optional): The hop length of the short time FFT. If `None`, it is set to `win_length//4`. Defaults to None. win_length (Optional[int], optional): The window length of the short time FFT. If `None`, it is set to same as `n_fft`. Defaults to None. window (str, optional): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'kaiser', 'gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'. Defaults to 'hann'. power (float, optional): Exponent for the magnitude spectrogram. Defaults to 2.0. center (bool, optional): Whether to pad `x` to make that the :math:`t \times hop\\_length` at the center of `t`-th frame. Defaults to True. pad_mode (str, optional): Choose padding pattern when `center` is `True`. Defaults to 'reflect'. n_mels (int, optional): Number of mel bins. Defaults to 64. f_min (float, optional): Minimum frequency in Hz. Defaults to 50.0. f_max (Optional[float], optional): Maximum frequency in Hz. Defaults to None. htk (bool, optional): Use HTK formula in computing fbank matrix. Defaults to False. norm (Union[str, float], optional): Type of normalization in computing fbank matrix. Slaney-style is used by default. You can specify norm=1.0/2.0 to use customized p-norm normalization. Defaults to 'slaney'. ref_value (float, optional): The reference value. If smaller than 1.0, the db level of the signal will be pulled up accordingly. Otherwise, the db level is pushed down. Defaults to 1.0. amin (float, optional): The minimum value of input magnitude. Defaults to 1e-10. top_db (Optional[float], optional): The maximum db value of spectrogram. Defaults to None. dtype (str, optional): Data type of input and window. Defaults to 'float32'. """ def __init__(self, sr: int=22050, n_mfcc: int=40, n_fft: int=512, hop_length: Optional[int]=None, win_length: Optional[int]=None, window: str='hann', power: float=2.0, center: bool=True, pad_mode: str='reflect', n_mels: int=64, f_min: float=50.0, f_max: Optional[float]=None, htk: bool=False, norm: Union[str, float]='slaney', ref_value: float=1.0, amin: float=1e-10, top_db: Optional[float]=None, dtype: str=paddle.float32) -> None: super(MFCC, self).__init__() assert n_mfcc <= n_mels, 'n_mfcc cannot be larger than n_mels: %d vs %d' % ( n_mfcc, n_mels) self._log_melspectrogram = LogMelSpectrogram( sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, power=power, center=center, pad_mode=pad_mode, n_mels=n_mels, f_min=f_min, f_max=f_max, htk=htk, norm=norm, ref_value=ref_value, amin=amin, top_db=top_db, dtype=dtype) self.dct_matrix = create_dct(n_mfcc=n_mfcc, n_mels=n_mels, dtype=dtype) self.register_buffer('dct_matrix', self.dct_matrix) def forward(self, x: Tensor) -> Tensor: """ Args: x (Tensor): Tensor of waveforms with shape `(N, T)` Returns: Tensor: Mel frequency cepstral coefficients with shape `(N, n_mfcc, num_frames)`. """ log_mel_feature = self._log_melspectrogram(x) mfcc = paddle.matmul( log_mel_feature.transpose((0, 2, 1)), self.dct_matrix).transpose( (0, 2, 1)) # (B, n_mels, L) return mfcc ================================================ FILE: audio/paddleaudio/functional/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from .functional import compute_fbank_matrix from .functional import create_dct from .functional import fft_frequencies from .functional import hz_to_mel from .functional import mel_frequencies from .functional import mel_to_hz from .functional import power_to_db ================================================ FILE: audio/paddleaudio/functional/functional.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. # Modified from librosa(https://github.com/librosa/librosa) import math from typing import Optional from typing import Union import paddle from paddle import Tensor __all__ = [ 'hz_to_mel', 'mel_to_hz', 'mel_frequencies', 'fft_frequencies', 'compute_fbank_matrix', 'power_to_db', 'create_dct', ] def hz_to_mel(freq: Union[Tensor, float], htk: bool=False) -> Union[Tensor, float]: """Convert Hz to Mels. Args: freq (Union[Tensor, float]): The input tensor with arbitrary shape. htk (bool, optional): Use htk scaling. Defaults to False. Returns: Union[Tensor, float]: Frequency in mels. """ if htk: if isinstance(freq, Tensor): return 2595.0 * paddle.log10(1.0 + freq / 700.0) else: return 2595.0 * math.log10(1.0 + freq / 700.0) # Fill in the linear part f_min = 0.0 f_sp = 200.0 / 3 mels = (freq - f_min) / f_sp # Fill in the log-scale part min_log_hz = 1000.0 # beginning of log region (Hz) min_log_mel = (min_log_hz - f_min) / f_sp # same (Mels) logstep = math.log(6.4) / 27.0 # step size for log region if isinstance(freq, Tensor): target = min_log_mel + paddle.log( freq / min_log_hz + 1e-10) / logstep # prevent nan with 1e-10 mask = (freq > min_log_hz).astype(freq.dtype) mels = target * mask + mels * ( 1 - mask) # will replace by masked_fill OP in future else: if freq >= min_log_hz: mels = min_log_mel + math.log(freq / min_log_hz + 1e-10) / logstep return mels def mel_to_hz(mel: Union[float, Tensor], htk: bool=False) -> Union[float, Tensor]: """Convert mel bin numbers to frequencies. Args: mel (Union[float, Tensor]): The mel frequency represented as a tensor with arbitrary shape. htk (bool, optional): Use htk scaling. Defaults to False. Returns: Union[float, Tensor]: Frequencies in Hz. """ if htk: return 700.0 * (10.0**(mel / 2595.0) - 1.0) f_min = 0.0 f_sp = 200.0 / 3 freqs = f_min + f_sp * mel # And now the nonlinear scale min_log_hz = 1000.0 # beginning of log region (Hz) min_log_mel = (min_log_hz - f_min) / f_sp # same (Mels) logstep = math.log(6.4) / 27.0 # step size for log region if isinstance(mel, Tensor): target = min_log_hz * paddle.exp(logstep * (mel - min_log_mel)) mask = (mel > min_log_mel).astype(mel.dtype) freqs = target * mask + freqs * ( 1 - mask) # will replace by masked_fill OP in future else: if mel >= min_log_mel: freqs = min_log_hz * math.exp(logstep * (mel - min_log_mel)) return freqs def mel_frequencies(n_mels: int=64, f_min: float=0.0, f_max: float=11025.0, htk: bool=False, dtype: str='float32') -> Tensor: """Compute mel frequencies. Args: n_mels (int, optional): Number of mel bins. Defaults to 64. f_min (float, optional): Minimum frequency in Hz. Defaults to 0.0. fmax (float, optional): Maximum frequency in Hz. Defaults to 11025.0. htk (bool, optional): Use htk scaling. Defaults to False. dtype (str, optional): The data type of the return frequencies. Defaults to 'float32'. Returns: Tensor: Tensor of n_mels frequencies in Hz with shape `(n_mels,)`. """ # 'Center freqs' of mel bands - uniformly spaced between limits min_mel = hz_to_mel(f_min, htk=htk) max_mel = hz_to_mel(f_max, htk=htk) mels = paddle.linspace(min_mel, max_mel, n_mels, dtype=dtype) freqs = mel_to_hz(mels, htk=htk) return freqs def fft_frequencies(sr: int, n_fft: int, dtype: str='float32') -> Tensor: """Compute fourier frequencies. Args: sr (int): Sample rate. n_fft (int): Number of fft bins. dtype (str, optional): The data type of the return frequencies. Defaults to 'float32'. Returns: Tensor: FFT frequencies in Hz with shape `(n_fft//2 + 1,)`. """ return paddle.linspace(0, float(sr) / 2, int(1 + n_fft // 2), dtype=dtype) def compute_fbank_matrix(sr: int, n_fft: int, n_mels: int=64, f_min: float=0.0, f_max: Optional[float]=None, htk: bool=False, norm: Union[str, float]='slaney', dtype: str='float32') -> Tensor: """Compute fbank matrix. Args: sr (int): Sample rate. n_fft (int): Number of fft bins. n_mels (int, optional): Number of mel bins. Defaults to 64. f_min (float, optional): Minimum frequency in Hz. Defaults to 0.0. f_max (Optional[float], optional): Maximum frequency in Hz. Defaults to None. htk (bool, optional): Use htk scaling. Defaults to False. norm (Union[str, float], optional): Type of normalization. Defaults to 'slaney'. dtype (str, optional): The data type of the return matrix. Defaults to 'float32'. Returns: Tensor: Mel transform matrix with shape `(n_mels, n_fft//2 + 1)`. """ if f_max is None: f_max = float(sr) / 2 # Initialize the weights weights = paddle.zeros((n_mels, int(1 + n_fft // 2)), dtype=dtype) # Center freqs of each FFT bin fftfreqs = fft_frequencies(sr=sr, n_fft=n_fft, dtype=dtype) # 'Center freqs' of mel bands - uniformly spaced between limits mel_f = mel_frequencies( n_mels + 2, f_min=f_min, f_max=f_max, htk=htk, dtype=dtype) fdiff = mel_f[1:] - mel_f[:-1] #np.diff(mel_f) ramps = mel_f.unsqueeze(1) - fftfreqs.unsqueeze(0) #ramps = np.subtract.outer(mel_f, fftfreqs) for i in range(n_mels): # lower and upper slopes for all bins lower = -ramps[i] / fdiff[i] upper = ramps[i + 2] / fdiff[i + 1] # .. then intersect them with each other and zero weights[i] = paddle.maximum( paddle.zeros_like(lower), paddle.minimum(lower, upper)) # Slaney-style mel is scaled to be approx constant energy per channel if norm == 'slaney': enorm = 2.0 / (mel_f[2:n_mels + 2] - mel_f[:n_mels]) weights *= enorm.unsqueeze(1) elif isinstance(norm, int) or isinstance(norm, float): weights = paddle.nn.functional.normalize(weights, p=norm, axis=-1) return weights def power_to_db(spect: Tensor, ref_value: float=1.0, amin: float=1e-10, top_db: Optional[float]=None) -> Tensor: """Convert a power spectrogram (amplitude squared) to decibel (dB) units. The function computes the scaling `10 * log10(x / ref)` in a numerically stable way. Args: spect (Tensor): STFT power spectrogram. ref_value (float, optional): The reference value. If smaller than 1.0, the db level of the signal will be pulled up accordingly. Otherwise, the db level is pushed down. Defaults to 1.0. amin (float, optional): Minimum threshold. Defaults to 1e-10. top_db (Optional[float], optional): Threshold the output at `top_db` below the peak. Defaults to None. Returns: Tensor: Power spectrogram in db scale. """ if amin <= 0: raise Exception("amin must be strictly positive") if ref_value <= 0: raise Exception("ref_value must be strictly positive") ones = paddle.ones_like(spect) log_spec = 10.0 * paddle.log10(paddle.maximum(ones * amin, spect)) log_spec -= 10.0 * math.log10(max(ref_value, amin)) if top_db is not None: if top_db < 0: raise Exception("top_db must be non-negative") log_spec = paddle.maximum(log_spec, ones * (log_spec.max() - top_db)) return log_spec def create_dct(n_mfcc: int, n_mels: int, norm: Optional[str]='ortho', dtype: str='float32') -> Tensor: """Create a discrete cosine transform(DCT) matrix. Args: n_mfcc (int): Number of mel frequency cepstral coefficients. n_mels (int): Number of mel filterbanks. norm (Optional[str], optional): Normalization type. Defaults to 'ortho'. dtype (str, optional): The data type of the return matrix. Defaults to 'float32'. Returns: Tensor: The DCT matrix with shape `(n_mels, n_mfcc)`. """ n = paddle.arange(n_mels, dtype=dtype) k = paddle.arange(n_mfcc, dtype=dtype).unsqueeze(1) dct = paddle.cos(math.pi / float(n_mels) * (n + 0.5) * k) # size (n_mfcc, n_mels) if norm is None: dct *= 2.0 else: assert norm == "ortho" dct[0] *= 1.0 / math.sqrt(2.0) dct *= math.sqrt(2.0 / float(n_mels)) return dct.T ================================================ FILE: audio/paddleaudio/functional/window.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved # # 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 import math from typing import List from typing import Tuple from typing import Union import paddle from paddle import Tensor class WindowFunctionRegister(object): def __init__(self): self._functions_dict = dict() def register(self): def add_subfunction(func): name = func.__name__ self._functions_dict[name] = func return func return add_subfunction def get(self, name): return self._functions_dict[name] window_function_register = WindowFunctionRegister() @window_function_register.register() def _cat(x: List[Tensor], data_type: str) -> Tensor: l = [paddle.to_tensor(_, data_type) for _ in x] return paddle.concat(l) @window_function_register.register() def _acosh(x: Union[Tensor, float]) -> Tensor: if isinstance(x, float): return math.log(x + math.sqrt(x**2 - 1)) return paddle.log(x + paddle.sqrt(paddle.square(x) - 1)) @window_function_register.register() def _extend(M: int, sym: bool) -> bool: """Extend window by 1 sample if needed for DFT-even symmetry.""" if not sym: return M + 1, True else: return M, False @window_function_register.register() def _len_guards(M: int) -> bool: """Handle small or incorrect window lengths.""" if int(M) != M or M < 0: raise ValueError('Window length M must be a non-negative integer') return M <= 1 @window_function_register.register() def _truncate(w: Tensor, needed: bool) -> Tensor: """Truncate window by 1 sample if needed for DFT-even symmetry.""" if needed: return w[:-1] else: return w @window_function_register.register() def _general_gaussian( M: int, p, sig, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a window with a generalized Gaussian shape. This function is consistent with scipy.signal.windows.general_gaussian(). """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) n = paddle.arange(0, M, dtype=dtype) - (M - 1.0) / 2.0 w = paddle.exp(-0.5 * paddle.abs(n / sig) ** (2 * p)) return _truncate(w, needs_trunc) @window_function_register.register() def _general_cosine( M: int, a: float, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a generic weighted sum of cosine terms window. This function is consistent with scipy.signal.windows.general_cosine(). """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) fac = paddle.linspace(-math.pi, math.pi, M, dtype=dtype) w = paddle.zeros((M,), dtype=dtype) for k in range(len(a)): w += a[k] * paddle.cos(k * fac) return _truncate(w, needs_trunc) @window_function_register.register() def _general_hamming( M: int, alpha: float, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a generalized Hamming window. This function is consistent with scipy.signal.windows.general_hamming() """ return _general_cosine(M, [alpha, 1.0 - alpha], sym, dtype=dtype) @window_function_register.register() def _taylor( M: int, nbar=4, sll=30, norm=True, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a Taylor window. The Taylor window taper function approximates the Dolph-Chebyshev window's constant sidelobe level for a parameterized number of near-in sidelobes. """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) # Original text uses a negative sidelobe level parameter and then negates # it in the calculation of B. To keep consistent with other methods we # assume the sidelobe level parameter to be positive. B = 10 ** (sll / 20) A = _acosh(B) / math.pi s2 = nbar**2 / (A**2 + (nbar - 0.5) ** 2) ma = paddle.arange(1, nbar, dtype=dtype) Fm = paddle.empty((nbar - 1,), dtype=dtype) signs = paddle.empty_like(ma) signs[::2] = 1 signs[1::2] = -1 m2 = ma * ma for mi in range(len(ma)): numer = signs[mi] * paddle.prod( 1 - m2[mi] / s2 / (A**2 + (ma - 0.5) ** 2) ) if mi == 0: denom = 2 * paddle.prod(1 - m2[mi] / m2[mi + 1 :]) elif mi == len(ma) - 1: denom = 2 * paddle.prod(1 - m2[mi] / m2[:mi]) else: denom = ( 2 * paddle.prod(1 - m2[mi] / m2[:mi]) * paddle.prod(1 - m2[mi] / m2[mi + 1 :]) ) Fm[mi] = numer / denom def W(n): return 1 + 2 * paddle.matmul( Fm.unsqueeze(0), paddle.cos(2 * math.pi * ma.unsqueeze(1) * (n - M / 2.0 + 0.5) / M), ) w = W(paddle.arange(0, M, dtype=dtype)) # normalize (Note that this is not described in the original text [1]) if norm: scale = 1.0 / W((M - 1) / 2) w *= scale w = w.squeeze() return _truncate(w, needs_trunc) @window_function_register.register() def _hamming(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a Hamming window. The Hamming window is a taper formed by using a raised cosine with non-zero endpoints, optimized to minimize the nearest side lobe. """ return _general_hamming(M, 0.54, sym, dtype=dtype) @window_function_register.register() def _hann(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a Hann window. The Hann window is a taper formed by using a raised cosine or sine-squared with ends that touch zero. """ return _general_hamming(M, 0.5, sym, dtype=dtype) @window_function_register.register() def _tukey( M: int, alpha=0.5, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a Tukey window. The Tukey window is also known as a tapered cosine window. """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) if alpha <= 0: return paddle.ones((M,), dtype=dtype) elif alpha >= 1.0: return hann(M, sym=sym) M, needs_trunc = _extend(M, sym) n = paddle.arange(0, M, dtype=dtype) width = int(alpha * (M - 1) / 2.0) n1 = n[0 : width + 1] n2 = n[width + 1 : M - width - 1] n3 = n[M - width - 1 :] w1 = 0.5 * (1 + paddle.cos(math.pi * (-1 + 2.0 * n1 / alpha / (M - 1)))) w2 = paddle.ones(n2.shape, dtype=dtype) w3 = 0.5 * ( 1 + paddle.cos(math.pi * (-2.0 / alpha + 1 + 2.0 * n3 / alpha / (M - 1))) ) w = paddle.concat([w1, w2, w3]) return _truncate(w, needs_trunc) @window_function_register.register() def _gaussian( M: int, std: float, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute a Gaussian window. The Gaussian widows has a Gaussian shape defined by the standard deviation(std). """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) n = paddle.arange(0, M, dtype=dtype) - (M - 1.0) / 2.0 sig2 = 2 * std * std w = paddle.exp(-(n**2) / sig2) return _truncate(w, needs_trunc) @window_function_register.register() def _exponential( M: int, center=None, tau=1.0, sym: bool = True, dtype: str = 'float64' ) -> Tensor: """Compute an exponential (or Poisson) window.""" if sym and center is not None: raise ValueError("If sym==True, center must be None.") if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) if center is None: center = (M - 1) / 2 n = paddle.arange(0, M, dtype=dtype) w = paddle.exp(-paddle.abs(n - center) / tau) return _truncate(w, needs_trunc) @window_function_register.register() def _triang(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a triangular window.""" if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) n = paddle.arange(1, (M + 1) // 2 + 1, dtype=dtype) if M % 2 == 0: w = (2 * n - 1.0) / M w = paddle.concat([w, w[::-1]]) else: w = 2 * n / (M + 1.0) w = paddle.concat([w, w[-2::-1]]) return _truncate(w, needs_trunc) @window_function_register.register() def _bohman(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a Bohman window. The Bohman window is the autocorrelation of a cosine window. """ if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) fac = paddle.abs(paddle.linspace(-1, 1, M, dtype=dtype)[1:-1]) w = (1 - fac) * paddle.cos(math.pi * fac) + 1.0 / math.pi * paddle.sin( math.pi * fac ) w = _cat([0, w, 0], dtype) return _truncate(w, needs_trunc) @window_function_register.register() def _blackman(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a Blackman window. The Blackman window is a taper formed by using the first three terms of a summation of cosines. It was designed to have close to the minimal leakage possible. It is close to optimal, only slightly worse than a Kaiser window. """ return _general_cosine(M, [0.42, 0.50, 0.08], sym, dtype=dtype) @window_function_register.register() def _cosine(M: int, sym: bool = True, dtype: str = 'float64') -> Tensor: """Compute a window with a simple cosine shape.""" if _len_guards(M): return paddle.ones((M,), dtype=dtype) M, needs_trunc = _extend(M, sym) w = paddle.sin(math.pi / M * (paddle.arange(0, M, dtype=dtype) + 0.5)) return _truncate(w, needs_trunc) def get_window( window: Union[str, Tuple[str, float]], win_length: int, fftbins: bool = True, dtype: str = 'float64', ) -> Tensor: """Return a window of a given length and type. Args: window (Union[str, Tuple[str, float]]): The window function applied to the signal before the Fourier transform. Supported window functions: 'hamming', 'hann', 'gaussian', 'general_gaussian', 'exponential', 'triang', 'bohman', 'blackman', 'cosine', 'tukey', 'taylor'. win_length (int): Number of samples. fftbins (bool, optional): If True, create a "periodic" window. Otherwise, create a "symmetric" window, for use in filter design. Defaults to True. dtype (str, optional): The data type of the return window. Defaults to 'float64'. Returns: Tensor: The window represented as a tensor. Examples: .. code-block:: python import paddle n_fft = 512 cosine_window = paddle.audio.functional.get_window('cosine', n_fft) std = 7 gaussian_window = paddle.audio.functional.get_window(('gaussian',std), n_fft) """ sym = not fftbins args = () if isinstance(window, tuple): winstr = window[0] if len(window) > 1: args = window[1:] elif isinstance(window, str): if window in ['gaussian', 'exponential']: raise ValueError( "The '" + window + "' window needs one or " "more parameters -- pass a tuple." ) else: winstr = window else: raise ValueError( "%s as window type is not supported." % str(type(window)) ) try: winfunc = window_function_register.get('_' + winstr) except KeyError as e: raise ValueError("Unknown window type.") from e params = (win_length,) + args kwargs = {'sym': sym} return winfunc(*params, dtype=dtype, **kwargs) ================================================ FILE: audio/paddleaudio/kaldi/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from .kaldi import fbank #from .kaldi import pitch ================================================ FILE: audio/paddleaudio/kaldi/kaldi.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import paddleaudio from paddleaudio._internal import module_utils __all__ = [ 'fbank', ] @module_utils.requires_kaldi() def fbank( wav, samp_freq: int=16000, frame_shift_ms: float=10.0, frame_length_ms: float=25.0, dither: float=0.0, preemph_coeff: float=0.97, remove_dc_offset: bool=True, window_type: str='povey', round_to_power_of_two: bool=True, blackman_coeff: float=0.42, snip_edges: bool=True, max_feature_vectors: int=-1, num_bins: int=23, low_freq: float=20, high_freq: float=0, vtln_low: float=100, vtln_high: float=-500, debug_mel: bool=False, htk_mode: bool=False, use_energy: bool=False, # fbank opts energy_floor: float=0.0, raw_energy: bool=True, htk_compat: bool=False, use_log_fbank: bool=True, use_power: bool=True): frame_opts = paddleaudio._paddleaudio.FrameExtractionOptions() mel_opts = paddleaudio._paddleaudio.MelBanksOptions() fbank_opts = paddleaudio._paddleaudio.FbankOptions() frame_opts.samp_freq = samp_freq frame_opts.frame_shift_ms = frame_shift_ms frame_opts.frame_length_ms = frame_length_ms frame_opts.dither = dither frame_opts.preemph_coeff = preemph_coeff frame_opts.remove_dc_offset = remove_dc_offset frame_opts.window_type = window_type frame_opts.round_to_power_of_two = round_to_power_of_two frame_opts.blackman_coeff = blackman_coeff frame_opts.snip_edges = snip_edges frame_opts.max_feature_vectors = max_feature_vectors mel_opts.num_bins = num_bins mel_opts.low_freq = low_freq mel_opts.high_freq = high_freq mel_opts.vtln_low = vtln_low mel_opts.vtln_high = vtln_high mel_opts.debug_mel = debug_mel mel_opts.htk_mode = htk_mode fbank_opts.use_energy = use_energy fbank_opts.energy_floor = energy_floor fbank_opts.raw_energy = raw_energy fbank_opts.htk_compat = htk_compat fbank_opts.use_log_fbank = use_log_fbank fbank_opts.use_power = use_power feat = paddleaudio._paddleaudio.ComputeFbank(frame_opts, mel_opts, fbank_opts, wav) return feat #@module_utils.requires_kaldi() #def pitch(wav, #samp_freq: int=16000, #frame_shift_ms: float=10.0, #frame_length_ms: float=25.0, #preemph_coeff: float=0.0, #min_f0: int=50, #max_f0: int=400, #soft_min_f0: float=10.0, #penalty_factor: float=0.1, #lowpass_cutoff: int=1000, #resample_freq: int=4000, #delta_pitch: float=0.005, #nccf_ballast: int=7000, #lowpass_filter_width: int=1, #upsample_filter_width: int=5, #max_frames_latency: int=0, #frames_per_chunk: int=0, #simulate_first_pass_online: bool=False, #recompute_frame: int=500, #nccf_ballast_online: bool=False, #snip_edges: bool=True): #pitch_opts = paddleaudio._paddleaudio.PitchExtractionOptions() #pitch_opts.samp_freq = samp_freq #pitch_opts.frame_shift_ms = frame_shift_ms #pitch_opts.frame_length_ms = frame_length_ms #pitch_opts.preemph_coeff = preemph_coeff #pitch_opts.min_f0 = min_f0 #pitch_opts.max_f0 = max_f0 #pitch_opts.soft_min_f0 = soft_min_f0 #pitch_opts.penalty_factor = penalty_factor #pitch_opts.lowpass_cutoff = lowpass_cutoff #pitch_opts.resample_freq = resample_freq #pitch_opts.delta_pitch = delta_pitch #pitch_opts.nccf_ballast = nccf_ballast #pitch_opts.lowpass_filter_width = lowpass_filter_width #pitch_opts.upsample_filter_width = upsample_filter_width #pitch_opts.max_frames_latency = max_frames_latency #pitch_opts.frames_per_chunk = frames_per_chunk #pitch_opts.simulate_first_pass_online = simulate_first_pass_online #pitch_opts.recompute_frame = recompute_frame #pitch_opts.nccf_ballast_online = nccf_ballast_online #pitch_opts.snip_edges = snip_edges #pitch = paddleaudio._paddleaudio.ComputeKaldiPitch(pitch_opts, wav) #return pitch ================================================ FILE: audio/paddleaudio/metric/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from .eer import compute_eer from .eer import compute_minDCF ================================================ FILE: audio/paddleaudio/metric/eer.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from typing import List import numpy as np import paddle from sklearn.metrics import roc_curve def compute_eer(labels: np.ndarray, scores: np.ndarray) -> List[float]: """Compute EER and return score threshold. Args: labels (np.ndarray): the trial label, shape: [N], one-dimension, N refer to the samples num scores (np.ndarray): the trial scores, shape: [N], one-dimension, N refer to the samples num Returns: List[float]: eer and the specific threshold """ fpr, tpr, threshold = roc_curve(y_true=labels, y_score=scores) fnr = 1 - tpr eer_threshold = threshold[np.nanargmin(np.absolute((fnr - fpr)))] eer = fpr[np.nanargmin(np.absolute((fnr - fpr)))] return eer, eer_threshold def compute_minDCF(positive_scores, negative_scores, c_miss=1.0, c_fa=1.0, p_target=0.01): """ This is modified from SpeechBrain https://github.com/speechbrain/speechbrain/blob/085be635c07f16d42cd1295045bc46c407f1e15b/speechbrain/utils/metric_stats.py#L509 Computes the minDCF metric normally used to evaluate speaker verification systems. The min_DCF is the minimum of the following C_det function computed within the defined threshold range: C_det = c_miss * p_miss * p_target + c_fa * p_fa * (1 -p_target) where p_miss is the missing probability and p_fa is the probability of having a false alarm. Args: positive_scores (Paddle.Tensor): The scores from entries of the same class. negative_scores (Paddle.Tensor): The scores from entries of different classes. c_miss (float, optional): Cost assigned to a missing error (default 1.0). c_fa (float, optional): Cost assigned to a false alarm (default 1.0). p_target (float, optional): Prior probability of having a target (default 0.01). Returns: List[float]: min dcf and the specific threshold """ # Computing candidate thresholds if len(positive_scores.shape) > 1: positive_scores = positive_scores.squeeze() if len(negative_scores.shape) > 1: negative_scores = negative_scores.squeeze() thresholds = paddle.sort(paddle.concat([positive_scores, negative_scores])) thresholds = paddle.unique(thresholds) # Adding intermediate thresholds interm_thresholds = (thresholds[0:-1] + thresholds[1:]) / 2 thresholds = paddle.sort(paddle.concat([thresholds, interm_thresholds])) # Computing False Rejection Rate (miss detection) positive_scores = paddle.concat( len(thresholds) * [positive_scores.unsqueeze(0)]) pos_scores_threshold = positive_scores.transpose(perm=[1, 0]) <= thresholds p_miss = (pos_scores_threshold.sum(0) ).astype("float32") / positive_scores.shape[1] del positive_scores del pos_scores_threshold # Computing False Acceptance Rate (false alarm) negative_scores = paddle.concat( len(thresholds) * [negative_scores.unsqueeze(0)]) neg_scores_threshold = negative_scores.transpose(perm=[1, 0]) > thresholds p_fa = (neg_scores_threshold.sum(0) ).astype("float32") / negative_scores.shape[1] del negative_scores del neg_scores_threshold c_det = c_miss * p_miss * p_target + c_fa * p_fa * (1 - p_target) c_min = paddle.min(c_det, axis=0) min_index = paddle.argmin(c_det, axis=0) return float(c_min), float(thresholds[min_index]) ================================================ FILE: audio/paddleaudio/sox_effects/__init__.py ================================================ from paddleaudio._internal import module_utils as _mod_utils from .sox_effects import apply_effects_file from .sox_effects import apply_effects_tensor from .sox_effects import effect_names from .sox_effects import init_sox_effects from .sox_effects import shutdown_sox_effects if _mod_utils.is_sox_available(): import atexit init_sox_effects() atexit.register(shutdown_sox_effects) __all__ = [ "init_sox_effects", "shutdown_sox_effects", "effect_names", "apply_effects_tensor", "apply_effects_file", ] ================================================ FILE: audio/paddleaudio/sox_effects/sox_effects.py ================================================ import os from typing import List from typing import Optional from typing import Tuple import paddle import paddleaudio from paddleaudio._internal import module_utils as _mod_utils from paddleaudio.utils.sox_utils import list_effects #code is from: https://github.com/pytorch/audio/blob/main/torchaudio/sox_effects/sox_effects.py @_mod_utils.requires_sox() def init_sox_effects(): """Initialize resources required to use sox effects. Note: You do not need to call this function manually. It is called automatically. Once initialized, you do not need to call this function again across the multiple uses of sox effects though it is safe to do so as long as :func:`shutdown_sox_effects` is not called yet. Once :func:`shutdown_sox_effects` is called, you can no longer use SoX effects and initializing again will result in error. """ paddleaudio._paddleaudio.sox_effects_initialize_sox_effects() @_mod_utils.requires_sox() def shutdown_sox_effects(): """Clean up resources required to use sox effects. Note: You do not need to call this function manually. It is called automatically. It is safe to call this function multiple times. Once :py:func:`shutdown_sox_effects` is called, you can no longer use SoX effects and initializing again will result in error. """ paddleaudio._paddleaudio.sox_effects_shutdown_sox_effects() @_mod_utils.requires_sox() def effect_names() -> List[str]: """Gets list of valid sox effect names Returns: List[str]: list of available effect names. Example >>> paddleaudio.sox_effects.effect_names() ['allpass', 'band', 'bandpass', ... ] """ return list(list_effects().keys()) @_mod_utils.requires_sox() def apply_effects_tensor( tensor: paddle.Tensor, sample_rate: int, effects: List[List[str]], channels_first: bool=True, ) -> Tuple[paddle.Tensor, int]: """Apply sox effects to given Tensor .. devices:: CPU Note: This function only works on CPU Tensors. This function works in the way very similar to ``sox`` command, however there are slight differences. For example, ``sox`` command adds certain effects automatically (such as ``rate`` effect after ``speed`` and ``pitch`` and other effects), but this function does only applies the given effects. (Therefore, to actually apply ``speed`` effect, you also need to give ``rate`` effect with desired sampling rate.). Args: tensor (paddle.Tensor): Input 2D CPU Tensor. sample_rate (int): Sample rate effects (List[List[str]]): List of effects. channels_first (bool, optional): Indicates if the input Tensor's dimension is `[channels, time]` or `[time, channels]` Returns: (Tensor, int): Resulting Tensor and sample rate. The resulting Tensor has the same ``dtype`` as the input Tensor, and the same channels order. The shape of the Tensor can be different based on the effects applied. Sample rate can also be different based on the effects applied. Example - Basic usage >>> >>> # Defines the effects to apply >>> effects = [ ... ['gain', '-n'], # normalises to 0dB ... ['pitch', '5'], # 5 cent pitch shift ... ['rate', '8000'], # resample to 8000 Hz ... ] >>> >>> # Generate pseudo wave: >>> # normalized, channels first, 2ch, sampling rate 16000, 1 second >>> sample_rate = 16000 >>> waveform = 2 * paddle.rand([2, sample_rate * 1]) - 1 >>> waveform.shape paddle.Size([2, 16000]) >>> waveform tensor([[ 0.3138, 0.7620, -0.9019, ..., -0.7495, -0.4935, 0.5442], [-0.0832, 0.0061, 0.8233, ..., -0.5176, -0.9140, -0.2434]]) >>> >>> # Apply effects >>> waveform, sample_rate = apply_effects_tensor( ... wave_form, sample_rate, effects, channels_first=True) >>> >>> # Check the result >>> # The new waveform is sampling rate 8000, 1 second. >>> # normalization and channel order are preserved >>> waveform.shape paddle.Size([2, 8000]) >>> waveform tensor([[ 0.5054, -0.5518, -0.4800, ..., -0.0076, 0.0096, -0.0110], [ 0.1331, 0.0436, -0.3783, ..., -0.0035, 0.0012, 0.0008]]) >>> sample_rate 8000 """ tensor_np = tensor.numpy() ret = paddleaudio._paddleaudio.sox_effects_apply_effects_tensor( tensor_np, sample_rate, effects, channels_first) if ret is not None: return (paddle.to_tensor(ret[0]), ret[1]) raise RuntimeError("Failed to apply sox effect") @_mod_utils.requires_sox() def apply_effects_file( path: str, effects: List[List[str]], normalize: bool=True, channels_first: bool=True, format: Optional[str]=None, ) -> Tuple[paddle.Tensor, int]: """Apply sox effects to the audio file and load the resulting data as Tensor Note: This function works in the way very similar to ``sox`` command, however there are slight differences. For example, ``sox`` command adds certain effects automatically (such as ``rate`` effect after ``speed``, ``pitch`` etc), but this function only applies the given effects. Therefore, to actually apply ``speed`` effect, you also need to give ``rate`` effect with desired sampling rate, because internally, ``speed`` effects only alter sampling rate and leave samples untouched. Args: path (path-like object or file-like object): effects (List[List[str]]): List of effects. normalize (bool, optional): When ``True``, this function always return ``float32``, and sample values are normalized to ``[-1.0, 1.0]``. If input file is integer WAV, giving ``False`` will change the resulting Tensor type to integer type. This argument has no effect for formats other than integer WAV type. channels_first (bool, optional): When True, the returned Tensor has dimension `[channel, time]`. Otherwise, the returned Tensor's dimension is `[time, channel]`. format (str or None, optional): Override the format detection with the given format. Providing the argument might help when libsox can not infer the format from header or extension, Returns: (Tensor, int): Resulting Tensor and sample rate. If ``normalize=True``, the resulting Tensor is always ``float32`` type. If ``normalize=False`` and the input audio file is of integer WAV file, then the resulting Tensor has corresponding integer type. (Note 24 bit integer type is not supported) If ``channels_first=True``, the resulting Tensor has dimension `[channel, time]`, otherwise `[time, channel]`. Example - Basic usage >>> >>> # Defines the effects to apply >>> effects = [ ... ['gain', '-n'], # normalises to 0dB ... ['pitch', '5'], # 5 cent pitch shift ... ['rate', '8000'], # resample to 8000 Hz ... ] >>> >>> # Apply effects and load data with channels_first=True >>> waveform, sample_rate = apply_effects_file("data.wav", effects, channels_first=True) >>> >>> # Check the result >>> waveform.shape paddle.Size([2, 8000]) >>> waveform tensor([[ 5.1151e-03, 1.8073e-02, 2.2188e-02, ..., 1.0431e-07, -1.4761e-07, 1.8114e-07], [-2.6924e-03, 2.1860e-03, 1.0650e-02, ..., 6.4122e-07, -5.6159e-07, 4.8103e-07]]) >>> sample_rate 8000 Example - Apply random speed perturbation to dataset >>> >>> # Load data from file, apply random speed perturbation >>> class RandomPerturbationFile(paddle.utils.data.Dataset): ... \"\"\"Given flist, apply random speed perturbation ... ... Suppose all the input files are at least one second long. ... \"\"\" ... def __init__(self, flist: List[str], sample_rate: int): ... super().__init__() ... self.flist = flist ... self.sample_rate = sample_rate ... ... def __getitem__(self, index): ... speed = 0.5 + 1.5 * random.randn() ... effects = [ ... ['gain', '-n', '-10'], # apply 10 db attenuation ... ['remix', '-'], # merge all the channels ... ['speed', f'{speed:.5f}'], # duration is now 0.5 ~ 2.0 seconds. ... ['rate', f'{self.sample_rate}'], ... ['pad', '0', '1.5'], # add 1.5 seconds silence at the end ... ['trim', '0', '2'], # get the first 2 seconds ... ] ... waveform, _ = paddleaudio.sox_effects.apply_effects_file( ... self.flist[index], effects) ... return waveform ... ... def __len__(self): ... return len(self.flist) ... >>> dataset = RandomPerturbationFile(file_list, sample_rate=8000) >>> loader = paddle.utils.data.DataLoader(dataset, batch_size=32) >>> for batch in loader: >>> pass """ if hasattr(path, "read"): ret = paddleaudio._paddleaudio.apply_effects_fileobj( path, effects, normalize, channels_first, format) if ret is None: raise RuntimeError("Failed to load audio from {}".format(path)) return (paddle.to_tensor(ret[0]), ret[1]) path = os.fspath(path) ret = paddleaudio._paddleaudio.sox_effects_apply_effects_file( path, effects, normalize, channels_first, format) if ret is not None: return (paddle.to_tensor(ret[0]), ret[1]) raise RuntimeError("Failed to load audio from {}".format(path)) ================================================ FILE: audio/paddleaudio/src/CMakeLists.txt ================================================ if (MSVC) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() if(APPLE) set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") endif(APPLE) ################################################################################ # libpaddleaudio ################################################################################ set( LIBPADDLEAUDIO_SOURCES utils.cpp ) set( LIBPADDLEAUDIO_INCLUDE_DIRS ${PROJECT_SOURCE_DIR} ) set( LIBPADDLEAUDIO_LINK_LIBRARIES ) set( LIBPADDLEAUDIO_COMPILE_DEFINITIONS) #------------------------------------------------------------------------------# # START OF CUSTOMIZATION LOGICS #------------------------------------------------------------------------------# if(BUILD_SOX) list( APPEND LIBPADDLEAUDIO_LINK_LIBRARIES libsox ) list( APPEND LIBPADDLEAUDIO_SOURCES ) list( APPEND LIBPADDLEAUDIO_COMPILE_DEFINITIONS INCLUDE_SOX ) endif() if(BUILD_KALDI) list( APPEND LIBPADDLEAUDIO_LINK_LIBRARIES kaldi-native-fbank-core ) list( APPEND LIBPADDLEAUDIO_COMPILE_DEFINITIONS INCLUDE_KALDI COMPILE_WITHOUT_OPENFST ) endif() #------------------------------------------------------------------------------# # END OF CUSTOMIZATION LOGICS #------------------------------------------------------------------------------# function (define_library name source include_dirs link_libraries compile_defs) add_library(${name} SHARED ${source}) target_include_directories(${name} PRIVATE ${include_dirs}) target_link_libraries(${name} ${link_libraries}) target_compile_definitions(${name} PRIVATE ${compile_defs}) set_target_properties(${name} PROPERTIES PREFIX "") if (MSVC) set_target_properties(${name} PROPERTIES SUFFIX ".pyd") endif(MSVC) install( TARGETS ${name} LIBRARY DESTINATION lib RUNTIME DESTINATION lib # For Windows ) endfunction() define_library( libpaddleaudio "${LIBPADDLEAUDIO_SOURCES}" "${LIBPADDLEAUDIO_INCLUDE_DIRS}" "${LIBPADDLEAUDIO_LINK_LIBRARIES}" "${LIBPADDLEAUDIO_COMPILE_DEFINITIONS}" ) if (APPLE) set(AUDIO_LIBRARY libpaddleaudio CACHE INTERNAL "") else() set(AUDIO_LIBRARY -Wl,--no-as-needed libpaddleaudio -Wl,--as-needed CACHE INTERNAL "") endif() ################################################################################ # _paddleaudio.so ################################################################################ if (BUILD_PADDLEAUDIO_PYTHON_EXTENSION) if (WIN32) find_package(Python3 ${PYTHON_VERSION} EXACT COMPONENTS Development) set(ADDITIONAL_ITEMS Python3::Python) endif() function(define_extension name sources include_dirs libraries definitions) add_library(${name} SHARED ${sources}) target_compile_definitions(${name} PRIVATE "${definitions}") target_include_directories( ${name} PRIVATE ${PROJECT_SOURCE_DIR} ${Python_INCLUDE_DIR} ${pybind11_INCLUDE_DIR} ${include_dirs}) target_link_libraries( ${name} ${libraries} ${PYTHON_LIBRARY} ${ADDITIONAL_ITEMS} ) set_target_properties(${name} PROPERTIES PREFIX "") if (MSVC) set_target_properties(${name} PROPERTIES SUFFIX ".pyd") endif(MSVC) if (APPLE) # https://github.com/facebookarchive/caffe2/issues/854#issuecomment-364538485 # https://github.com/pytorch/pytorch/commit/73f6715f4725a0723d8171d3131e09ac7abf0666 set_target_properties(${name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") endif() install( TARGETS ${name} LIBRARY DESTINATION . RUNTIME DESTINATION . # For Windows ) endfunction() set( EXTENSION_SOURCES pybind/pybind.cpp ) #----------------------------------------------------------------------------# # START OF CUSTOMIZATION LOGICS #----------------------------------------------------------------------------# if(BUILD_SOX) list( APPEND EXTENSION_SOURCES pybind/sox/effects.cpp pybind/sox/effects_chain.cpp pybind/sox/io.cpp pybind/sox/types.cpp pybind/sox/utils.cpp ) endif() if(BUILD_KALDI) list( APPEND EXTENSION_SOURCES pybind/kaldi/kaldi_feature_wrapper.cc pybind/kaldi/kaldi_feature.cc ) endif() #----------------------------------------------------------------------------# # END OF CUSTOMIZATION LOGICS #----------------------------------------------------------------------------# define_extension( _paddleaudio "${EXTENSION_SOURCES}" "" libpaddleaudio "${LIBPADDLEAUDIO_COMPILE_DEFINITIONS}" ) # if(BUILD_CTC_DECODER) # set( # DECODER_EXTENSION_SOURCES # decoder/bindings/pybind.cpp # ) # define_extension( # _paddleaudio_decoder # "${DECODER_EXTENSION_SOURCES}" # "" # "libpaddleaudio_decoder" # "${LIBPADDLEAUDIO_DECODER_DEFINITIONS}" # ) # endif() # if(USE_FFMPEG) # set( # FFMPEG_EXTENSION_SOURCES # ffmpeg/pybind/typedefs.cpp # ffmpeg/pybind/pybind.cpp # ffmpeg/pybind/stream_reader.cpp # ) # define_extension( # _paddleaudio_ffmpeg # "${FFMPEG_EXTENSION_SOURCES}" # "${FFMPEG_INCLUDE_DIRS}" # "libpaddleaudio_ffmpeg" # "${LIBPADDLEAUDIO_DECODER_DEFINITIONS}" # ) # endif() endif() ================================================ FILE: audio/paddleaudio/src/optional/COPYING ================================================ Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. ================================================ FILE: audio/paddleaudio/src/optional/optional.hpp ================================================ /// // optional - An implementation of std::optional with extensions // Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama) // // Documentation available at https://tl.tartanllama.xyz/ // // To the extent possible under law, the author(s) have dedicated all // copyright and related and neighboring rights to this software to the // public domain worldwide. This software is distributed without any warranty. // // You should have received a copy of the CC0 Public Domain Dedication // along with this software. If not, see // . // https://github.com/TartanLlama/optional /// #ifndef TL_OPTIONAL_HPP #define TL_OPTIONAL_HPP #define TL_OPTIONAL_VERSION_MAJOR 1 #define TL_OPTIONAL_VERSION_MINOR 0 #define TL_OPTIONAL_VERSION_PATCH 0 #include #include #include #include #include #if (defined(_MSC_VER) && _MSC_VER == 1900) #define TL_OPTIONAL_MSVC2015 #endif #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ !defined(__clang__)) #define TL_OPTIONAL_GCC49 #endif #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ !defined(__clang__)) #define TL_OPTIONAL_GCC54 #endif #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ !defined(__clang__)) #define TL_OPTIONAL_GCC55 #endif #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ !defined(__clang__)) // GCC < 5 doesn't support overloading on const&& for member functions #define TL_OPTIONAL_NO_CONSTRR // GCC < 5 doesn't support some standard C++11 type traits #define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::has_trivial_copy_constructor::value #define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::has_trivial_copy_assign::value // This one will be different for GCC 5.7 if it's ever supported #define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible::value // GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks // std::vector // for non-copyable types #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) #ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX #define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX namespace tl { namespace detail { template struct is_trivially_copy_constructible : std::is_trivially_copy_constructible {}; #ifdef _GLIBCXX_VECTOR template struct is_trivially_copy_constructible> : std::is_trivially_copy_constructible {}; #endif } } #endif #define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ tl::detail::is_trivially_copy_constructible::value #define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::is_trivially_copy_assignable::value #define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible::value #else #define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::is_trivially_copy_constructible::value #define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::is_trivially_copy_assignable::value #define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible::value #endif #if __cplusplus > 201103L #define TL_OPTIONAL_CXX14 #endif // constexpr implies const in C++11, not C++14 #if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || \ defined(TL_OPTIONAL_GCC49)) #define TL_OPTIONAL_11_CONSTEXPR #else #define TL_OPTIONAL_11_CONSTEXPR constexpr #endif namespace tl { #ifndef TL_MONOSTATE_INPLACE_MUTEX #define TL_MONOSTATE_INPLACE_MUTEX /// Used to represent an optional with no data; essentially a bool class monostate {}; /// A tag type to tell optional to construct its value in-place struct in_place_t { explicit in_place_t() = default; }; /// A tag to tell optional to construct its value in-place static constexpr in_place_t in_place{}; #endif template class optional; namespace detail { #ifndef TL_TRAITS_MUTEX #define TL_TRAITS_MUTEX // C++14-style aliases for brevity template using remove_const_t = typename std::remove_const::type; template using remove_reference_t = typename std::remove_reference::type; template using decay_t = typename std::decay::type; template using enable_if_t = typename std::enable_if::type; template using conditional_t = typename std::conditional::type; // std::conjunction from C++17 template struct conjunction : std::true_type {}; template struct conjunction : B {}; template struct conjunction : std::conditional, B>::type {}; #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L #define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND #endif // In C++11 mode, there's an issue in libc++'s std::mem_fn // which results in a hard-error when using it in a noexcept expression // in some cases. This is a check to workaround the common failing case. #ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND template struct is_pointer_to_non_const_member_func : std::false_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_pointer_to_non_const_member_func : std::true_type {}; template struct is_const_or_const_ref : std::false_type {}; template struct is_const_or_const_ref : std::true_type {}; template struct is_const_or_const_ref : std::true_type {}; #endif // std::invoke from C++17 // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround template < typename Fn, typename... Args, #ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND typename = enable_if_t::value && is_const_or_const_ref::value)>, #endif typename = enable_if_t>::value>, int = 0> constexpr auto invoke(Fn &&f, Args &&... args) noexcept( noexcept(std::mem_fn(f)(std::forward(args)...))) -> decltype(std::mem_fn(f)(std::forward(args)...)) { return std::mem_fn(f)(std::forward(args)...); } template >::value>> constexpr auto invoke(Fn &&f, Args &&... args) noexcept( noexcept(std::forward(f)(std::forward(args)...))) -> decltype(std::forward(f)(std::forward(args)...)) { return std::forward(f)(std::forward(args)...); } // std::invoke_result from C++17 template struct invoke_result_impl; template struct invoke_result_impl< F, decltype(detail::invoke(std::declval(), std::declval()...), void()), Us...> { using type = decltype(detail::invoke(std::declval(), std::declval()...)); }; template using invoke_result = invoke_result_impl; template using invoke_result_t = typename invoke_result::type; #if defined(_MSC_VER) && _MSC_VER <= 1900 // TODO make a version which works with MSVC 2015 template struct is_swappable : std::true_type {}; template struct is_nothrow_swappable : std::true_type {}; #else // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept namespace swap_adl_tests { // if swap ADL finds this then it would call std::swap otherwise (same // signature) struct tag {}; template tag swap(T &, T &); template tag swap(T (&a)[N], T (&b)[N]); // helper functions to test if an unqualified swap is possible, and if it // becomes std::swap template std::false_type can_swap(...) noexcept(false); template (), std::declval()))> std::true_type can_swap(int) noexcept(noexcept(swap(std::declval(), std::declval()))); template std::false_type uses_std(...); template std::is_same(), std::declval())), tag> uses_std(int); template struct is_std_swap_noexcept : std::integral_constant::value && std::is_nothrow_move_assignable::value> {}; template struct is_std_swap_noexcept : is_std_swap_noexcept {}; template struct is_adl_swap_noexcept : std::integral_constant(0))> {}; } // namespace swap_adl_tests template struct is_swappable : std::integral_constant< bool, decltype(detail::swap_adl_tests::can_swap(0))::value && (!decltype(detail::swap_adl_tests::uses_std(0))::value || (std::is_move_assignable::value && std::is_move_constructible::value))> {}; template struct is_swappable : std::integral_constant< bool, decltype(detail::swap_adl_tests::can_swap(0))::value && (!decltype( detail::swap_adl_tests::uses_std(0))::value || is_swappable::value)> {}; template struct is_nothrow_swappable : std::integral_constant< bool, is_swappable::value && ((decltype(detail::swap_adl_tests::uses_std(0))::value &&detail::swap_adl_tests::is_std_swap_noexcept::value) || (!decltype(detail::swap_adl_tests::uses_std(0))::value && detail::swap_adl_tests::is_adl_swap_noexcept::value))> { }; #endif #endif // std::void_t from C++17 template struct voider { using type = void; }; template using void_t = typename voider::type; // Trait for checking if a type is a tl::optional template struct is_optional_impl : std::false_type {}; template struct is_optional_impl> : std::true_type {}; template using is_optional = is_optional_impl>; // Change void to tl::monostate template using fixup_void = conditional_t::value, monostate, U>; template > using get_map_return = optional>>; // Check if invoking F for some Us returns void template struct returns_void_impl; template struct returns_void_impl>, U...> : std::is_void> {}; template using returns_void = returns_void_impl; template using enable_if_ret_void = enable_if_t::value>; template using disable_if_ret_void = enable_if_t::value>; template using enable_forward_value = detail::enable_if_t::value && !std::is_same, in_place_t>::value && !std::is_same, detail::decay_t>::value>; template using enable_from_other = detail::enable_if_t< std::is_constructible::value && !std::is_constructible &>::value && !std::is_constructible &&>::value && !std::is_constructible &>::value && !std::is_constructible &&>::value && !std::is_convertible &, T>::value && !std::is_convertible &&, T>::value && !std::is_convertible &, T>::value && !std::is_convertible &&, T>::value>; template using enable_assign_forward = detail::enable_if_t< !std::is_same, detail::decay_t>::value && !detail::conjunction, std::is_same>>::value && std::is_constructible::value && std::is_assignable::value>; template using enable_assign_from_other = detail::enable_if_t< std::is_constructible::value && std::is_assignable::value && !std::is_constructible &>::value && !std::is_constructible &&>::value && !std::is_constructible &>::value && !std::is_constructible &&>::value && !std::is_convertible &, T>::value && !std::is_convertible &&, T>::value && !std::is_convertible &, T>::value && !std::is_convertible &&, T>::value && !std::is_assignable &>::value && !std::is_assignable &&>::value && !std::is_assignable &>::value && !std::is_assignable &&>::value>; // The storage base manages the actual storage, and correctly propagates // trivial destruction from T. This case is for when T is not trivially // destructible. template ::value> struct optional_storage_base { TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {} template TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u) : m_value(std::forward(u)...), m_has_value(true) {} ~optional_storage_base() { if (m_has_value) { m_value.~T(); m_has_value = false; } } struct dummy {}; union { dummy m_dummy; T m_value; }; bool m_has_value; }; // This case is for when T is trivially destructible. template struct optional_storage_base { TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept : m_dummy(), m_has_value(false) {} template TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u) : m_value(std::forward(u)...), m_has_value(true) {} // No destructor, so this class is trivially destructible struct dummy {}; union { dummy m_dummy; T m_value; }; bool m_has_value = false; }; // This base class provides some handy member functions which can be used in // further derived classes template struct optional_operations_base : optional_storage_base { using optional_storage_base::optional_storage_base; void hard_reset() noexcept { get().~T(); this->m_has_value = false; } template void construct(Args &&... args) noexcept { new (std::addressof(this->m_value)) T(std::forward(args)...); this->m_has_value = true; } template void assign(Opt &&rhs) { if (this->has_value()) { if (rhs.has_value()) { this->m_value = std::forward(rhs).get(); } else { this->m_value.~T(); this->m_has_value = false; } } else if (rhs.has_value()) { construct(std::forward(rhs).get()); } } bool has_value() const { return this->m_has_value; } TL_OPTIONAL_11_CONSTEXPR T &get() & { return this->m_value; } TL_OPTIONAL_11_CONSTEXPR const T &get() const & { return this->m_value; } TL_OPTIONAL_11_CONSTEXPR T &&get() && { return std::move(this->m_value); } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr const T &&get() const && { return std::move(this->m_value); } #endif }; // This class manages conditionally having a trivial copy constructor // This specialization is for when T is trivially copy constructible template struct optional_copy_base : optional_operations_base { using optional_operations_base::optional_operations_base; }; // This specialization is for when T is not trivially copy constructible template struct optional_copy_base : optional_operations_base { using optional_operations_base::optional_operations_base; optional_copy_base() = default; optional_copy_base(const optional_copy_base &rhs) : optional_operations_base() { if (rhs.has_value()) { this->construct(rhs.get()); } else { this->m_has_value = false; } } optional_copy_base(optional_copy_base &&rhs) = default; optional_copy_base &operator=(const optional_copy_base &rhs) = default; optional_copy_base &operator=(optional_copy_base &&rhs) = default; }; // This class manages conditionally having a trivial move constructor // Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it // doesn't implement an analogue to std::is_trivially_move_constructible. We // have to make do with a non-trivial move constructor even if T is trivially // move constructible #ifndef TL_OPTIONAL_GCC49 template ::value> struct optional_move_base : optional_copy_base { using optional_copy_base::optional_copy_base; }; #else template struct optional_move_base; #endif template struct optional_move_base : optional_copy_base { using optional_copy_base::optional_copy_base; optional_move_base() = default; optional_move_base(const optional_move_base &rhs) = default; optional_move_base(optional_move_base &&rhs) noexcept( std::is_nothrow_move_constructible::value) { if (rhs.has_value()) { this->construct(std::move(rhs.get())); } else { this->m_has_value = false; } } optional_move_base &operator=(const optional_move_base &rhs) = default; optional_move_base &operator=(optional_move_base &&rhs) = default; }; // This class manages conditionally having a trivial copy assignment operator template struct optional_copy_assign_base : optional_move_base { using optional_move_base::optional_move_base; }; template struct optional_copy_assign_base : optional_move_base { using optional_move_base::optional_move_base; optional_copy_assign_base() = default; optional_copy_assign_base(const optional_copy_assign_base &rhs) = default; optional_copy_assign_base(optional_copy_assign_base &&rhs) = default; optional_copy_assign_base &operator=(const optional_copy_assign_base &rhs) { this->assign(rhs); return *this; } optional_copy_assign_base &operator=(optional_copy_assign_base &&rhs) = default; }; // This class manages conditionally having a trivial move assignment operator // Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it // doesn't implement an analogue to std::is_trivially_move_assignable. We have // to make do with a non-trivial move assignment operator even if T is trivially // move assignable #ifndef TL_OPTIONAL_GCC49 template ::value &&std::is_trivially_move_constructible::value &&std::is_trivially_move_assignable::value> struct optional_move_assign_base : optional_copy_assign_base { using optional_copy_assign_base::optional_copy_assign_base; }; #else template struct optional_move_assign_base; #endif template struct optional_move_assign_base : optional_copy_assign_base { using optional_copy_assign_base::optional_copy_assign_base; optional_move_assign_base() = default; optional_move_assign_base(const optional_move_assign_base &rhs) = default; optional_move_assign_base(optional_move_assign_base &&rhs) = default; optional_move_assign_base &operator=(const optional_move_assign_base &rhs) = default; optional_move_assign_base & operator=(optional_move_assign_base &&rhs) noexcept( std::is_nothrow_move_constructible::value &&std::is_nothrow_move_assignable::value) { this->assign(std::move(rhs)); return *this; } }; // optional_delete_ctor_base will conditionally delete copy and move // constructors depending on whether T is copy/move constructible template ::value, bool EnableMove = std::is_move_constructible::value> struct optional_delete_ctor_base { optional_delete_ctor_base() = default; optional_delete_ctor_base(const optional_delete_ctor_base &) = default; optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default; optional_delete_ctor_base &operator=(const optional_delete_ctor_base &) = default; optional_delete_ctor_base &operator=( optional_delete_ctor_base &&) noexcept = default; }; template struct optional_delete_ctor_base { optional_delete_ctor_base() = default; optional_delete_ctor_base(const optional_delete_ctor_base &) = default; optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete; optional_delete_ctor_base &operator=(const optional_delete_ctor_base &) = default; optional_delete_ctor_base &operator=( optional_delete_ctor_base &&) noexcept = default; }; template struct optional_delete_ctor_base { optional_delete_ctor_base() = default; optional_delete_ctor_base(const optional_delete_ctor_base &) = delete; optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = default; optional_delete_ctor_base &operator=(const optional_delete_ctor_base &) = default; optional_delete_ctor_base &operator=( optional_delete_ctor_base &&) noexcept = default; }; template struct optional_delete_ctor_base { optional_delete_ctor_base() = default; optional_delete_ctor_base(const optional_delete_ctor_base &) = delete; optional_delete_ctor_base(optional_delete_ctor_base &&) noexcept = delete; optional_delete_ctor_base &operator=(const optional_delete_ctor_base &) = default; optional_delete_ctor_base &operator=( optional_delete_ctor_base &&) noexcept = default; }; // optional_delete_assign_base will conditionally delete copy and move // constructors depending on whether T is copy/move constructible + assignable template ::value && std::is_copy_assignable::value), bool EnableMove = (std::is_move_constructible::value && std::is_move_assignable::value)> struct optional_delete_assign_base { optional_delete_assign_base() = default; optional_delete_assign_base(const optional_delete_assign_base &) = default; optional_delete_assign_base(optional_delete_assign_base &&) noexcept = default; optional_delete_assign_base &operator=( const optional_delete_assign_base &) = default; optional_delete_assign_base &operator=( optional_delete_assign_base &&) noexcept = default; }; template struct optional_delete_assign_base { optional_delete_assign_base() = default; optional_delete_assign_base(const optional_delete_assign_base &) = default; optional_delete_assign_base(optional_delete_assign_base &&) noexcept = default; optional_delete_assign_base &operator=( const optional_delete_assign_base &) = default; optional_delete_assign_base &operator=( optional_delete_assign_base &&) noexcept = delete; }; template struct optional_delete_assign_base { optional_delete_assign_base() = default; optional_delete_assign_base(const optional_delete_assign_base &) = default; optional_delete_assign_base(optional_delete_assign_base &&) noexcept = default; optional_delete_assign_base &operator=( const optional_delete_assign_base &) = delete; optional_delete_assign_base &operator=( optional_delete_assign_base &&) noexcept = default; }; template struct optional_delete_assign_base { optional_delete_assign_base() = default; optional_delete_assign_base(const optional_delete_assign_base &) = default; optional_delete_assign_base(optional_delete_assign_base &&) noexcept = default; optional_delete_assign_base &operator=( const optional_delete_assign_base &) = delete; optional_delete_assign_base &operator=( optional_delete_assign_base &&) noexcept = delete; }; } // namespace detail /// A tag type to represent an empty optional struct nullopt_t { struct do_not_use {}; constexpr explicit nullopt_t(do_not_use, do_not_use) noexcept {} }; /// Represents an empty optional static constexpr nullopt_t nullopt{nullopt_t::do_not_use{}, nullopt_t::do_not_use{}}; class bad_optional_access : public std::exception { public: bad_optional_access() = default; const char *what() const noexcept { return "Optional has no value"; } }; /// An optional object is an object that contains the storage for another /// object and manages the lifetime of this contained object, if any. The /// contained object may be initialized after the optional object has been /// initialized, and may be destroyed before the optional object has been /// destroyed. The initialization state of the contained object is tracked by /// the optional object. template class optional : private detail::optional_move_assign_base, private detail::optional_delete_ctor_base, private detail::optional_delete_assign_base { using base = detail::optional_move_assign_base; static_assert(!std::is_same::value, "instantiation of optional with in_place_t is ill-formed"); static_assert(!std::is_same, nullopt_t>::value, "instantiation of optional with nullopt_t is ill-formed"); public: // The different versions for C++14 and 11 are needed because deduced return // types are not SFINAE-safe. This provides better support for things like // generic lambdas. C.f. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation which returns an optional on the stored /// object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : result(nullopt); } template constexpr auto and_then(F &&f) const & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr auto and_then(F &&f) const && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : result(nullopt); } #endif #else /// Carries out some operation which returns an optional on the stored /// object if there is one. template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then( F &&f) && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : result(nullopt); } template constexpr detail::invoke_result_t and_then(F &&f) const & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr detail::invoke_result_t and_then(F &&f) const && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : result(nullopt); } #endif #endif #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) & { return optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) && { return optional_map_impl(std::move(*this), std::forward(f)); } template constexpr auto map(F &&f) const & { return optional_map_impl(*this, std::forward(f)); } template constexpr auto map(F &&f) const && { return optional_map_impl(std::move(*this), std::forward(f)); } #else /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR decltype( optional_map_impl(std::declval(), std::declval())) map(F &&f) & { return optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR decltype( optional_map_impl(std::declval(), std::declval())) map(F &&f) && { return optional_map_impl(std::move(*this), std::forward(f)); } template constexpr decltype(optional_map_impl(std::declval(), std::declval())) map(F &&f) const & { return optional_map_impl(*this, std::forward(f)); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr decltype(optional_map_impl(std::declval(), std::declval())) map(F &&f) const && { return optional_map_impl(std::move(*this), std::forward(f)); } #endif #endif #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto transform(F &&f) & { return optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR auto transform(F &&f) && { return optional_map_impl(std::move(*this), std::forward(f)); } template constexpr auto transform(F &&f) const & { return optional_map_impl(*this, std::forward(f)); } template constexpr auto transform(F &&f) const && { return optional_map_impl(std::move(*this), std::forward(f)); } #else /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR decltype( optional_map_impl(std::declval(), std::declval())) transform(F &&f) & { return optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR decltype( optional_map_impl(std::declval(), std::declval())) transform(F &&f) && { return optional_map_impl(std::move(*this), std::forward(f)); } template constexpr decltype(optional_map_impl(std::declval(), std::declval())) transform(F &&f) const & { return optional_map_impl(*this, std::forward(f)); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr decltype(optional_map_impl(std::declval(), std::declval())) transform(F &&f) const && { return optional_map_impl(std::move(*this), std::forward(f)); } #endif #endif /// Calls `f` if the optional is empty template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & { if (has_value()) return *this; std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & { return has_value() ? *this : std::forward(f)(); } template * = nullptr> optional or_else(F &&f) && { if (has_value()) return std::move(*this); std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) && { return has_value() ? std::move(*this) : std::forward(f)(); } template * = nullptr> optional or_else(F &&f) const & { if (has_value()) return *this; std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const & { return has_value() ? *this : std::forward(f)(); } #ifndef TL_OPTIONAL_NO_CONSTRR template * = nullptr> optional or_else(F &&f) const && { if (has_value()) return std::move(*this); std::forward(f)(); return nullopt; } template * = nullptr> optional or_else(F &&f) const && { return has_value() ? std::move(*this) : std::forward(f)(); } #endif /// Maps the stored value with `f` if there is one, otherwise returns `u`. template U map_or(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } template U map_or(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); } template U map_or(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } #ifndef TL_OPTIONAL_NO_CONSTRR template U map_or(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); } #endif /// Maps the stored value with `f` if there is one, otherwise calls /// `u` and returns the result. template detail::invoke_result_t map_or_else(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } template detail::invoke_result_t map_or_else(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } template detail::invoke_result_t map_or_else(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } #ifndef TL_OPTIONAL_NO_CONSTRR template detail::invoke_result_t map_or_else(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } #endif /// Returns `u` if `*this` has a value, otherwise an empty optional. template constexpr optional::type> conjunction(U &&u) const { using result = optional>; return has_value() ? result{u} : result{nullopt}; } /// Returns `rhs` if `*this` is empty, otherwise the current value. TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) & { return has_value() ? *this : rhs; } constexpr optional disjunction(const optional &rhs) const & { return has_value() ? *this : rhs; } TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) && { return has_value() ? std::move(*this) : rhs; } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr optional disjunction(const optional &rhs) const && { return has_value() ? std::move(*this) : rhs; } #endif TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) & { return has_value() ? *this : std::move(rhs); } constexpr optional disjunction(optional &&rhs) const & { return has_value() ? *this : std::move(rhs); } TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) && { return has_value() ? std::move(*this) : std::move(rhs); } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr optional disjunction(optional &&rhs) const && { return has_value() ? std::move(*this) : std::move(rhs); } #endif /// Takes the value out of the optional, leaving it empty optional take() { optional ret = std::move(*this); reset(); return ret; } using value_type = T; /// Constructs an optional that does not contain a value. constexpr optional() noexcept = default; constexpr optional(nullopt_t) noexcept {} /// Copy constructor /// /// If `rhs` contains a value, the stored value is direct-initialized with /// it. Otherwise, the constructed optional is empty. TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) = default; /// Move constructor /// /// If `rhs` contains a value, the stored value is direct-initialized with /// it. Otherwise, the constructed optional is empty. TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs) = default; /// Constructs the stored value in-place using the given arguments. template constexpr explicit optional( detail::enable_if_t::value, in_place_t>, Args &&... args) : base(in_place, std::forward(args)...) {} template TL_OPTIONAL_11_CONSTEXPR explicit optional( detail::enable_if_t &, Args &&...>::value, in_place_t>, std::initializer_list il, Args &&... args) { this->construct(il, std::forward(args)...); } /// Constructs the stored value with `u`. template < class U = T, detail::enable_if_t::value> * = nullptr, detail::enable_forward_value * = nullptr> constexpr optional(U &&u) : base(in_place, std::forward(u)) {} template < class U = T, detail::enable_if_t::value> * = nullptr, detail::enable_forward_value * = nullptr> constexpr explicit optional(U &&u) : base(in_place, std::forward(u)) {} /// Converting copy constructor. template * = nullptr, detail::enable_if_t::value> * = nullptr> optional(const optional &rhs) { if (rhs.has_value()) { this->construct(*rhs); } } template * = nullptr, detail::enable_if_t::value> * = nullptr> explicit optional(const optional &rhs) { if (rhs.has_value()) { this->construct(*rhs); } } /// Converting move constructor. template < class U, detail::enable_from_other * = nullptr, detail::enable_if_t::value> * = nullptr> optional(optional &&rhs) { if (rhs.has_value()) { this->construct(std::move(*rhs)); } } template < class U, detail::enable_from_other * = nullptr, detail::enable_if_t::value> * = nullptr> explicit optional(optional &&rhs) { if (rhs.has_value()) { this->construct(std::move(*rhs)); } } /// Destroys the stored value if there is one. ~optional() = default; /// Assignment to empty. /// /// Destroys the current value if there is one. optional &operator=(nullopt_t) noexcept { if (has_value()) { this->m_value.~T(); this->m_has_value = false; } return *this; } /// Copy assignment. /// /// Copies the value from `rhs` if there is one. Otherwise resets the stored /// value in `*this`. optional &operator=(const optional &rhs) = default; /// Move assignment. /// /// Moves the value from `rhs` if there is one. Otherwise resets the stored /// value in `*this`. optional &operator=(optional &&rhs) = default; /// Assigns the stored value from `u`, destroying the old value if there was /// one. template * = nullptr> optional &operator=(U &&u) { if (has_value()) { this->m_value = std::forward(u); } else { this->construct(std::forward(u)); } return *this; } /// Converting copy assignment operator. /// /// Copies the value from `rhs` if there is one. Otherwise resets the stored /// value in `*this`. template * = nullptr> optional &operator=(const optional &rhs) { if (has_value()) { if (rhs.has_value()) { this->m_value = *rhs; } else { this->hard_reset(); } } if (rhs.has_value()) { this->construct(*rhs); } return *this; } // TODO check exception guarantee /// Converting move assignment operator. /// /// Moves the value from `rhs` if there is one. Otherwise resets the stored /// value in `*this`. template * = nullptr> optional &operator=(optional &&rhs) { if (has_value()) { if (rhs.has_value()) { this->m_value = std::move(*rhs); } else { this->hard_reset(); } } if (rhs.has_value()) { this->construct(std::move(*rhs)); } return *this; } /// Constructs the value in-place, destroying the current one if there is /// one. template T &emplace(Args &&... args) { static_assert(std::is_constructible::value, "T must be constructible with Args"); *this = nullopt; this->construct(std::forward(args)...); return value(); } template detail::enable_if_t< std::is_constructible &, Args &&...>::value, T &> emplace(std::initializer_list il, Args &&... args) { *this = nullopt; this->construct(il, std::forward(args)...); return value(); } /// Swaps this optional with the other. /// /// If neither optionals have a value, nothing happens. /// If both have a value, the values are swapped. /// If one has a value, it is moved to the other and the movee is left /// valueless. void swap(optional &rhs) noexcept( std::is_nothrow_move_constructible::value &&detail::is_nothrow_swappable::value) { using std::swap; if (has_value()) { if (rhs.has_value()) { swap(**this, *rhs); } else { new (std::addressof(rhs.m_value)) T(std::move(this->m_value)); this->m_value.T::~T(); } } else if (rhs.has_value()) { new (std::addressof(this->m_value)) T(std::move(rhs.m_value)); rhs.m_value.T::~T(); } swap(this->m_has_value, rhs.m_has_value); } /// Returns a pointer to the stored value constexpr const T *operator->() const { return std::addressof(this->m_value); } TL_OPTIONAL_11_CONSTEXPR T *operator->() { return std::addressof(this->m_value); } /// Returns the stored value TL_OPTIONAL_11_CONSTEXPR T &operator*() & { return this->m_value; } constexpr const T &operator*() const & { return this->m_value; } TL_OPTIONAL_11_CONSTEXPR T &&operator*() && { return std::move(this->m_value); } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr const T &&operator*() const && { return std::move(this->m_value); } #endif /// Returns whether or not the optional has a value constexpr bool has_value() const noexcept { return this->m_has_value; } constexpr explicit operator bool() const noexcept { return this->m_has_value; } /// Returns the contained value if there is one, otherwise throws /// bad_optional_access TL_OPTIONAL_11_CONSTEXPR T &value() & { if (has_value()) return this->m_value; throw bad_optional_access(); } TL_OPTIONAL_11_CONSTEXPR const T &value() const & { if (has_value()) return this->m_value; throw bad_optional_access(); } TL_OPTIONAL_11_CONSTEXPR T &&value() && { if (has_value()) return std::move(this->m_value); throw bad_optional_access(); } #ifndef TL_OPTIONAL_NO_CONSTRR TL_OPTIONAL_11_CONSTEXPR const T &&value() const && { if (has_value()) return std::move(this->m_value); throw bad_optional_access(); } #endif /// Returns the stored value if there is one, otherwise returns `u` template constexpr T value_or(U &&u) const & { static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } template TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && { static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } /// Destroys the stored value if one exists, making the optional empty void reset() noexcept { if (has_value()) { this->m_value.~T(); this->m_has_value = false; } } }; // namespace tl /// Compares two optional objects template inline constexpr bool operator==(const optional &lhs, const optional &rhs) { return lhs.has_value() == rhs.has_value() && (!lhs.has_value() || *lhs == *rhs); } template inline constexpr bool operator!=(const optional &lhs, const optional &rhs) { return lhs.has_value() != rhs.has_value() || (lhs.has_value() && *lhs != *rhs); } template inline constexpr bool operator<(const optional &lhs, const optional &rhs) { return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs); } template inline constexpr bool operator>(const optional &lhs, const optional &rhs) { return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs); } template inline constexpr bool operator<=(const optional &lhs, const optional &rhs) { return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs); } template inline constexpr bool operator>=(const optional &lhs, const optional &rhs) { return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs); } /// Compares an optional to a `nullopt` template inline constexpr bool operator==(const optional &lhs, nullopt_t) noexcept { return !lhs.has_value(); } template inline constexpr bool operator==(nullopt_t, const optional &rhs) noexcept { return !rhs.has_value(); } template inline constexpr bool operator!=(const optional &lhs, nullopt_t) noexcept { return lhs.has_value(); } template inline constexpr bool operator!=(nullopt_t, const optional &rhs) noexcept { return rhs.has_value(); } template inline constexpr bool operator<(const optional &, nullopt_t) noexcept { return false; } template inline constexpr bool operator<(nullopt_t, const optional &rhs) noexcept { return rhs.has_value(); } template inline constexpr bool operator<=(const optional &lhs, nullopt_t) noexcept { return !lhs.has_value(); } template inline constexpr bool operator<=(nullopt_t, const optional &) noexcept { return true; } template inline constexpr bool operator>(const optional &lhs, nullopt_t) noexcept { return lhs.has_value(); } template inline constexpr bool operator>(nullopt_t, const optional &) noexcept { return false; } template inline constexpr bool operator>=(const optional &, nullopt_t) noexcept { return true; } template inline constexpr bool operator>=(nullopt_t, const optional &rhs) noexcept { return !rhs.has_value(); } /// Compares the optional with a value. template inline constexpr bool operator==(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs == rhs : false; } template inline constexpr bool operator==(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs == *rhs : false; } template inline constexpr bool operator!=(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs != rhs : true; } template inline constexpr bool operator!=(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs != *rhs : true; } template inline constexpr bool operator<(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs < rhs : true; } template inline constexpr bool operator<(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs < *rhs : false; } template inline constexpr bool operator<=(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs <= rhs : true; } template inline constexpr bool operator<=(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs <= *rhs : false; } template inline constexpr bool operator>(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs > rhs : false; } template inline constexpr bool operator>(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs > *rhs : true; } template inline constexpr bool operator>=(const optional &lhs, const U &rhs) { return lhs.has_value() ? *lhs >= rhs : false; } template inline constexpr bool operator>=(const U &lhs, const optional &rhs) { return rhs.has_value() ? lhs >= *rhs : true; } template ::value> * = nullptr, detail::enable_if_t::value> * = nullptr> void swap(optional &lhs, optional &rhs) noexcept(noexcept(lhs.swap(rhs))) { return lhs.swap(rhs); } namespace detail { struct i_am_secret {}; } // namespace detail template ::value, detail::decay_t, T>> inline constexpr optional make_optional(U &&v) { return optional(std::forward(v)); } template inline constexpr optional make_optional(Args &&... args) { return optional(in_place, std::forward(args)...); } template inline constexpr optional make_optional(std::initializer_list il, Args &&... args) { return optional(in_place, il, std::forward(args)...); } #if __cplusplus >= 201703L template optional(T)->optional; #endif /// \exclude namespace detail { #ifdef TL_OPTIONAL_CXX14 template (), *std::declval())), detail::enable_if_t::value> * = nullptr> constexpr auto optional_map_impl(Opt &&opt, F &&f) { return opt.has_value() ? detail::invoke(std::forward(f), *std::forward(opt)) : optional(nullopt); } template (), *std::declval())), detail::enable_if_t::value> * = nullptr> auto optional_map_impl(Opt &&opt, F &&f) { if (opt.has_value()) { detail::invoke(std::forward(f), *std::forward(opt)); return make_optional(monostate{}); } return optional(nullopt); } #else template (), *std::declval())), detail::enable_if_t::value> * = nullptr> constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional { return opt.has_value() ? detail::invoke(std::forward(f), *std::forward(opt)) : optional(nullopt); } template (), *std::declval())), detail::enable_if_t::value> * = nullptr> auto optional_map_impl(Opt &&opt, F &&f) -> optional { if (opt.has_value()) { detail::invoke(std::forward(f), *std::forward(opt)); return monostate{}; } return nullopt; } #endif } // namespace detail /// Specialization for when `T` is a reference. `optional` acts similarly /// to a `T*`, but provides more operations and shows intent more clearly. template class optional { public: // The different versions for C++14 and 11 are needed because deduced return // types are not SFINAE-safe. This provides better support for things like // generic lambdas. C.f. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation which returns an optional on the stored /// object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template TL_OPTIONAL_11_CONSTEXPR auto and_then(F &&f) && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template constexpr auto and_then(F &&f) const & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr auto and_then(F &&f) const && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #endif #else /// Carries out some operation which returns an optional on the stored /// object if there is one. template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then( F &&f) && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } template constexpr detail::invoke_result_t and_then(F &&f) const & { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr detail::invoke_result_t and_then(F &&f) const && { using result = detail::invoke_result_t; static_assert(detail::is_optional::value, "F must return an optional"); return has_value() ? detail::invoke(std::forward(f), **this) : result(nullopt); } #endif #endif #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) & { return detail::optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR auto map(F &&f) && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } template constexpr auto map(F &&f) const & { return detail::optional_map_impl(*this, std::forward(f)); } template constexpr auto map(F &&f) const && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } #else /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( std::declval(), std::declval())) map(F &&f) & { return detail::optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( std::declval(), std::declval())) map(F &&f) && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } template constexpr decltype(detail::optional_map_impl( std::declval(), std::declval())) map(F &&f) const & { return detail::optional_map_impl(*this, std::forward(f)); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr decltype(detail::optional_map_impl( std::declval(), std::declval())) map(F &&f) const && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } #endif #endif #if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR auto transform(F &&f) & { return detail::optional_map_impl(*this, std::forward(f)); } template TL_OPTIONAL_11_CONSTEXPR auto transform(F &&f) && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } template constexpr auto transform(F &&f) const & { return detail::optional_map_impl(*this, std::forward(f)); } template constexpr auto transform(F &&f) const && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } #else /// Carries out some operation on the stored object if there is one. template TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( std::declval(), std::declval())) transform(F &&f) & { return detail::optional_map_impl(*this, std::forward(f)); } /// \group map /// \synopsis template auto transform(F &&f) &&; template TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( std::declval(), std::declval())) transform(F &&f) && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } template constexpr decltype(detail::optional_map_impl( std::declval(), std::declval())) transform(F &&f) const & { return detail::optional_map_impl(*this, std::forward(f)); } #ifndef TL_OPTIONAL_NO_CONSTRR template constexpr decltype(detail::optional_map_impl( std::declval(), std::declval())) transform(F &&f) const && { return detail::optional_map_impl(std::move(*this), std::forward(f)); } #endif #endif /// Calls `f` if the optional is empty template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & { if (has_value()) return *this; std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) & { return has_value() ? *this : std::forward(f)(); } template * = nullptr> optional or_else(F &&f) && { if (has_value()) return std::move(*this); std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) && { return has_value() ? std::move(*this) : std::forward(f)(); } template * = nullptr> optional or_else(F &&f) const & { if (has_value()) return *this; std::forward(f)(); return nullopt; } template * = nullptr> optional TL_OPTIONAL_11_CONSTEXPR or_else(F &&f) const & { return has_value() ? *this : std::forward(f)(); } #ifndef TL_OPTIONAL_NO_CONSTRR template * = nullptr> optional or_else(F &&f) const && { if (has_value()) return std::move(*this); std::forward(f)(); return nullopt; } template * = nullptr> optional or_else(F &&f) const && { return has_value() ? std::move(*this) : std::forward(f)(); } #endif /// Maps the stored value with `f` if there is one, otherwise returns `u` template U map_or(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } template U map_or(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); } template U map_or(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u); } #ifndef TL_OPTIONAL_NO_CONSTRR template U map_or(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u); } #endif /// Maps the stored value with `f` if there is one, otherwise calls /// `u` and returns the result. template detail::invoke_result_t map_or_else(F &&f, U &&u) & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } template detail::invoke_result_t map_or_else(F &&f, U &&u) && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } template detail::invoke_result_t map_or_else(F &&f, U &&u) const & { return has_value() ? detail::invoke(std::forward(f), **this) : std::forward(u)(); } #ifndef TL_OPTIONAL_NO_CONSTRR template detail::invoke_result_t map_or_else(F &&f, U &&u) const && { return has_value() ? detail::invoke(std::forward(f), std::move(**this)) : std::forward(u)(); } #endif /// Returns `u` if `*this` has a value, otherwise an empty optional. template constexpr optional::type> conjunction(U &&u) const { using result = optional>; return has_value() ? result{u} : result{nullopt}; } /// Returns `rhs` if `*this` is empty, otherwise the current value. TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) & { return has_value() ? *this : rhs; } constexpr optional disjunction(const optional &rhs) const & { return has_value() ? *this : rhs; } TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional &rhs) && { return has_value() ? std::move(*this) : rhs; } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr optional disjunction(const optional &rhs) const && { return has_value() ? std::move(*this) : rhs; } #endif TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) & { return has_value() ? *this : std::move(rhs); } constexpr optional disjunction(optional &&rhs) const & { return has_value() ? *this : std::move(rhs); } TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional &&rhs) && { return has_value() ? std::move(*this) : std::move(rhs); } #ifndef TL_OPTIONAL_NO_CONSTRR constexpr optional disjunction(optional &&rhs) const && { return has_value() ? std::move(*this) : std::move(rhs); } #endif /// Takes the value out of the optional, leaving it empty optional take() { optional ret = std::move(*this); reset(); return ret; } using value_type = T &; /// Constructs an optional that does not contain a value. constexpr optional() noexcept : m_value(nullptr) {} constexpr optional(nullopt_t) noexcept : m_value(nullptr) {} /// Copy constructor /// /// If `rhs` contains a value, the stored value is direct-initialized with /// it. Otherwise, the constructed optional is empty. TL_OPTIONAL_11_CONSTEXPR optional(const optional &rhs) noexcept = default; /// Move constructor /// /// If `rhs` contains a value, the stored value is direct-initialized with /// it. Otherwise, the constructed optional is empty. TL_OPTIONAL_11_CONSTEXPR optional(optional &&rhs) = default; /// Constructs the stored value with `u`. template >::value> * = nullptr> constexpr optional(U &&u) noexcept : m_value(std::addressof(u)) { static_assert(std::is_lvalue_reference::value, "U must be an lvalue"); } template constexpr explicit optional(const optional &rhs) noexcept : optional(*rhs) {} /// No-op ~optional() = default; /// Assignment to empty. /// /// Destroys the current value if there is one. optional &operator=(nullopt_t) noexcept { m_value = nullptr; return *this; } /// Copy assignment. /// /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise /// resets the stored value in `*this`. optional &operator=(const optional &rhs) = default; /// Rebinds this optional to `u`. template >::value> * = nullptr> optional &operator=(U &&u) { static_assert(std::is_lvalue_reference::value, "U must be an lvalue"); m_value = std::addressof(u); return *this; } /// Converting copy assignment operator. /// /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise /// resets the stored value in `*this`. template optional &operator=(const optional &rhs) noexcept { m_value = std::addressof(rhs.value()); return *this; } /// Rebinds this optional to `u`. template >::value> * = nullptr> optional &emplace(U &&u) noexcept { return *this = std::forward(u); } void swap(optional &rhs) noexcept { std::swap(m_value, rhs.m_value); } /// Returns a pointer to the stored value constexpr const T *operator->() const noexcept { return m_value; } TL_OPTIONAL_11_CONSTEXPR T *operator->() noexcept { return m_value; } /// Returns the stored value TL_OPTIONAL_11_CONSTEXPR T &operator*() noexcept { return *m_value; } constexpr const T &operator*() const noexcept { return *m_value; } constexpr bool has_value() const noexcept { return m_value != nullptr; } constexpr explicit operator bool() const noexcept { return m_value != nullptr; } /// Returns the contained value if there is one, otherwise throws /// bad_optional_access TL_OPTIONAL_11_CONSTEXPR T &value() { if (has_value()) return *m_value; throw bad_optional_access(); } TL_OPTIONAL_11_CONSTEXPR const T &value() const { if (has_value()) return *m_value; throw bad_optional_access(); } /// Returns the stored value if there is one, otherwise returns `u` template constexpr T value_or(U &&u) const &noexcept { static_assert(std::is_copy_constructible::value && std::is_convertible::value, "T must be copy constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } /// \group value_or template TL_OPTIONAL_11_CONSTEXPR T value_or(U &&u) && noexcept { static_assert(std::is_move_constructible::value && std::is_convertible::value, "T must be move constructible and convertible from U"); return has_value() ? **this : static_cast(std::forward(u)); } /// Destroys the stored value if one exists, making the optional empty void reset() noexcept { m_value = nullptr; } private: T *m_value; }; // namespace tl } // namespace tl namespace std { // TODO SFINAE template struct hash> { ::std::size_t operator()(const tl::optional &o) const { if (!o.has_value()) return 0; return std::hash>()(*o); } }; } // namespace std #endif ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/feature_common.h ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. #pragma once #include "pybind11/pybind11.h" #include "pybind11/numpy.h" #include "kaldi-native-fbank/csrc/feature-window.h" namespace paddleaudio { namespace kaldi { namespace py = pybind11; template class StreamingFeatureTpl { public: typedef typename F::Options Options; StreamingFeatureTpl(const Options& opts); bool ComputeFeature(const std::vector& wav, std::vector* feats); void Reset() { remained_wav_.resize(0); } int Dim() { return computer_.Dim(); } private: bool Compute(const std::vector& waves, std::vector* feats); Options opts_; knf::FeatureWindowFunction window_function_; std::vector remained_wav_; F computer_; }; } // namespace kaldi } // namespace ppspeech #include "feature_common_inl.h" ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/feature_common_inl.h ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. namespace paddleaudio { namespace kaldi { template StreamingFeatureTpl::StreamingFeatureTpl(const Options& opts) : opts_(opts), computer_(opts), window_function_(opts.frame_opts) { // window_function_(computer_.GetFrameOptions()) { the opt set to zero } template bool StreamingFeatureTpl::ComputeFeature( const std::vector& wav, std::vector* feats) { // append remained waves int wav_len = wav.size(); if (wav_len == 0) return false; int left_len = remained_wav_.size(); std::vector waves(left_len + wav_len); std::memcpy(waves.data(), remained_wav_.data(), left_len * sizeof(float)); std::memcpy(waves.data() + left_len, wav.data(), wav_len * sizeof(float)); // cache remained waves knf::FrameExtractionOptions frame_opts = computer_.GetFrameOptions(); int num_frames = knf::NumFrames(waves.size(), frame_opts); int frame_shift = frame_opts.WindowShift(); int left_samples = waves.size() - frame_shift * num_frames; remained_wav_.resize(left_samples); std::memcpy(remained_wav_.data(), waves.data() + frame_shift * num_frames, left_samples * sizeof(float)); // compute speech feature Compute(waves, feats); return true; } // Compute feat template bool StreamingFeatureTpl::Compute(const std::vector& waves, std::vector* feats) { const knf::FrameExtractionOptions& frame_opts = computer_.GetFrameOptions(); int num_samples = waves.size(); int frame_length = frame_opts.WindowSize(); int sample_rate = frame_opts.samp_freq; if (num_samples < frame_length) { return true; } int num_frames = knf::NumFrames(num_samples, frame_opts); feats->resize(num_frames * Dim()); std::vector window; bool need_raw_log_energy = computer_.NeedRawLogEnergy(); for (int frame = 0; frame < num_frames; frame++) { std::fill(window.begin(), window.end(), 0); float raw_log_energy = 0.0; float vtln_warp = 1.0; knf::ExtractWindow(0, waves, frame, frame_opts, window_function_, &window, need_raw_log_energy ? &raw_log_energy : NULL); std::vector this_feature(computer_.Dim()); computer_.Compute( raw_log_energy, vtln_warp, &window, this_feature.data()); std::memcpy(feats->data() + frame * Dim(), this_feature.data(), sizeof(float) * Dim()); } return true; } } // namespace kaldi } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/kaldi_feature.cc ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. #include "paddleaudio/src/pybind/kaldi/kaldi_feature.h" //#include "feat/pitch-functions.h" namespace paddleaudio { namespace kaldi { bool InitFbank( knf::FrameExtractionOptions frame_opts, knf::MelBanksOptions mel_opts, FbankOptions fbank_opts) { knf::FbankOptions opts; opts.frame_opts = frame_opts; opts.mel_opts = mel_opts; opts.use_energy = fbank_opts.use_energy; opts.energy_floor = fbank_opts.energy_floor; opts.raw_energy = fbank_opts.raw_energy; opts.htk_compat = fbank_opts.htk_compat; opts.use_log_fbank = fbank_opts.use_log_fbank; opts.use_power = fbank_opts.use_power; paddleaudio::kaldi::KaldiFeatureWrapper::GetInstance()->InitFbank(opts); return true; } py::array_t ComputeFbankStreaming(const py::array_t& wav) { return paddleaudio::kaldi::KaldiFeatureWrapper::GetInstance()->ComputeFbank( wav); } py::array_t ComputeFbank( knf::FrameExtractionOptions frame_opts, knf::MelBanksOptions mel_opts, FbankOptions fbank_opts, const py::array_t& wav) { InitFbank(frame_opts, mel_opts, fbank_opts); py::array_t result = ComputeFbankStreaming(wav); paddleaudio::kaldi::KaldiFeatureWrapper::GetInstance()->ResetFbank(); return result; } void ResetFbank() { paddleaudio::kaldi::KaldiFeatureWrapper::GetInstance()->ResetFbank(); } //py::array_t ComputeKaldiPitch( //const ::kaldi::PitchExtractionOptions& opts, //const py::array_t& wav) { //py::buffer_info info = wav.request(); //::kaldi::SubVector<::kaldi::BaseFloat> input_wav((float*)info.ptr, info.size); //::kaldi::Matrix<::kaldi::BaseFloat> features; //::kaldi::ComputeKaldiPitch(opts, input_wav, &features); //auto result = py::array_t({features.NumRows(), features.NumCols()}); //for (int row_idx = 0; row_idx < features.NumRows(); ++row_idx) { //std::memcpy(result.mutable_data(row_idx), features.Row(row_idx).Data(), //sizeof(float)*features.NumCols()); //} //return result; //} } // namespace kaldi } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/kaldi_feature.h ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. #pragma once #include #include #include #include "paddleaudio/src/pybind/kaldi/kaldi_feature_wrapper.h" //#include "feat/pitch-functions.h" namespace py = pybind11; namespace paddleaudio { namespace kaldi { struct FbankOptions{ bool use_energy; // append an extra dimension with energy to the filter banks float energy_floor; bool raw_energy; // If true, compute energy before preemphasis and windowing bool htk_compat; // If true, put energy last (if using energy) bool use_log_fbank; // if true (default), produce log-filterbank, else linear bool use_power; FbankOptions(): use_energy(false), energy_floor(0.0), raw_energy(true), htk_compat(false), use_log_fbank(true), use_power(true) {} }; bool InitFbank( knf::FrameExtractionOptions frame_opts, knf::MelBanksOptions mel_opts, FbankOptions fbank_opts); py::array_t ComputeFbank( knf::FrameExtractionOptions frame_opts, knf::MelBanksOptions mel_opts, FbankOptions fbank_opts, const py::array_t& wav); py::array_t ComputeFbankStreaming(const py::array_t& wav); void ResetFbank(); //py::array_t ComputeKaldiPitch( //const ::kaldi::PitchExtractionOptions& opts, //const py::array_t& wav); } // namespace kaldi } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/kaldi_feature_wrapper.cc ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. #include "paddleaudio/src/pybind/kaldi/kaldi_feature_wrapper.h" namespace paddleaudio { namespace kaldi { KaldiFeatureWrapper* KaldiFeatureWrapper::GetInstance() { static KaldiFeatureWrapper instance; return &instance; } bool KaldiFeatureWrapper::InitFbank(knf::FbankOptions opts) { fbank_.reset(new Fbank(opts)); return true; } py::array_t KaldiFeatureWrapper::ComputeFbank( const py::array_t wav) { py::buffer_info info = wav.request(); std::vector input_wav((float*)info.ptr, (float*)info.ptr + info.size); std::vector feats; bool flag = fbank_->ComputeFeature(input_wav, &feats); if (flag == false || feats.size() == 0) return py::array_t(); auto result = py::array_t(feats.size()); py::buffer_info xs = result.request(); float* res_ptr = (float*)xs.ptr; std::memcpy(res_ptr, feats.data(), sizeof(float)*feats.size()); std::vector shape{static_cast(feats.size() / Dim()), static_cast(Dim())}; return result.reshape(shape); } } // namespace kaldi } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/kaldi/kaldi_feature_wrapper.h ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // 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. #pragma once #include "paddleaudio/third_party/kaldi-native-fbank/csrc/feature-fbank.h" #include "paddleaudio/src/pybind/kaldi/feature_common.h" namespace paddleaudio { namespace kaldi { typedef StreamingFeatureTpl Fbank; class KaldiFeatureWrapper { public: static KaldiFeatureWrapper* GetInstance(); bool InitFbank(knf::FbankOptions opts); py::array_t ComputeFbank(const py::array_t wav); int Dim() { return fbank_->Dim(); } void ResetFbank() { fbank_->Reset(); } private: std::unique_ptr fbank_; }; } // namespace kaldi } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/pybind.cpp ================================================ // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. #ifdef INCLUDE_KALDI #include "paddleaudio/src/pybind/kaldi/kaldi_feature.h" #include "paddleaudio/third_party/kaldi-native-fbank/csrc/feature-fbank.h" #endif #ifdef INCLUDE_SOX #include "paddleaudio/src/pybind/sox/io.h" #include "paddleaudio/src/pybind/sox/effects.h" #endif #include #include // `tl::optional` #ifdef INCLUDE_SOX namespace pybind11 { namespace detail { template struct type_caster> : optional_caster> {}; }} #endif PYBIND11_MODULE(_paddleaudio, m) { #ifdef INCLUDE_SOX m.def("get_info_file", &paddleaudio::sox_io::get_info_file, "Get metadata of audio file."); // support obj later m.def("get_info_fileobj", &paddleaudio::sox_io::get_info_fileobj, "Get metadata of audio in file object."); m.def("load_audio_fileobj", &paddleaudio::sox_io::load_audio_fileobj, "Load audio from file object."); m.def("save_audio_fileobj", &paddleaudio::sox_io::save_audio_fileobj, "Save audio to file obj."); // sox io m.def("sox_io_get_info", &paddleaudio::sox_io::get_info_file); m.def( "sox_io_load_audio_file", &paddleaudio::sox_io::load_audio_file); m.def( "sox_io_save_audio_file", &paddleaudio::sox_io::save_audio_file); // sox utils m.def("sox_utils_set_seed", &paddleaudio::sox_utils::set_seed); m.def( "sox_utils_set_verbosity", &paddleaudio::sox_utils::set_verbosity); m.def( "sox_utils_set_use_threads", &paddleaudio::sox_utils::set_use_threads); m.def( "sox_utils_set_buffer_size", &paddleaudio::sox_utils::set_buffer_size); m.def( "sox_utils_list_effects", &paddleaudio::sox_utils::list_effects); m.def( "sox_utils_list_read_formats", &paddleaudio::sox_utils::list_read_formats); m.def( "sox_utils_list_write_formats", &paddleaudio::sox_utils::list_write_formats); m.def( "sox_utils_get_buffer_size", &paddleaudio::sox_utils::get_buffer_size); // effect m.def("apply_effects_fileobj", &paddleaudio::sox_effects::apply_effects_fileobj, "Decode audio data from file-like obj and apply effects."); m.def("sox_effects_initialize_sox_effects", &paddleaudio::sox_effects::initialize_sox_effects); m.def( "sox_effects_shutdown_sox_effects", &paddleaudio::sox_effects::shutdown_sox_effects); m.def( "sox_effects_apply_effects_tensor", &paddleaudio::sox_effects::apply_effects_tensor); m.def( "sox_effects_apply_effects_file", &paddleaudio::sox_effects::apply_effects_file); #endif #ifdef INCLUDE_KALDI m.def("ComputeFbank", &paddleaudio::kaldi::ComputeFbank, "compute fbank"); //py::class_(m, "PitchExtractionOptions") //.def(py::init<>()) //.def_readwrite("samp_freq", &kaldi::PitchExtractionOptions::samp_freq) //.def_readwrite("frame_shift_ms", &kaldi::PitchExtractionOptions::frame_shift_ms) //.def_readwrite("frame_length_ms", &kaldi::PitchExtractionOptions::frame_length_ms) //.def_readwrite("preemph_coeff", &kaldi::PitchExtractionOptions::preemph_coeff) //.def_readwrite("min_f0", &kaldi::PitchExtractionOptions::min_f0) //.def_readwrite("max_f0", &kaldi::PitchExtractionOptions::max_f0) //.def_readwrite("soft_min_f0", &kaldi::PitchExtractionOptions::soft_min_f0) //.def_readwrite("penalty_factor", &kaldi::PitchExtractionOptions::penalty_factor) //.def_readwrite("lowpass_cutoff", &kaldi::PitchExtractionOptions::lowpass_cutoff) //.def_readwrite("resample_freq", &kaldi::PitchExtractionOptions::resample_freq) //.def_readwrite("delta_pitch", &kaldi::PitchExtractionOptions::delta_pitch) //.def_readwrite("nccf_ballast", &kaldi::PitchExtractionOptions::nccf_ballast) //.def_readwrite("lowpass_filter_width", &kaldi::PitchExtractionOptions::lowpass_filter_width) //.def_readwrite("upsample_filter_width", &kaldi::PitchExtractionOptions::upsample_filter_width) //.def_readwrite("max_frames_latency", &kaldi::PitchExtractionOptions::max_frames_latency) //.def_readwrite("frames_per_chunk", &kaldi::PitchExtractionOptions::frames_per_chunk) //.def_readwrite("simulate_first_pass_online", &kaldi::PitchExtractionOptions::simulate_first_pass_online) //.def_readwrite("recompute_frame", &kaldi::PitchExtractionOptions::recompute_frame) //.def_readwrite("nccf_ballast_online", &kaldi::PitchExtractionOptions::nccf_ballast_online) //.def_readwrite("snip_edges", &kaldi::PitchExtractionOptions::snip_edges); //m.def("ComputeKaldiPitch", &paddleaudio::kaldi::ComputeKaldiPitch, "compute kaldi pitch"); py::class_(m, "FrameExtractionOptions") .def(py::init<>()) .def_readwrite("samp_freq", &knf::FrameExtractionOptions::samp_freq) .def_readwrite("frame_shift_ms", &knf::FrameExtractionOptions::frame_shift_ms) .def_readwrite("frame_length_ms", &knf::FrameExtractionOptions::frame_length_ms) .def_readwrite("dither", &knf::FrameExtractionOptions::dither) .def_readwrite("preemph_coeff", &knf::FrameExtractionOptions::preemph_coeff) .def_readwrite("remove_dc_offset", &knf::FrameExtractionOptions::remove_dc_offset) .def_readwrite("window_type", &knf::FrameExtractionOptions::window_type) .def_readwrite("round_to_power_of_two", &knf::FrameExtractionOptions::round_to_power_of_two) .def_readwrite("blackman_coeff", &knf::FrameExtractionOptions::blackman_coeff) .def_readwrite("snip_edges", &knf::FrameExtractionOptions::snip_edges) .def_readwrite("max_feature_vectors", &knf::FrameExtractionOptions::max_feature_vectors); py::class_(m, "MelBanksOptions") .def(py::init<>()) .def_readwrite("num_bins", &knf::MelBanksOptions::num_bins) .def_readwrite("low_freq", &knf::MelBanksOptions::low_freq) .def_readwrite("high_freq", &knf::MelBanksOptions::high_freq) .def_readwrite("vtln_low", &knf::MelBanksOptions::vtln_low) .def_readwrite("vtln_high", &knf::MelBanksOptions::vtln_high) .def_readwrite("debug_mel", &knf::MelBanksOptions::debug_mel) .def_readwrite("htk_mode", &knf::MelBanksOptions::htk_mode); py::class_(m, "FbankOptions") .def(py::init<>()) .def_readwrite("use_energy", &paddleaudio::kaldi::FbankOptions::use_energy) .def_readwrite("energy_floor", &paddleaudio::kaldi::FbankOptions::energy_floor) .def_readwrite("raw_energy", &paddleaudio::kaldi::FbankOptions::raw_energy) .def_readwrite("htk_compat", &paddleaudio::kaldi::FbankOptions::htk_compat) .def_readwrite("use_log_fbank", &paddleaudio::kaldi::FbankOptions::use_log_fbank) .def_readwrite("use_power", &paddleaudio::kaldi::FbankOptions::use_power); #endif } ================================================ FILE: audio/paddleaudio/src/pybind/sox/effects.cpp ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/effects.cpp with modification. #include #include #include "paddleaudio/src/pybind/sox/effects.h" #include "paddleaudio/src/pybind/sox/effects_chain.h" #include "paddleaudio/src/pybind/sox/utils.h" using namespace paddleaudio::sox_utils; namespace paddleaudio::sox_effects { // Streaming decoding over file-like object is tricky because libsox operates on // FILE pointer. The following is what `sox` and `play` commands do // - file input -> FILE pointer // - URL input -> call wget in subprocess and pipe the data -> FILE pointer // - stdin -> FILE pointer // // We want to, instead, fetch byte strings chunk by chunk, consume them, and // discard. // // Here is the approach // 1. Initialize sox_format_t using sox_open_mem_read, providing the initial // chunk of byte string // This will perform header-based format detection, if necessary, then fill // the metadata of sox_format_t. Internally, sox_open_mem_read uses fmemopen, // which returns FILE* which points the buffer of the provided byte string. // 2. Each time sox reads a chunk from the FILE*, we update the underlying // buffer in a way that it // starts with unseen data, and append the new data read from the given // fileobj. This will trick libsox as if it keeps reading from the FILE* // continuously. // For Step 2. see `fileobj_input_drain` function in effects_chain.cpp auto apply_effects_fileobj( py::object fileobj, const std::vector>& effects, tl::optional normalize, tl::optional channels_first, tl::optional format) -> tl::optional> { // Prepare the buffer used throughout the lifecycle of SoxEffectChain. // // For certain format (such as FLAC), libsox keeps reading the content at // the initialization unless it reaches EOF even when the header is properly // parsed. (Making buffer size 8192, which is way bigger than the header, // resulted in libsox consuming all the buffer content at the time it opens // the file.) Therefore buffer has to always contain valid data, except after // EOF. We default to `sox_get_globals()->bufsiz`* for buffer size and we // first check if there is enough data to fill the buffer. `read_fileobj` // repeatedly calls `read` method until it receives the requested length of // bytes or it reaches EOF. If we get bytes shorter than requested, that means // the whole audio data are fetched. // // * This can be changed with `paddleaudio.utils.sox_utils.set_buffer_size`. const auto capacity = [&]() { // NOTE: // Use the abstraction provided by `libpaddleaudio` to access the global // config defined by libsox. Directly using `sox_get_globals` function will // end up retrieving the static variable defined in `_paddleaudio`, which is // not correct. const auto bufsiz = get_buffer_size(); const int64_t kDefaultCapacityInBytes = 256; return (bufsiz > kDefaultCapacityInBytes) ? bufsiz : kDefaultCapacityInBytes; }(); std::string buffer(capacity, '\0'); auto* in_buf = const_cast(buffer.data()); auto num_read = read_fileobj(&fileobj, capacity, in_buf); // If the file is shorter than 256, then libsox cannot read the header. auto in_buffer_size = (num_read > 256) ? num_read : 256; // Open file (this starts reading the header) // When opening a file there are two functions that can touches FILE*. // * `auto_detect_format` // https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/formats.c#L43 // * `startread` handler of detected format. // https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/formats.c#L574 // To see the handler of a particular format, go to // https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/.c // For example, voribs can be found // https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/vorbis.c#L97-L158 SoxFormat sf(sox_open_mem_read( in_buf, in_buffer_size, /*signal=*/nullptr, /*encoding=*/nullptr, /*filetype=*/format.has_value() ? format.value().c_str() : nullptr)); // In case of streamed data, length can be 0 if (static_cast(sf) == nullptr || sf->encoding.encoding == SOX_ENCODING_UNKNOWN) { return {}; } // Prepare output buffer std::vector out_buffer; out_buffer.reserve(sf->signal.length); // Create and run SoxEffectsChain const auto dtype = get_dtype(sf->encoding.encoding, sf->signal.precision); paddleaudio::sox_effects_chain::SoxEffectsChainPyBind chain( /*input_encoding=*/sf->encoding, /*output_encoding=*/get_tensor_encodinginfo(dtype)); chain.addInputFileObj(sf, in_buf, in_buffer_size, &fileobj); for (const auto& effect : effects) { chain.addEffect(effect); } chain.addOutputBuffer(&out_buffer); chain.run(); // Create tensor from buffer bool channels_first_ = channels_first.value_or(true); auto tensor = convert_to_tensor( /*buffer=*/out_buffer.data(), /*num_samples=*/out_buffer.size(), /*num_channels=*/chain.getOutputNumChannels(), dtype, normalize.value_or(true), channels_first_); return std::forward_as_tuple( tensor, static_cast(chain.getOutputSampleRate())); } namespace { enum SoxEffectsResourceState { NotInitialized, Initialized, ShutDown }; SoxEffectsResourceState SOX_RESOURCE_STATE = NotInitialized; std::mutex SOX_RESOURCE_STATE_MUTEX; } // namespace void initialize_sox_effects() { const std::lock_guard lock(SOX_RESOURCE_STATE_MUTEX); switch (SOX_RESOURCE_STATE) { case NotInitialized: if (sox_init() != SOX_SUCCESS) { throw std::runtime_error("Failed to initialize sox effects."); }; SOX_RESOURCE_STATE = Initialized; break; case Initialized: break; case ShutDown: throw std::runtime_error( "SoX Effects has been shut down. Cannot initialize again."); } }; void shutdown_sox_effects() { const std::lock_guard lock(SOX_RESOURCE_STATE_MUTEX); switch (SOX_RESOURCE_STATE) { case NotInitialized: throw std::runtime_error( "SoX Effects is not initialized. Cannot shutdown."); case Initialized: if (sox_quit() != SOX_SUCCESS) { throw std::runtime_error("Failed to initialize sox effects."); }; SOX_RESOURCE_STATE = ShutDown; break; case ShutDown: break; } } auto apply_effects_tensor( py::array waveform, int64_t sample_rate, const std::vector>& effects, bool channels_first) -> std::tuple { validate_input_tensor(waveform); // Create SoxEffectsChain const auto dtype = waveform.dtype(); paddleaudio::sox_effects_chain::SoxEffectsChain chain( /*input_encoding=*/get_tensor_encodinginfo(dtype), /*output_encoding=*/get_tensor_encodinginfo(dtype)); // Prepare output buffer std::vector out_buffer; out_buffer.reserve(waveform.size()); // Build and run effects chain chain.addInputTensor(&waveform, sample_rate, channels_first); for (const auto& effect : effects) { chain.addEffect(effect); } chain.addOutputBuffer(&out_buffer); chain.run(); // Create tensor from buffer auto out_tensor = convert_to_tensor( /*buffer=*/out_buffer.data(), /*num_samples=*/out_buffer.size(), /*num_channels=*/chain.getOutputNumChannels(), dtype, /*normalize=*/false, channels_first); return std::tuple( out_tensor, chain.getOutputSampleRate()); } auto apply_effects_file( const std::string& path, const std::vector>& effects, tl::optional normalize, tl::optional channels_first, const tl::optional& format) -> tl::optional> { // Open input file SoxFormat sf(sox_open_read( path.c_str(), /*signal=*/nullptr, /*encoding=*/nullptr, /*filetype=*/format.has_value() ? format.value().c_str() : nullptr)); if (static_cast(sf) == nullptr || sf->encoding.encoding == SOX_ENCODING_UNKNOWN) { return {}; } const auto dtype = get_dtype(sf->encoding.encoding, sf->signal.precision); // Prepare output std::vector out_buffer; out_buffer.reserve(sf->signal.length); // Create and run SoxEffectsChain paddleaudio::sox_effects_chain::SoxEffectsChain chain( /*input_encoding=*/sf->encoding, /*output_encoding=*/get_tensor_encodinginfo(dtype)); chain.addInputFile(sf); for (const auto& effect : effects) { chain.addEffect(effect); } chain.addOutputBuffer(&out_buffer); chain.run(); // Create tensor from buffer bool channels_first_ = channels_first.value_or(true); auto tensor = convert_to_tensor( /*buffer=*/out_buffer.data(), /*num_samples=*/out_buffer.size(), /*num_channels=*/chain.getOutputNumChannels(), dtype, normalize.value_or(true), channels_first_); return std::tuple( tensor, chain.getOutputSampleRate()); } } // namespace paddleaudio::sox_effects ================================================ FILE: audio/paddleaudio/src/pybind/sox/effects.h ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/effects.h with modification. #include #include #include "paddleaudio/src/optional/optional.hpp" namespace py = pybind11; namespace paddleaudio::sox_effects { auto apply_effects_fileobj( py::object fileobj, const std::vector>& effects, tl::optional normalize, tl::optional channels_first, tl::optional format) -> tl::optional>; void initialize_sox_effects(); void shutdown_sox_effects(); auto apply_effects_tensor( py::array waveform, int64_t sample_rate, const std::vector>& effects, bool channels_first) -> std::tuple; auto apply_effects_file( const std::string& path, const std::vector>& effects, tl::optional normalize, tl::optional channels_first, const tl::optional& format) -> tl::optional>; } // namespace paddleaudio::sox_effects ================================================ FILE: audio/paddleaudio/src/pybind/sox/effects_chain.cpp ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/effects_chain.cpp with modification. #include #include #include #include "paddleaudio/src/pybind/sox/effects_chain.h" #include "paddleaudio/src/pybind/sox/utils.h" using namespace paddleaudio::sox_utils; namespace paddleaudio::sox_effects_chain { namespace { /// helper classes for passing the location of input tensor and output buffer /// /// drain/flow callback functions require plain C style function signature and /// the way to pass extra data is to attach data to sox_effect_t::priv pointer. /// The following structs will be assigned to sox_effect_t::priv pointer which /// gives sox_effect_t an access to input Tensor and output buffer object. struct TensorInputPriv { size_t index; py::array* waveform; int64_t sample_rate; bool channels_first; }; struct TensorOutputPriv { std::vector* buffer; }; struct FileOutputPriv { sox_format_t* sf; }; /// Callback function to feed Tensor data to SoxEffectChain. int tensor_input_drain(sox_effect_t* effp, sox_sample_t* obuf, size_t* osamp) { // Retrieve the input Tensor and current index auto priv = static_cast(effp->priv); auto index = priv->index; auto tensor = *(priv->waveform); auto num_channels = effp->out_signal.channels; // Adjust the number of samples to read const size_t num_samples = tensor.size(); if (index + *osamp > num_samples) { *osamp = num_samples - index; } // Ensure that it's a multiple of the number of channels *osamp -= *osamp % num_channels; // Slice the input Tensor // refactor this module, chunk auto i_frame = index / num_channels; auto num_frames = *osamp / num_channels; std::vector chunk(num_frames*num_channels); py::buffer_info ori_info = tensor.request(); void* ptr = ori_info.ptr; // Convert to sox_sample_t (int32_t) switch (tensor.dtype().num()) { //case c10::ScalarType::Float: { case 11: { // Need to convert to 64-bit precision so that // values around INT32_MIN/MAX are handled correctly. for (int idx = 0; idx < chunk.size(); ++idx) { int frame_idx = (idx + index) / num_channels; int channels_idx = (idx + index) % num_channels; double elem = 0; if (priv->channels_first) { elem = *(float*)tensor.data(channels_idx, frame_idx); } else { elem = *(float*)tensor.data(frame_idx, channels_idx); } elem = elem * 2147483648.; // *new_ptr = std::clamp(elem, INT32_MIN, INT32_MAX); if (elem > INT32_MAX) { chunk[idx] = INT32_MAX; } else if (elem < INT32_MIN) { chunk[idx] = INT32_MIN; } else { chunk[idx] = elem; } } break; } //case c10::ScalarType::Int: { case 5: { for (int idx = 0; idx < chunk.size(); ++idx) { int frame_idx = (idx + index) / num_channels; int channels_idx = (idx + index) % num_channels; int elem = 0; if (priv->channels_first) { elem = *(int*)tensor.data(channels_idx, frame_idx); } else { elem = *(int*)tensor.data(frame_idx, channels_idx); } chunk[idx] = elem; } break; } // case short case 3: { for (int idx = 0; idx < chunk.size(); ++idx) { int frame_idx = (idx + index) / num_channels; int channels_idx = (idx + index) % num_channels; int16_t elem = 0; if (priv->channels_first) { elem = *(int16_t*)tensor.data(channels_idx, frame_idx); } else { elem = *(int16_t*)tensor.data(frame_idx, channels_idx); } chunk[idx] = elem * 65536; } break; } // case byte case 1: { for (int idx = 0; idx < chunk.size(); ++idx) { int frame_idx = (idx + index) / num_channels; int channels_idx = (idx + index) % num_channels; int8_t elem = 0; if (priv->channels_first) { elem = *(int8_t*)tensor.data(channels_idx, frame_idx); } else { elem = *(int8_t*)tensor.data(frame_idx, channels_idx); } chunk[idx] = (elem - 128) * 16777216; } break; } default: throw std::runtime_error("Unexpected dtype."); } // Write to buffer memcpy(obuf, chunk.data(), *osamp * 4); priv->index += *osamp; return (priv->index == num_samples) ? SOX_EOF : SOX_SUCCESS; } /// Callback function to fetch data from SoxEffectChain. int tensor_output_flow( sox_effect_t* effp, sox_sample_t const* ibuf, sox_sample_t* obuf LSX_UNUSED, size_t* isamp, size_t* osamp) { *osamp = 0; // Get output buffer auto out_buffer = static_cast(effp->priv)->buffer; // Append at the end out_buffer->insert(out_buffer->end(), ibuf, ibuf + *isamp); return SOX_SUCCESS; } int file_output_flow( sox_effect_t* effp, sox_sample_t const* ibuf, sox_sample_t* obuf LSX_UNUSED, size_t* isamp, size_t* osamp) { *osamp = 0; if (*isamp) { auto sf = static_cast(effp->priv)->sf; if (sox_write(sf, ibuf, *isamp) != *isamp) { if (sf->sox_errno) { std::ostringstream stream; stream << sf->sox_errstr << " " << sox_strerror(sf->sox_errno) << " " << sf->filename; throw std::runtime_error(stream.str()); } return SOX_EOF; } } return SOX_SUCCESS; } sox_effect_handler_t* get_tensor_input_handler() { static sox_effect_handler_t handler{ /*name=*/"input_tensor", /*usage=*/NULL, /*flags=*/SOX_EFF_MCHAN, /*getopts=*/NULL, /*start=*/NULL, /*flow=*/NULL, /*drain=*/tensor_input_drain, /*stop=*/NULL, /*kill=*/NULL, /*priv_size=*/sizeof(TensorInputPriv)}; return &handler; } sox_effect_handler_t* get_tensor_output_handler() { static sox_effect_handler_t handler{ /*name=*/"output_tensor", /*usage=*/NULL, /*flags=*/SOX_EFF_MCHAN, /*getopts=*/NULL, /*start=*/NULL, /*flow=*/tensor_output_flow, /*drain=*/NULL, /*stop=*/NULL, /*kill=*/NULL, /*priv_size=*/sizeof(TensorOutputPriv)}; return &handler; } sox_effect_handler_t* get_file_output_handler() { static sox_effect_handler_t handler{ /*name=*/"output_file", /*usage=*/NULL, /*flags=*/SOX_EFF_MCHAN, /*getopts=*/NULL, /*start=*/NULL, /*flow=*/file_output_flow, /*drain=*/NULL, /*stop=*/NULL, /*kill=*/NULL, /*priv_size=*/sizeof(FileOutputPriv)}; return &handler; } } // namespace SoxEffect::SoxEffect(sox_effect_t* se) noexcept : se_(se) {} SoxEffect::~SoxEffect() { if (se_ != nullptr) { free(se_); } } SoxEffect::operator sox_effect_t*() const { return se_; } auto SoxEffect::operator->() noexcept -> sox_effect_t* { return se_; } SoxEffectsChain::SoxEffectsChain( sox_encodinginfo_t input_encoding, sox_encodinginfo_t output_encoding) : in_enc_(input_encoding), out_enc_(output_encoding), in_sig_(), interm_sig_(), out_sig_(), sec_(sox_create_effects_chain(&in_enc_, &out_enc_)) { if (!sec_) { throw std::runtime_error("Failed to create effect chain."); } } SoxEffectsChain::~SoxEffectsChain() { if (sec_ != nullptr) { sox_delete_effects_chain(sec_); } } void SoxEffectsChain::run() { sox_flow_effects(sec_, NULL, NULL); } void SoxEffectsChain::addInputTensor( py::array* waveform, int64_t sample_rate, bool channels_first) { in_sig_ = get_signalinfo(waveform, sample_rate, "wav", channels_first); interm_sig_ = in_sig_; SoxEffect e(sox_create_effect(get_tensor_input_handler())); auto priv = static_cast(e->priv); priv->index = 0; priv->waveform = waveform; priv->sample_rate = sample_rate; priv->channels_first = channels_first; if (sox_add_effect(sec_, e, &interm_sig_, &in_sig_) != SOX_SUCCESS) { throw std::runtime_error( "Internal Error: Failed to add effect: input_tensor"); } } void SoxEffectsChain::addOutputBuffer( std::vector* output_buffer) { SoxEffect e(sox_create_effect(get_tensor_output_handler())); static_cast(e->priv)->buffer = output_buffer; if (sox_add_effect(sec_, e, &interm_sig_, &in_sig_) != SOX_SUCCESS) { throw std::runtime_error( "Internal Error: Failed to add effect: output_tensor"); } } void SoxEffectsChain::addInputFile(sox_format_t* sf) { in_sig_ = sf->signal; interm_sig_ = in_sig_; SoxEffect e(sox_create_effect(sox_find_effect("input"))); char* opts[] = {(char*)sf}; sox_effect_options(e, 1, opts); if (sox_add_effect(sec_, e, &interm_sig_, &in_sig_) != SOX_SUCCESS) { std::ostringstream stream; stream << "Internal Error: Failed to add effect: input " << sf->filename; throw std::runtime_error(stream.str()); } } void SoxEffectsChain::addOutputFile(sox_format_t* sf) { out_sig_ = sf->signal; SoxEffect e(sox_create_effect(get_file_output_handler())); static_cast(e->priv)->sf = sf; if (sox_add_effect(sec_, e, &interm_sig_, &out_sig_) != SOX_SUCCESS) { std::ostringstream stream; stream << "Internal Error: Failed to add effect: output " << sf->filename; throw std::runtime_error(stream.str()); } } void SoxEffectsChain::addEffect(const std::vector effect) { const auto num_args = effect.size(); if (num_args == 0) { throw std::runtime_error("Invalid argument: empty effect."); } const auto name = effect[0]; if (UNSUPPORTED_EFFECTS.find(name) != UNSUPPORTED_EFFECTS.end()) { std::ostringstream stream; stream << "Unsupported effect: " << name; throw std::runtime_error(stream.str()); } auto returned_effect = sox_find_effect(name.c_str()); if (!returned_effect) { std::ostringstream stream; stream << "Unsupported effect: " << name; throw std::runtime_error(stream.str()); } SoxEffect e(sox_create_effect(returned_effect)); const auto num_options = num_args - 1; std::vector opts; for (size_t i = 1; i < num_args; ++i) { opts.push_back((char*)effect[i].c_str()); } if (sox_effect_options(e, num_options, num_options ? opts.data() : nullptr) != SOX_SUCCESS) { std::ostringstream stream; stream << "Invalid effect option:"; for (const auto& v : effect) { stream << " " << v; } throw std::runtime_error(stream.str()); } if (sox_add_effect(sec_, e, &interm_sig_, &in_sig_) != SOX_SUCCESS) { std::ostringstream stream; stream << "Internal Error: Failed to add effect: \"" << name; for (size_t i = 1; i < num_args; ++i) { stream << " " << effect[i]; } stream << "\""; throw std::runtime_error(stream.str()); } } int64_t SoxEffectsChain::getOutputNumChannels() { return interm_sig_.channels; } int64_t SoxEffectsChain::getOutputSampleRate() { return interm_sig_.rate; } namespace { /// helper classes for passing file-like object to SoxEffectChain struct FileObjInputPriv { sox_format_t* sf; py::object* fileobj; bool eof_reached; char* buffer; uint64_t buffer_size; }; struct FileObjOutputPriv { sox_format_t* sf; py::object* fileobj; char** buffer; size_t* buffer_size; }; /// Callback function to feed byte string /// https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/sox.h#L1268-L1278 auto fileobj_input_drain(sox_effect_t* effp, sox_sample_t* obuf, size_t* osamp) -> int { auto priv = static_cast(effp->priv); auto sf = priv->sf; auto buffer = priv->buffer; // 1. Refresh the buffer // // NOTE: // Since the underlying FILE* was opened with `fmemopen`, the only way // libsox detect EOF is reaching the end of the buffer. (null byte won't // help) Therefore we need to align the content at the end of buffer, // otherwise, libsox will keep reading the content beyond intended length. // // Before: // // |<-------consumed------>|<---remaining--->| // |***********************|-----------------| // ^ ftell // // After: // // |<-offset->|<---remaining--->|<-new data->| // |**********|-----------------|++++++++++++| // ^ ftell // NOTE: // Do not use `sf->tell_off` here. Presumably, `tell_off` and `fseek` are // supposed to be in sync, but there are cases (Vorbis) they are not // in sync and `tell_off` has seemingly uninitialized value, which // leads num_remain to be negative and cause segmentation fault // in `memmove`. const auto tell = ftell((FILE*)sf->fp); if (tell < 0) { throw std::runtime_error("Internal Error: ftell failed."); } const auto num_consumed = static_cast(tell); if (num_consumed > priv->buffer_size) { throw std::runtime_error("Internal Error: buffer overrun."); } const auto num_remain = priv->buffer_size - num_consumed; // 1.1. Fetch the data to see if there is data to fill the buffer size_t num_refill = 0; std::string chunk(num_consumed, '\0'); if (num_consumed && !priv->eof_reached) { num_refill = read_fileobj( priv->fileobj, num_consumed, const_cast(chunk.data())); if (num_refill < num_consumed) { priv->eof_reached = true; } } const auto offset = num_consumed - num_refill; // 1.2. Move the unconsumed data towards the beginning of buffer. if (num_remain) { auto src = static_cast(buffer + num_consumed); auto dst = static_cast(buffer + offset); memmove(dst, src, num_remain); } // 1.3. Refill the remaining buffer. if (num_refill) { auto src = static_cast(const_cast(chunk.c_str())); auto dst = buffer + offset + num_remain; memcpy(dst, src, num_refill); } // 1.4. Set the file pointer to the new offset sf->tell_off = offset; fseek((FILE*)sf->fp, offset, SEEK_SET); // 2. Perform decoding operation // The following part is practically same as "input" effect // https://github.com/dmkrepo/libsox/blob/b9dd1a86e71bbd62221904e3e59dfaa9e5e72046/src/input.c#L30-L48 // At this point, osamp represents the buffer size in bytes, // but sox_read expects the maximum number of samples ready to read. // Normally, this is fine, but in case when the samples are not 4-byte // aligned, (e.g. sample is 24bits), the resulting signal is not correct. // https://github.com/pytorch/audio/issues/2083 if (sf->encoding.bits_per_sample > 0) *osamp /= (sf->encoding.bits_per_sample / 8); // Ensure that it's a multiple of the number of channels *osamp -= *osamp % effp->out_signal.channels; // Read up to *osamp samples into obuf; // store the actual number read back to *osamp *osamp = sox_read(sf, obuf, *osamp); // Decoding is finished when fileobject is exhausted and sox can no longer // decode a sample. return (priv->eof_reached && !*osamp) ? SOX_EOF : SOX_SUCCESS; } auto fileobj_output_flow( sox_effect_t* effp, sox_sample_t const* ibuf, sox_sample_t* obuf LSX_UNUSED, size_t* isamp, size_t* osamp) -> int { *osamp = 0; if (*isamp) { auto priv = static_cast(effp->priv); auto sf = priv->sf; auto fp = static_cast(sf->fp); auto fileobj = priv->fileobj; auto buffer = priv->buffer; // Encode chunk auto num_samples_written = sox_write(sf, ibuf, *isamp); fflush(fp); // Copy the encoded chunk to python object. fileobj->attr("write")(py::bytes(*buffer, ftell(fp))); // Reset FILE* sf->tell_off = 0; fseek(fp, 0, SEEK_SET); if (num_samples_written != *isamp) { if (sf->sox_errno) { std::ostringstream stream; stream << sf->sox_errstr << " " << sox_strerror(sf->sox_errno) << " " << sf->filename; throw std::runtime_error(stream.str()); } return SOX_EOF; } } return SOX_SUCCESS; } auto get_fileobj_input_handler() -> sox_effect_handler_t* { static sox_effect_handler_t handler{ /*name=*/"input_fileobj_object", /*usage=*/nullptr, /*flags=*/SOX_EFF_MCHAN, /*getopts=*/nullptr, /*start=*/nullptr, /*flow=*/nullptr, /*drain=*/fileobj_input_drain, /*stop=*/nullptr, /*kill=*/nullptr, /*priv_size=*/sizeof(FileObjInputPriv)}; return &handler; } auto get_fileobj_output_handler() -> sox_effect_handler_t* { static sox_effect_handler_t handler{ /*name=*/"output_fileobj_object", /*usage=*/nullptr, /*flags=*/SOX_EFF_MCHAN, /*getopts=*/nullptr, /*start=*/nullptr, /*flow=*/fileobj_output_flow, /*drain=*/nullptr, /*stop=*/nullptr, /*kill=*/nullptr, /*priv_size=*/sizeof(FileObjOutputPriv)}; return &handler; } } // namespace void SoxEffectsChainPyBind::addInputFileObj( sox_format_t* sf, char* buffer, uint64_t buffer_size, py::object* fileobj) { in_sig_ = sf->signal; interm_sig_ = in_sig_; SoxEffect e(sox_create_effect(get_fileobj_input_handler())); auto priv = static_cast(e->priv); priv->sf = sf; priv->fileobj = fileobj; priv->eof_reached = false; priv->buffer = buffer; priv->buffer_size = buffer_size; if (sox_add_effect(sec_, e, &interm_sig_, &in_sig_) != SOX_SUCCESS) { throw std::runtime_error( "Internal Error: Failed to add effect: input fileobj"); } } void SoxEffectsChainPyBind::addOutputFileObj( sox_format_t* sf, char** buffer, size_t* buffer_size, py::object* fileobj) { out_sig_ = sf->signal; SoxEffect e(sox_create_effect(get_fileobj_output_handler())); auto priv = static_cast(e->priv); priv->sf = sf; priv->fileobj = fileobj; priv->buffer = buffer; priv->buffer_size = buffer_size; if (sox_add_effect(sec_, e, &interm_sig_, &out_sig_) != SOX_SUCCESS) { throw std::runtime_error( "Internal Error: Failed to add effect: output fileobj"); } } } // namespace paddleaudio::sox_effects_chain ================================================ FILE: audio/paddleaudio/src/pybind/sox/effects_chain.h ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/effects_chain.h with modification. #pragma once #include #include "paddleaudio/src/pybind/sox/utils.h" namespace paddleaudio::sox_effects_chain { // Helper struct to safely close sox_effect_t* pointer returned by // sox_create_effect struct SoxEffect { explicit SoxEffect(sox_effect_t* se) noexcept; SoxEffect(const SoxEffect& other) = delete; SoxEffect(const SoxEffect&& other) = delete; auto operator=(const SoxEffect& other) -> SoxEffect& = delete; auto operator=(SoxEffect&& other) -> SoxEffect& = delete; ~SoxEffect(); operator sox_effect_t*() const; auto operator->() noexcept -> sox_effect_t*; private: sox_effect_t* se_; }; // Helper struct to safely close sox_effects_chain_t with handy methods class SoxEffectsChain { const sox_encodinginfo_t in_enc_; const sox_encodinginfo_t out_enc_; protected: sox_signalinfo_t in_sig_; sox_signalinfo_t interm_sig_; sox_signalinfo_t out_sig_; sox_effects_chain_t* sec_; public: explicit SoxEffectsChain( sox_encodinginfo_t input_encoding, sox_encodinginfo_t output_encoding); SoxEffectsChain(const SoxEffectsChain& other) = delete; SoxEffectsChain(const SoxEffectsChain&& other) = delete; SoxEffectsChain& operator=(const SoxEffectsChain& other) = delete; SoxEffectsChain& operator=(SoxEffectsChain&& other) = delete; ~SoxEffectsChain(); void run(); void addInputTensor( py::array* waveform, int64_t sample_rate, bool channels_first); void addInputFile(sox_format_t* sf); void addOutputBuffer(std::vector* output_buffer); void addOutputFile(sox_format_t* sf); void addEffect(const std::vector effect); int64_t getOutputNumChannels(); int64_t getOutputSampleRate(); }; class SoxEffectsChainPyBind : public SoxEffectsChain { using SoxEffectsChain::SoxEffectsChain; public: void addInputFileObj( sox_format_t* sf, char* buffer, uint64_t buffer_size, py::object* fileobj); void addOutputFileObj( sox_format_t* sf, char** buffer, size_t* buffer_size, py::object* fileobj); }; } // namespace paddleaudio::sox_effects_chain ================================================ FILE: audio/paddleaudio/src/pybind/sox/io.cpp ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/io.cpp with modification. #include "paddleaudio/src/pybind/sox/io.h" #include "paddleaudio/src/pybind/sox/effects.h" #include "paddleaudio/src/pybind/sox/types.h" #include "paddleaudio/src/pybind/sox/effects_chain.h" #include "paddleaudio/src/pybind/sox/utils.h" #include "paddleaudio/src/optional/optional.hpp" using namespace paddleaudio::sox_utils; namespace paddleaudio { namespace sox_io { auto get_info_file(const std::string &path, const tl::optional &format) -> std::tuple { SoxFormat sf( sox_open_read(path.data(), /*signal=*/nullptr, /*encoding=*/nullptr, /*filetype=*/format.has_value() ? format.value().c_str() : nullptr)); validate_input_file(sf, path); return std::make_tuple( static_cast(sf->signal.rate), static_cast(sf->signal.length / sf->signal.channels), static_cast(sf->signal.channels), static_cast(sf->encoding.bits_per_sample), get_encoding(sf->encoding.encoding)); } std::vector> get_effects( const tl::optional& frame_offset, const tl::optional& num_frames) { const auto offset = frame_offset.value_or(0); if (offset < 0) { throw std::runtime_error( "Invalid argument: frame_offset must be non-negative."); } const auto frames = num_frames.value_or(-1); if (frames == 0 || frames < -1) { throw std::runtime_error( "Invalid argument: num_frames must be -1 or greater than 0."); } std::vector> effects; if (frames != -1) { std::ostringstream os_offset, os_frames; os_offset << offset << "s"; os_frames << "+" << frames << "s"; effects.emplace_back( std::vector{"trim", os_offset.str(), os_frames.str()}); } else if (offset != 0) { std::ostringstream os_offset; os_offset << offset << "s"; effects.emplace_back(std::vector{"trim", os_offset.str()}); } return effects; } auto get_info_fileobj(py::object fileobj, const tl::optional &format) -> std::tuple { const auto capacity = [&]() { const auto bufsiz = get_buffer_size(); const int64_t kDefaultCapacityInBytes = 4096; return (bufsiz > kDefaultCapacityInBytes) ? bufsiz : kDefaultCapacityInBytes; }(); std::string buffer(capacity, '\0'); auto *buf = const_cast(buffer.data()); auto num_read = read_fileobj(&fileobj, capacity, buf); // If the file is shorter than 256, then libsox cannot read the header. auto buf_size = (num_read > 256) ? num_read : 256; SoxFormat sf(sox_open_mem_read( buf, buf_size, /*signal=*/nullptr, /*encoding=*/nullptr, /*filetype=*/format.has_value() ? format.value().c_str() : nullptr)); // In case of streamed data, length can be 0 validate_input_memfile(sf); return std::make_tuple( static_cast(sf->signal.rate), static_cast(sf->signal.length / sf->signal.channels), static_cast(sf->signal.channels), static_cast(sf->encoding.bits_per_sample), get_encoding(sf->encoding.encoding)); } tl::optional> load_audio_fileobj( py::object fileobj, const tl::optional& frame_offset, const tl::optional& num_frames, tl::optional normalize, tl::optional channels_first, const tl::optional& format) { auto effects = get_effects(frame_offset, num_frames); return paddleaudio::sox_effects::apply_effects_fileobj( std::move(fileobj), effects, normalize, channels_first, std::move(format)); } tl::optional> load_audio_file( const std::string& path, const tl::optional& frame_offset, const tl::optional& num_frames, tl::optional normalize, tl::optional channels_first, const tl::optional& format) { auto effects = get_effects(frame_offset, num_frames); return paddleaudio::sox_effects::apply_effects_file( path, effects, normalize, channels_first, format); } void save_audio_file(const std::string& path, py::array tensor, int64_t sample_rate, bool channels_first, tl::optional compression, tl::optional format, tl::optional encoding, tl::optional bits_per_sample) { validate_input_tensor(tensor); const auto filetype = [&]() { if (format.has_value()) return format.value(); return get_filetype(path); }(); if (filetype == "amr-nb") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); //TORCH_CHECK(num_channels == 1, // "amr-nb format only supports single channel audio."); assert(num_channels == 1); } else if (filetype == "htk") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); // TORCH_CHECK(num_channels == 1, // "htk format only supports single channel audio."); assert(num_channels == 1); } else if (filetype == "gsm") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); assert(num_channels == 1); assert(sample_rate == 8000); //TORCH_CHECK(num_channels == 1, // "gsm format only supports single channel audio."); //TORCH_CHECK(sample_rate == 8000, // "gsm format only supports a sampling rate of 8kHz."); } const auto signal_info = get_signalinfo(&tensor, sample_rate, filetype, channels_first); const auto encoding_info = get_encodinginfo_for_save( filetype, tensor.dtype(), compression, encoding, bits_per_sample); SoxFormat sf(sox_open_write(path.c_str(), &signal_info, &encoding_info, /*filetype=*/filetype.c_str(), /*oob=*/nullptr, /*overwrite_permitted=*/nullptr)); if (static_cast(sf) == nullptr) { throw std::runtime_error( "Error saving audio file: failed to open file " + path); } paddleaudio::sox_effects_chain::SoxEffectsChain chain( /*input_encoding=*/get_tensor_encodinginfo(tensor.dtype()), /*output_encoding=*/sf->encoding); chain.addInputTensor(&tensor, sample_rate, channels_first); chain.addOutputFile(sf); chain.run(); } namespace { // helper class to automatically release buffer, to be used by // save_audio_fileobj struct AutoReleaseBuffer { char* ptr; size_t size; AutoReleaseBuffer() : ptr(nullptr), size(0) {} AutoReleaseBuffer(const AutoReleaseBuffer& other) = delete; AutoReleaseBuffer(AutoReleaseBuffer&& other) = delete; auto operator=(const AutoReleaseBuffer& other) -> AutoReleaseBuffer& = delete; auto operator=(AutoReleaseBuffer&& other) -> AutoReleaseBuffer& = delete; ~AutoReleaseBuffer() { if (ptr) { free(ptr); } } }; } // namespace void save_audio_fileobj( py::object fileobj, py::array tensor, int64_t sample_rate, bool channels_first, tl::optional compression, tl::optional format, tl::optional encoding, tl::optional bits_per_sample) { if (!format.has_value()) { throw std::runtime_error( "`format` is required when saving to file object."); } const auto filetype = format.value(); if (filetype == "amr-nb") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); if (num_channels != 1) { throw std::runtime_error( "amr-nb format only supports single channel audio."); } } else if (filetype == "htk") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); if (num_channels != 1) { throw std::runtime_error( "htk format only supports single channel audio."); } } else if (filetype == "gsm") { const auto num_channels = tensor.shape(channels_first ? 0 : 1); if (num_channels != 1) { throw std::runtime_error( "gsm format only supports single channel audio."); } if (sample_rate != 8000) { throw std::runtime_error( "gsm format only supports a sampling rate of 8kHz."); } } const auto signal_info = get_signalinfo(&tensor, sample_rate, filetype, channels_first); const auto encoding_info = get_encodinginfo_for_save( filetype, tensor.dtype(), compression, std::move(encoding), bits_per_sample); AutoReleaseBuffer buffer; SoxFormat sf(sox_open_memstream_write( &buffer.ptr, &buffer.size, &signal_info, &encoding_info, filetype.c_str(), /*oob=*/nullptr)); if (static_cast(sf) == nullptr) { throw std::runtime_error( "Error saving audio file: failed to open memory stream."); } paddleaudio::sox_effects_chain::SoxEffectsChainPyBind chain( /*input_encoding=*/get_tensor_encodinginfo(tensor.dtype()), /*output_encoding=*/sf->encoding); chain.addInputTensor(&tensor, sample_rate, channels_first); chain.addOutputFileObj(sf, &buffer.ptr, &buffer.size, &fileobj); chain.run(); // Closing the sox_format_t is necessary for flushing the last chunk to the // buffer sf.close(); fileobj.attr("write")(py::bytes(buffer.ptr, buffer.size)); } } // namespace paddleaudio } // namespace sox_io ================================================ FILE: audio/paddleaudio/src/pybind/sox/io.h ================================================ // the code is from https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/io.h with modification. #pragma once #include "paddleaudio/src/pybind/sox/utils.h" namespace py = pybind11; namespace paddleaudio { namespace sox_io { auto get_info_file(const std::string &path, const tl::optional &format) -> std::tuple; auto get_info_fileobj(py::object fileobj, const tl::optional &format) -> std::tuple; tl::optional> load_audio_fileobj( py::object fileobj, const tl::optional& frame_offset, const tl::optional& num_frames, tl::optional normalize, tl::optional channels_first, const tl::optional& format); void save_audio_fileobj( py::object fileobj, py::array tensor, int64_t sample_rate, bool channels_first, tl::optional compression, tl::optional format, tl::optional encoding, tl::optional bits_per_sample); auto get_effects(const tl::optional& frame_offset, const tl::optional& num_frames) -> std::vector>; tl::optional> load_audio_file( const std::string& path, const tl::optional& frame_offset, const tl::optional& num_frames, tl::optional normalize, tl::optional channels_first, const tl::optional& format); void save_audio_file(const std::string& path, py::array tensor, int64_t sample_rate, bool channels_first, tl::optional compression, tl::optional format, tl::optional encoding, tl::optional bits_per_sample); } // namespace paddleaudio } // namespace sox_io ================================================ FILE: audio/paddleaudio/src/pybind/sox/types.cpp ================================================ //code is from: https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/types.cpp #include "paddleaudio/src/pybind/sox/types.h" #include #include namespace paddleaudio { namespace sox_utils { Format get_format_from_string(const std::string& format) { if (format == "wav") return Format::WAV; if (format == "mp3") return Format::MP3; if (format == "flac") return Format::FLAC; if (format == "ogg" || format == "vorbis") return Format::VORBIS; if (format == "amr-nb") return Format::AMR_NB; if (format == "amr-wb") return Format::AMR_WB; if (format == "amb") return Format::AMB; if (format == "sph") return Format::SPHERE; if (format == "htk") return Format::HTK; if (format == "gsm") return Format::GSM; std::ostringstream stream; stream << "Internal Error: unexpected format value: " << format; throw std::runtime_error(stream.str()); } std::string to_string(Encoding v) { switch (v) { case Encoding::UNKNOWN: return "UNKNOWN"; case Encoding::PCM_SIGNED: return "PCM_S"; case Encoding::PCM_UNSIGNED: return "PCM_U"; case Encoding::PCM_FLOAT: return "PCM_F"; case Encoding::FLAC: return "FLAC"; case Encoding::ULAW: return "ULAW"; case Encoding::ALAW: return "ALAW"; case Encoding::MP3: return "MP3"; case Encoding::VORBIS: return "VORBIS"; case Encoding::AMR_WB: return "AMR_WB"; case Encoding::AMR_NB: return "AMR_NB"; case Encoding::OPUS: return "OPUS"; default: throw std::runtime_error("Internal Error: unexpected encoding."); } } Encoding get_encoding_from_option(const tl::optional encoding) { if (!encoding.has_value()) return Encoding::NOT_PROVIDED; std::string v = encoding.value(); if (v == "PCM_S") return Encoding::PCM_SIGNED; if (v == "PCM_U") return Encoding::PCM_UNSIGNED; if (v == "PCM_F") return Encoding::PCM_FLOAT; if (v == "ULAW") return Encoding::ULAW; if (v == "ALAW") return Encoding::ALAW; std::ostringstream stream; stream << "Internal Error: unexpected encoding value: " << v; throw std::runtime_error(stream.str()); } BitDepth get_bit_depth_from_option(const tl::optional bit_depth) { if (!bit_depth.has_value()) return BitDepth::NOT_PROVIDED; int64_t v = bit_depth.value(); switch (v) { case 8: return BitDepth::B8; case 16: return BitDepth::B16; case 24: return BitDepth::B24; case 32: return BitDepth::B32; case 64: return BitDepth::B64; default: { std::ostringstream s; s << "Internal Error: unexpected bit depth value: " << v; throw std::runtime_error(s.str()); } } } std::string get_encoding(sox_encoding_t encoding) { switch (encoding) { case SOX_ENCODING_UNKNOWN: return "UNKNOWN"; case SOX_ENCODING_SIGN2: return "PCM_S"; case SOX_ENCODING_UNSIGNED: return "PCM_U"; case SOX_ENCODING_FLOAT: return "PCM_F"; case SOX_ENCODING_FLAC: return "FLAC"; case SOX_ENCODING_ULAW: return "ULAW"; case SOX_ENCODING_ALAW: return "ALAW"; case SOX_ENCODING_MP3: return "MP3"; case SOX_ENCODING_VORBIS: return "VORBIS"; case SOX_ENCODING_AMR_WB: return "AMR_WB"; case SOX_ENCODING_AMR_NB: return "AMR_NB"; case SOX_ENCODING_OPUS: return "OPUS"; case SOX_ENCODING_GSM: return "GSM"; default: return "UNKNOWN"; } } } // namespace sox_utils } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/sox/types.h ================================================ //code is from: https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/types.h #pragma once #include #include "paddleaudio/src/optional/optional.hpp" namespace paddleaudio { namespace sox_utils { enum class Format { WAV, MP3, FLAC, VORBIS, AMR_NB, AMR_WB, AMB, SPHERE, GSM, HTK, }; Format get_format_from_string(const std::string& format); enum class Encoding { NOT_PROVIDED, UNKNOWN, PCM_SIGNED, PCM_UNSIGNED, PCM_FLOAT, FLAC, ULAW, ALAW, MP3, VORBIS, AMR_WB, AMR_NB, OPUS, }; std::string to_string(Encoding v); Encoding get_encoding_from_option(const tl::optional encoding); enum class BitDepth : unsigned { NOT_PROVIDED = 0, B8 = 8, B16 = 16, B24 = 24, B32 = 32, B64 = 64, }; BitDepth get_bit_depth_from_option(const tl::optional bit_depth); std::string get_encoding(sox_encoding_t encoding); } // namespace sox_utils } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/src/pybind/sox/utils.cpp ================================================ //code is from: https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/utils.cpp with modification. #include #include "paddleaudio/src/pybind/sox/utils.h" #include "paddleaudio/src/pybind/sox/types.h" #include namespace paddleaudio { namespace sox_utils { auto read_fileobj(py::object *fileobj, const uint64_t size, char *buffer) -> uint64_t { uint64_t num_read = 0; while (num_read < size) { auto request = size - num_read; auto chunk = static_cast( static_cast(fileobj->attr("read")(request))); auto chunk_len = chunk.length(); if (chunk_len == 0) { break; } if (chunk_len > request) { std::ostringstream message; message << "Requested up to " << request << " bytes but, " << "received " << chunk_len << " bytes. " << "The given object does not confirm to read protocol of file " "object."; throw std::runtime_error(message.str()); } memcpy(buffer, chunk.data(), chunk_len); buffer += chunk_len; num_read += chunk_len; } return num_read; } void set_seed(const int64_t seed) { sox_get_globals()->ranqd1 = static_cast(seed); } void set_verbosity(const int64_t verbosity) { sox_get_globals()->verbosity = static_cast(verbosity); } void set_use_threads(const bool use_threads) { sox_get_globals()->use_threads = static_cast(use_threads); } void set_buffer_size(const int64_t buffer_size) { sox_get_globals()->bufsiz = static_cast(buffer_size); } int64_t get_buffer_size() { return sox_get_globals()->bufsiz; } std::vector> list_effects() { std::vector> effects; for (const sox_effect_fn_t* fns = sox_get_effect_fns(); *fns; ++fns) { const sox_effect_handler_t* handler = (*fns)(); if (handler && handler->name) { if (UNSUPPORTED_EFFECTS.find(handler->name) == UNSUPPORTED_EFFECTS.end()) { effects.emplace_back(std::vector{ handler->name, handler->usage ? std::string(handler->usage) : std::string("")}); } } } return effects; } std::vector list_write_formats() { std::vector formats; for (const sox_format_tab_t* fns = sox_get_format_fns(); fns->fn; ++fns) { const sox_format_handler_t* handler = fns->fn(); for (const char* const* names = handler->names; *names; ++names) { if (!strchr(*names, '/') && handler->write) formats.emplace_back(*names); } } return formats; } std::vector list_read_formats() { std::vector formats; for (const sox_format_tab_t* fns = sox_get_format_fns(); fns->fn; ++fns) { const sox_format_handler_t* handler = fns->fn(); for (const char* const* names = handler->names; *names; ++names) { if (!strchr(*names, '/') && handler->read) formats.emplace_back(*names); } } return formats; } SoxFormat::SoxFormat(sox_format_t* fd) noexcept : fd_(fd) {} SoxFormat::~SoxFormat() { close(); } sox_format_t* SoxFormat::operator->() const noexcept { return fd_; } SoxFormat::operator sox_format_t*() const noexcept { return fd_; } void SoxFormat::close() { if (fd_ != nullptr) { sox_close(fd_); fd_ = nullptr; } } void validate_input_file(const SoxFormat& sf, const std::string& path) { if (static_cast(sf) == nullptr) { throw std::runtime_error( "Error loading audio file: failed to open file " + path); } if (sf->encoding.encoding == SOX_ENCODING_UNKNOWN) { throw std::runtime_error("Error loading audio file: unknown encoding."); } } void validate_input_memfile(const SoxFormat &sf) { return validate_input_file(sf, ""); } void validate_input_tensor(const py::array tensor) { if (tensor.ndim() != 2) { throw std::runtime_error("Input tensor has to be 2D."); } char dtype = tensor.dtype().char_(); bool flag = (dtype == 'f') || (dtype == 'd') || (dtype == 'l') || (dtype == 'i'); if (flag == false) { throw std::runtime_error( "Input tensor has to be one of float32, int32, int16 or uint8 type."); } } py::dtype get_dtype( const sox_encoding_t encoding, const unsigned precision) { switch (encoding) { case SOX_ENCODING_UNSIGNED: // 8-bit PCM WAV return py::dtype('u1'); case SOX_ENCODING_SIGN2: // 16-bit, 24-bit, or 32-bit PCM WAV switch (precision) { case 16: return py::dtype("i2"); case 24: // Cast 24-bit to 32-bit. case 32: return py::dtype('i'); default: throw std::runtime_error( "Only 16, 24, and 32 bits are supported for signed PCM."); } default: // default to float32 for the other formats, including // 32-bit floating-point WAV, // MP3, // FLAC, // VORBIS etc... return py::dtype("f"); } } py::array convert_to_tensor( sox_sample_t* buffer, const int32_t num_samples, const int32_t num_channels, const py::dtype dtype, const bool normalize, const bool channels_first) { // todo refactor later(SGoat) py::array t; uint64_t dummy = 0; SOX_SAMPLE_LOCALS; int32_t num_rows = num_samples / num_channels; if (normalize || dtype.char_() == 'f') { t = py::array(dtype, {num_rows, num_channels}); auto ptr = (float*)t.mutable_data(0, 0); for (int32_t i = 0; i < num_samples; ++i) { ptr[i] = SOX_SAMPLE_TO_FLOAT_32BIT(buffer[i], dummy); } if (channels_first) { py::array t2 = py::array(dtype, {num_channels, num_rows}); for (int32_t row_idx = 0; row_idx < num_channels; ++row_idx) { for (int32_t col_idx = 0; col_idx < num_rows; ++col_idx) *(float*)t2.mutable_data(row_idx, col_idx) = *(float*)t.data(col_idx, row_idx); } return t2; } } else if (dtype.char_() == 'i') { t = py::array(dtype, {num_rows, num_channels}); auto ptr = (int*)t.mutable_data(0, 0); for (int32_t i = 0; i < num_samples; ++i) { ptr[i] = buffer[i]; } if (channels_first) { py::array t2 = py::array(dtype, {num_channels, num_rows}); for (int32_t row_idx = 0; row_idx < num_channels; ++row_idx) { for (int32_t col_idx = 0; col_idx < num_rows; ++col_idx) *(int*)t2.mutable_data(row_idx, col_idx) = *(int*)t.data(col_idx, row_idx); } return t2; } } else if (dtype.char_() == 'h') { // int16 t = py::array(dtype, {num_rows, num_channels}); auto ptr = (int16_t*)t.mutable_data(0, 0); for (int32_t i = 0; i < num_samples; ++i) { ptr[i] = SOX_SAMPLE_TO_SIGNED_16BIT(buffer[i], dummy); } if (channels_first) { py::array t2 = py::array(dtype, {num_channels, num_rows}); for (int32_t row_idx = 0; row_idx < num_channels; ++row_idx) { for (int32_t col_idx = 0; col_idx < num_rows; ++col_idx) *(int16_t*)t2.mutable_data(row_idx, col_idx) = *(int16_t*)t.data(col_idx, row_idx); } return t2; } } else if (dtype.char_() == 'b') { //t = torch::empty({num_samples / num_channels, num_channels}, torch::kUInt8); t = py::array(dtype, {num_rows, num_channels}); auto ptr = (uint8_t*)t.mutable_data(0,0); for (int32_t i = 0; i < num_samples; ++i) { ptr[i] = SOX_SAMPLE_TO_UNSIGNED_8BIT(buffer[i], dummy); } if (channels_first) { py::array t2 = py::array(dtype, {num_channels, num_rows}); for (int32_t row_idx = 0; row_idx < num_channels; ++row_idx) { for (int32_t col_idx = 0; col_idx < num_rows; ++col_idx) *(uint8_t*)t2.mutable_data(row_idx, col_idx) = *(uint8_t*)t.data(col_idx, row_idx); } return t2; } } else { throw std::runtime_error("Unsupported dtype."); } return t; } const std::string get_filetype(const std::string path) { std::string ext = path.substr(path.find_last_of(".") + 1); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); return ext; } namespace { std::tuple get_save_encoding_for_wav( const std::string format, py::dtype dtype, const Encoding& encoding, const BitDepth& bits_per_sample) { switch (encoding) { case Encoding::NOT_PROVIDED: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: switch (dtype.num()) { case 11: // float32 numpy dtype num return std::make_tuple<>(SOX_ENCODING_FLOAT, 32); case 5: // int numpy dtype num return std::make_tuple<>(SOX_ENCODING_SIGN2, 32); case 3: // int16 numpy return std::make_tuple<>(SOX_ENCODING_SIGN2, 16); case 1: // byte numpy return std::make_tuple<>(SOX_ENCODING_UNSIGNED, 8); default: throw std::runtime_error("Internal Error: Unexpected dtype."); } case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_UNSIGNED, 8); default: return std::make_tuple<>( SOX_ENCODING_SIGN2, static_cast(bits_per_sample)); } case Encoding::PCM_SIGNED: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: return std::make_tuple<>(SOX_ENCODING_SIGN2, 32); case BitDepth::B8: throw std::runtime_error( format + " does not support 8-bit signed PCM encoding."); default: return std::make_tuple<>( SOX_ENCODING_SIGN2, static_cast(bits_per_sample)); } case Encoding::PCM_UNSIGNED: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_UNSIGNED, 8); default: throw std::runtime_error( format + " only supports 8-bit for unsigned PCM encoding."); } case Encoding::PCM_FLOAT: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: case BitDepth::B32: return std::make_tuple<>(SOX_ENCODING_FLOAT, 32); case BitDepth::B64: return std::make_tuple<>(SOX_ENCODING_FLOAT, 64); default: throw std::runtime_error( format + " only supports 32-bit or 64-bit for floating-point PCM encoding."); } case Encoding::ULAW: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_ULAW, 8); default: throw std::runtime_error( format + " only supports 8-bit for mu-law encoding."); } case Encoding::ALAW: switch (bits_per_sample) { case BitDepth::NOT_PROVIDED: case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_ALAW, 8); default: throw std::runtime_error( format + " only supports 8-bit for a-law encoding."); } default: throw std::runtime_error( format + " does not support encoding: " + to_string(encoding)); } } std::tuple get_save_encoding( const std::string& format, const py::dtype dtype, const tl::optional encoding, const tl::optional bits_per_sample) { const Format fmt = get_format_from_string(format); const Encoding enc = get_encoding_from_option(encoding); const BitDepth bps = get_bit_depth_from_option(bits_per_sample); switch (fmt) { case Format::WAV: case Format::AMB: return get_save_encoding_for_wav(format, dtype, enc, bps); case Format::MP3: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("mp3 does not support `encoding` option."); if (bps != BitDepth::NOT_PROVIDED) throw std::runtime_error( "mp3 does not support `bits_per_sample` option."); return std::make_tuple<>(SOX_ENCODING_MP3, 16); case Format::HTK: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("htk does not support `encoding` option."); if (bps != BitDepth::NOT_PROVIDED) throw std::runtime_error( "htk does not support `bits_per_sample` option."); return std::make_tuple<>(SOX_ENCODING_SIGN2, 16); case Format::VORBIS: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("vorbis does not support `encoding` option."); if (bps != BitDepth::NOT_PROVIDED) throw std::runtime_error( "vorbis does not support `bits_per_sample` option."); return std::make_tuple<>(SOX_ENCODING_VORBIS, 16); case Format::AMR_NB: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("amr-nb does not support `encoding` option."); if (bps != BitDepth::NOT_PROVIDED) throw std::runtime_error( "amr-nb does not support `bits_per_sample` option."); return std::make_tuple<>(SOX_ENCODING_AMR_NB, 16); case Format::FLAC: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("flac does not support `encoding` option."); switch (bps) { case BitDepth::B32: case BitDepth::B64: throw std::runtime_error( "flac does not support `bits_per_sample` larger than 24."); default: return std::make_tuple<>( SOX_ENCODING_FLAC, static_cast(bps)); } case Format::SPHERE: switch (enc) { case Encoding::NOT_PROVIDED: case Encoding::PCM_SIGNED: switch (bps) { case BitDepth::NOT_PROVIDED: return std::make_tuple<>(SOX_ENCODING_SIGN2, 32); default: return std::make_tuple<>( SOX_ENCODING_SIGN2, static_cast(bps)); } case Encoding::PCM_UNSIGNED: throw std::runtime_error( "sph does not support unsigned integer PCM."); case Encoding::PCM_FLOAT: throw std::runtime_error("sph does not support floating point PCM."); case Encoding::ULAW: switch (bps) { case BitDepth::NOT_PROVIDED: case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_ULAW, 8); default: throw std::runtime_error( "sph only supports 8-bit for mu-law encoding."); } case Encoding::ALAW: switch (bps) { case BitDepth::NOT_PROVIDED: case BitDepth::B8: return std::make_tuple<>(SOX_ENCODING_ALAW, 8); default: return std::make_tuple<>( SOX_ENCODING_ALAW, static_cast(bps)); } default: throw std::runtime_error( "sph does not support encoding: " + encoding.value()); } case Format::GSM: if (enc != Encoding::NOT_PROVIDED) throw std::runtime_error("gsm does not support `encoding` option."); if (bps != BitDepth::NOT_PROVIDED) throw std::runtime_error( "gsm does not support `bits_per_sample` option."); return std::make_tuple<>(SOX_ENCODING_GSM, 16); default: throw std::runtime_error("Unsupported format: " + format); } } unsigned get_precision(const std::string filetype, py::dtype dtype) { if (filetype == "mp3") return SOX_UNSPEC; if (filetype == "flac") return 24; if (filetype == "ogg" || filetype == "vorbis") return SOX_UNSPEC; if (filetype == "wav" || filetype == "amb") { switch (dtype.num()) { case 1: // byte in numpy dtype num return 8; case 3: // short, in numpy dtype num return 16; case 5: // int, numpy dtype return 32; case 11: // float, numpy dtype return 32; default: throw std::runtime_error("Unsupported dtype."); } } if (filetype == "sph") return 32; if (filetype == "amr-nb") { return 16; } if (filetype == "gsm") { return 16; } if (filetype == "htk") { return 16; } throw std::runtime_error("Unsupported file type: " + filetype); } } // namespace sox_signalinfo_t get_signalinfo( const py::array* waveform, const int64_t sample_rate, const std::string filetype, const bool channels_first) { return sox_signalinfo_t{ /*rate=*/static_cast(sample_rate), /*channels=*/ static_cast(waveform->shape(channels_first ? 0 : 1)), /*precision=*/get_precision(filetype, waveform->dtype()), /*length=*/static_cast(waveform->size())}; } sox_encodinginfo_t get_tensor_encodinginfo(py::dtype dtype) { sox_encoding_t encoding = [&]() { switch (dtype.num()) { case 1: // byte return SOX_ENCODING_UNSIGNED; case 3: // short return SOX_ENCODING_SIGN2; case 5: // int32 return SOX_ENCODING_SIGN2; case 11: // float return SOX_ENCODING_FLOAT; default: throw std::runtime_error("Unsupported dtype."); } }(); unsigned bits_per_sample = [&]() { switch (dtype.num()) { case 1: // byte return 8; case 3: //short return 16; case 5: // int32 return 32; case 11: // float return 32; default: throw std::runtime_error("Unsupported dtype."); } }(); return sox_encodinginfo_t{ /*encoding=*/encoding, /*bits_per_sample=*/bits_per_sample, /*compression=*/HUGE_VAL, /*reverse_bytes=*/sox_option_default, /*reverse_nibbles=*/sox_option_default, /*reverse_bits=*/sox_option_default, /*opposite_endian=*/sox_false}; } sox_encodinginfo_t get_encodinginfo_for_save( const std::string& format, const py::dtype dtype, const tl::optional compression, const tl::optional encoding, const tl::optional bits_per_sample) { auto enc = get_save_encoding(format, dtype, encoding, bits_per_sample); return sox_encodinginfo_t{ /*encoding=*/std::get<0>(enc), /*bits_per_sample=*/std::get<1>(enc), /*compression=*/compression.value_or(HUGE_VAL), /*reverse_bytes=*/sox_option_default, /*reverse_nibbles=*/sox_option_default, /*reverse_bits=*/sox_option_default, /*opposite_endian=*/sox_false}; } } // namespace paddleaudio } // namespace sox_utils ================================================ FILE: audio/paddleaudio/src/pybind/sox/utils.h ================================================ //code is from: https://github.com/pytorch/audio/blob/main/torchaudio/csrc/sox/utils.h with modification. #pragma once #include #include #include #include "paddleaudio/src/optional/optional.hpp" namespace py = pybind11; namespace paddleaudio { namespace sox_utils { auto read_fileobj(py::object *fileobj, uint64_t size, char *buffer) -> uint64_t; void set_seed(const int64_t seed); void set_verbosity(const int64_t verbosity); void set_use_threads(const bool use_threads); void set_buffer_size(const int64_t buffer_size); int64_t get_buffer_size(); std::vector> list_effects(); std::vector list_read_formats(); std::vector list_write_formats(); //////////////////////////////////////////////////////////////////////////////// // Utilities for sox_io / sox_effects implementations //////////////////////////////////////////////////////////////////////////////// const std::unordered_set UNSUPPORTED_EFFECTS = {"input", "output", "spectrogram", "noiseprof", "noisered", "splice"}; /// helper class to automatically close sox_format_t* struct SoxFormat { explicit SoxFormat(sox_format_t* fd) noexcept; SoxFormat(const SoxFormat& other) = delete; SoxFormat(SoxFormat&& other) = delete; SoxFormat& operator=(const SoxFormat& other) = delete; SoxFormat& operator=(SoxFormat&& other) = delete; ~SoxFormat(); sox_format_t* operator->() const noexcept; operator sox_format_t*() const noexcept; void close(); private: sox_format_t* fd_; }; /// /// Verify that input Tensor is 2D, CPU and either uin8, int16, int32 or float32 void validate_input_tensor(const py::array); void validate_input_file(const SoxFormat& sf, const std::string& path); void validate_input_memfile(const SoxFormat &sf); /// /// Get target dtype for the given encoding and precision. py::dtype get_dtype( const sox_encoding_t encoding, const unsigned precision); /// /// Convert sox_sample_t buffer to uint8/int16/int32/float32 Tensor /// NOTE: This function might modify the values in the input buffer to /// reduce the number of memory copy. /// @param buffer Pointer to buffer that contains audio data. /// @param num_samples The number of samples to read. /// @param num_channels The number of channels. Used to reshape the resulting /// Tensor. /// @param dtype Target dtype. Determines the output dtype and value range in /// conjunction with normalization. /// @param normalize Perform normalization. Only effective when dtype is not /// kFloat32. When effective, the output tensor is kFloat32 type and value range /// is [-1.0, 1.0] /// @param channels_first When True, output Tensor has shape of [num_channels, /// num_frames]. py::array convert_to_tensor( sox_sample_t* buffer, const int32_t num_samples, const int32_t num_channels, const py::dtype dtype, const bool normalize, const bool channels_first); /// Extract extension from file path const std::string get_filetype(const std::string path); /// Get sox_signalinfo_t for passing a py::array object. sox_signalinfo_t get_signalinfo( const py::array* waveform, const int64_t sample_rate, const std::string filetype, const bool channels_first); /// Get sox_encodinginfo_t for Tensor I/O sox_encodinginfo_t get_tensor_encodinginfo(const py::dtype dtype); /// Get sox_encodinginfo_t for saving to file/file object sox_encodinginfo_t get_encodinginfo_for_save( const std::string& format, const py::dtype dtype, const tl::optional compression, const tl::optional encoding, const tl::optional bits_per_sample); } // namespace paddleaudio } // namespace sox_utils ================================================ FILE: audio/paddleaudio/src/utils.cpp ================================================ // this is from: https://github.com/pytorch/audio/blob/main/torchaudio/csrc/utils.cpp with modification. namespace paddleaudio { namespace { bool is_sox_available() { #ifdef INCLUDE_SOX return true; #else return false; #endif } bool is_kaldi_available() { #ifdef INCLUDE_KALDI return true; #else return false; #endif } // It tells whether paddleaudio was compiled with ffmpeg // not the runtime availability. bool is_ffmpeg_available() { #ifdef USE_FFMPEG return true; #else return false; #endif } } // namespace } // namespace paddleaudio ================================================ FILE: audio/paddleaudio/third_party/.gitignore ================================================ archives/ install/ ================================================ FILE: audio/paddleaudio/third_party/CMakeLists.txt ================================================ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") ################################################################################ # sox ################################################################################ if (BUILD_SOX) add_subdirectory(sox) endif() ################################################################################ # kaldi ################################################################################ if (BUILD_KALDI) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(kaldi-native-fbank/csrc) endif() ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/CMakeLists.txt ================================================ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../) add_library(kaldi-native-fbank-core feature-fbank.cc feature-functions.cc feature-window.cc fftsg.c log.cc mel-computations.cc rfft.cc ) # We are using std::call_once() in log.h,which requires us to link with -pthread if(NOT WIN32) target_link_libraries(kaldi-native-fbank-core -pthread) endif() if(KNF_HAVE_EXECINFO_H) target_compile_definitions(kaldi-native-fbank-core PRIVATE KNF_HAVE_EXECINFO_H=1) endif() if(KNF_HAVE_CXXABI_H) target_compile_definitions(kaldi-native-fbank-core PRIVATE KNF_HAVE_CXXABI_H=1) endif() ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-fbank.cc ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/feature-fbank.cc // #include "kaldi-native-fbank/csrc/feature-fbank.h" #include #include "kaldi-native-fbank/csrc/feature-functions.h" namespace knf { static void Sqrt(float *in_out, int32_t n) { for (int32_t i = 0; i != n; ++i) { in_out[i] = std::sqrt(in_out[i]); } } std::ostream &operator<<(std::ostream &os, const FbankOptions &opts) { os << opts.ToString(); return os; } FbankComputer::FbankComputer(const FbankOptions &opts) : opts_(opts), rfft_(opts.frame_opts.PaddedWindowSize()) { if (opts.energy_floor > 0.0f) { log_energy_floor_ = logf(opts.energy_floor); } // We'll definitely need the filterbanks info for VTLN warping factor 1.0. // [note: this call caches it.] GetMelBanks(1.0f); } FbankComputer::~FbankComputer() { for (auto iter = mel_banks_.begin(); iter != mel_banks_.end(); ++iter) delete iter->second; } const MelBanks *FbankComputer::GetMelBanks(float vtln_warp) { MelBanks *this_mel_banks = nullptr; // std::map::iterator iter = mel_banks_.find(vtln_warp); auto iter = mel_banks_.find(vtln_warp); if (iter == mel_banks_.end()) { this_mel_banks = new MelBanks(opts_.mel_opts, opts_.frame_opts, vtln_warp); mel_banks_[vtln_warp] = this_mel_banks; } else { this_mel_banks = iter->second; } return this_mel_banks; } void FbankComputer::Compute(float signal_raw_log_energy, float vtln_warp, std::vector *signal_frame, float *feature) { const MelBanks &mel_banks = *(GetMelBanks(vtln_warp)); KNF_CHECK_EQ(signal_frame->size(), opts_.frame_opts.PaddedWindowSize()); // Compute energy after window function (not the raw one). if (opts_.use_energy && !opts_.raw_energy) { signal_raw_log_energy = std::log( std::max(InnerProduct(signal_frame->data(), signal_frame->data(), signal_frame->size()), std::numeric_limits::epsilon())); } rfft_.Compute(signal_frame->data()); // signal_frame is modified in-place ComputePowerSpectrum(signal_frame); // Use magnitude instead of power if requested. if (!opts_.use_power) { Sqrt(signal_frame->data(), signal_frame->size() / 2 + 1); } int32_t mel_offset = ((opts_.use_energy && !opts_.htk_compat) ? 1 : 0); // Its length is opts_.mel_opts.num_bins float *mel_energies = feature + mel_offset; // Sum with mel filter banks over the power spectrum mel_banks.Compute(signal_frame->data(), mel_energies); if (opts_.use_log_fbank) { // Avoid log of zero (which should be prevented anyway by dithering). for (int32_t i = 0; i != opts_.mel_opts.num_bins; ++i) { auto t = std::max(mel_energies[i], std::numeric_limits::epsilon()); mel_energies[i] = std::log(t); } } // Copy energy as first value (or the last, if htk_compat == true). if (opts_.use_energy) { if (opts_.energy_floor > 0.0 && signal_raw_log_energy < log_energy_floor_) { signal_raw_log_energy = log_energy_floor_; } int32_t energy_index = opts_.htk_compat ? opts_.mel_opts.num_bins : 0; feature[energy_index] = signal_raw_log_energy; } } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-fbank.h ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/feature-fbank.h #ifndef KALDI_NATIVE_FBANK_CSRC_FEATURE_FBANK_H_ #define KALDI_NATIVE_FBANK_CSRC_FEATURE_FBANK_H_ #include #include "kaldi-native-fbank/csrc/feature-window.h" #include "kaldi-native-fbank/csrc/mel-computations.h" #include "kaldi-native-fbank/csrc/rfft.h" namespace knf { struct FbankOptions { FrameExtractionOptions frame_opts; MelBanksOptions mel_opts; // append an extra dimension with energy to the filter banks bool use_energy = false; float energy_floor = 0.0f; // active iff use_energy==true // If true, compute log_energy before preemphasis and windowing // If false, compute log_energy after preemphasis ans windowing bool raw_energy = true; // active iff use_energy==true // If true, put energy last (if using energy) // If false, put energy first bool htk_compat = false; // active iff use_energy==true // if true (default), produce log-filterbank, else linear bool use_log_fbank = true; // if true (default), use power in filterbank // analysis, else magnitude. bool use_power = true; FbankOptions() { mel_opts.num_bins = 23; } std::string ToString() const { std::ostringstream os; os << "frame_opts: \n"; os << frame_opts << "\n"; os << "\n"; os << "mel_opts: \n"; os << mel_opts << "\n"; os << "use_energy: " << use_energy << "\n"; os << "energy_floor: " << energy_floor << "\n"; os << "raw_energy: " << raw_energy << "\n"; os << "htk_compat: " << htk_compat << "\n"; os << "use_log_fbank: " << use_log_fbank << "\n"; os << "use_power: " << use_power << "\n"; return os.str(); } }; std::ostream &operator<<(std::ostream &os, const FbankOptions &opts); class FbankComputer { public: using Options = FbankOptions; explicit FbankComputer(const FbankOptions &opts); ~FbankComputer(); int32_t Dim() const { return opts_.mel_opts.num_bins + (opts_.use_energy ? 1 : 0); } // if true, compute log_energy_pre_window but after dithering and dc removal bool NeedRawLogEnergy() const { return opts_.use_energy && opts_.raw_energy; } const FrameExtractionOptions &GetFrameOptions() const { return opts_.frame_opts; } const FbankOptions &GetOptions() const { return opts_; } /** Function that computes one frame of features from one frame of signal. @param [in] signal_raw_log_energy The log-energy of the frame of the signal prior to windowing and pre-emphasis, or log(numeric_limits::min()), whichever is greater. Must be ignored by this function if this class returns false from this->NeedsRawLogEnergy(). @param [in] vtln_warp The VTLN warping factor that the user wants to be applied when computing features for this utterance. Will normally be 1.0, meaning no warping is to be done. The value will be ignored for feature types that don't support VLTN, such as spectrogram features. @param [in] signal_frame One frame of the signal, as extracted using the function ExtractWindow() using the options returned by this->GetFrameOptions(). The function will use the vector as a workspace, which is why it's a non-const pointer. @param [out] feature Pointer to a vector of size this->Dim(), to which the computed feature will be written. It should be pre-allocated. */ void Compute(float signal_raw_log_energy, float vtln_warp, std::vector *signal_frame, float *feature); private: const MelBanks *GetMelBanks(float vtln_warp); FbankOptions opts_; float log_energy_floor_; std::map mel_banks_; // float is VTLN coefficient. Rfft rfft_; }; } // namespace knf #endif // KALDI_NATIVE_FBANK_CSRC_FEATURE_FBANK_H_ ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-functions.cc ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/feature-functions.cc #include "kaldi-native-fbank/csrc/feature-functions.h" #include #include namespace knf { void ComputePowerSpectrum(std::vector *complex_fft) { int32_t dim = complex_fft->size(); // now we have in complex_fft, first half of complex spectrum // it's stored as [real0, realN/2, real1, im1, real2, im2, ...] float *p = complex_fft->data(); int32_t half_dim = dim / 2; float first_energy = p[0] * p[0]; float last_energy = p[1] * p[1]; // handle this special case for (int32_t i = 1; i < half_dim; ++i) { float real = p[i * 2]; float im = p[i * 2 + 1]; p[i] = real * real + im * im; } p[0] = first_energy; p[half_dim] = last_energy; // Will actually never be used, and anyway // if the signal has been bandlimited sensibly this should be zero. } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-functions.h ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/feature-functions.h #ifndef KALDI_NATIVE_FBANK_CSRC_FEATURE_FUNCTIONS_H #define KALDI_NATIVE_FBANK_CSRC_FEATURE_FUNCTIONS_H #include namespace knf { // ComputePowerSpectrum converts a complex FFT (as produced by the FFT // functions in csrc/rfft.h), and converts it into // a power spectrum. If the complex FFT is a vector of size n (representing // half of the complex FFT of a real signal of size n, as described there), // this function computes in the first (n/2) + 1 elements of it, the // energies of the fft bins from zero to the Nyquist frequency. Contents of the // remaining (n/2) - 1 elements are undefined at output. void ComputePowerSpectrum(std::vector *complex_fft); } // namespace knf #endif // KALDI_NATIVE_FBANK_CSRC_FEATURE_FUNCTIONS_H ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-window.cc ================================================ // kaldi-native-fbank/csrc/feature-window.cc // // Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) // This file is copied/modified from kaldi/src/feat/feature-window.cc #include "kaldi-native-fbank/csrc/feature-window.h" #include #include #ifndef M_2PI #define M_2PI 6.283185307179586476925286766559005 #endif namespace knf { std::ostream &operator<<(std::ostream &os, const FrameExtractionOptions &opts) { os << opts.ToString(); return os; } FeatureWindowFunction::FeatureWindowFunction(const FrameExtractionOptions &opts) : window_(opts.WindowSize()) { int32_t frame_length = opts.WindowSize(); KNF_CHECK_GT(frame_length, 0); float *window_data = window_.data(); double a = M_2PI / (frame_length - 1); for (int32_t i = 0; i < frame_length; i++) { double i_fl = static_cast(i); if (opts.window_type == "hanning") { window_data[i] = 0.5 - 0.5 * cos(a * i_fl); } else if (opts.window_type == "sine") { // when you are checking ws wikipedia, please // note that 0.5 * a = M_PI/(frame_length-1) window_data[i] = sin(0.5 * a * i_fl); } else if (opts.window_type == "hamming") { window_data[i] = 0.54 - 0.46 * cos(a * i_fl); } else if (opts.window_type == "povey") { // like hamming but goes to zero at edges. window_data[i] = pow(0.5 - 0.5 * cos(a * i_fl), 0.85); } else if (opts.window_type == "rectangular") { window_data[i] = 1.0; } else if (opts.window_type == "blackman") { window_data[i] = opts.blackman_coeff - 0.5 * cos(a * i_fl) + (0.5 - opts.blackman_coeff) * cos(2 * a * i_fl); } else { KNF_LOG(FATAL) << "Invalid window type " << opts.window_type; } } } void FeatureWindowFunction::Apply(float *wave) const { int32_t window_size = window_.size(); const float *p = window_.data(); for (int32_t k = 0; k != window_size; ++k) { wave[k] *= p[k]; } } int64_t FirstSampleOfFrame(int32_t frame, const FrameExtractionOptions &opts) { int64_t frame_shift = opts.WindowShift(); if (opts.snip_edges) { return frame * frame_shift; } else { int64_t midpoint_of_frame = frame_shift * frame + frame_shift / 2, beginning_of_frame = midpoint_of_frame - opts.WindowSize() / 2; return beginning_of_frame; } } int32_t NumFrames(int64_t num_samples, const FrameExtractionOptions &opts, bool flush /*= true*/) { int64_t frame_shift = opts.WindowShift(); int64_t frame_length = opts.WindowSize(); if (opts.snip_edges) { // with --snip-edges=true (the default), we use a HTK-like approach to // determining the number of frames-- all frames have to fit completely into // the waveform, and the first frame begins at sample zero. if (num_samples < frame_length) return 0; else return (1 + ((num_samples - frame_length) / frame_shift)); // You can understand the expression above as follows: 'num_samples - // frame_length' is how much room we have to shift the frame within the // waveform; 'frame_shift' is how much we shift it each time; and the ratio // is how many times we can shift it (integer arithmetic rounds down). } else { // if --snip-edges=false, the number of frames is determined by rounding the // (file-length / frame-shift) to the nearest integer. The point of this // formula is to make the number of frames an obvious and predictable // function of the frame shift and signal length, which makes many // segmentation-related questions simpler. // // Because integer division in C++ rounds toward zero, we add (half the // frame-shift minus epsilon) before dividing, to have the effect of // rounding towards the closest integer. int32_t num_frames = (num_samples + (frame_shift / 2)) / frame_shift; if (flush) return num_frames; // note: 'end' always means the last plus one, i.e. one past the last. int64_t end_sample_of_last_frame = FirstSampleOfFrame(num_frames - 1, opts) + frame_length; // the following code is optimized more for clarity than efficiency. // If flush == false, we can't output frames that extend past the end // of the signal. while (num_frames > 0 && end_sample_of_last_frame > num_samples) { num_frames--; end_sample_of_last_frame -= frame_shift; } return num_frames; } } void ExtractWindow(int64_t sample_offset, const std::vector &wave, int32_t f, const FrameExtractionOptions &opts, const FeatureWindowFunction &window_function, std::vector *window, float *log_energy_pre_window /*= nullptr*/) { KNF_CHECK(sample_offset >= 0 && wave.size() != 0); int32_t frame_length = opts.WindowSize(); int32_t frame_length_padded = opts.PaddedWindowSize(); int64_t num_samples = sample_offset + wave.size(); int64_t start_sample = FirstSampleOfFrame(f, opts); int64_t end_sample = start_sample + frame_length; if (opts.snip_edges) { KNF_CHECK(start_sample >= sample_offset && end_sample <= num_samples); } else { KNF_CHECK(sample_offset == 0 || start_sample >= sample_offset); } if (window->size() != frame_length_padded) { window->resize(frame_length_padded); } // wave_start and wave_end are start and end indexes into 'wave', for the // piece of wave that we're trying to extract. int32_t wave_start = int32_t(start_sample - sample_offset); int32_t wave_end = wave_start + frame_length; if (wave_start >= 0 && wave_end <= wave.size()) { // the normal case-- no edge effects to consider. std::copy(wave.begin() + wave_start, wave.begin() + wave_start + frame_length, window->data()); } else { // Deal with any end effects by reflection, if needed. This code will only // be reached for about two frames per utterance, so we don't concern // ourselves excessively with efficiency. int32_t wave_dim = wave.size(); for (int32_t s = 0; s < frame_length; ++s) { int32_t s_in_wave = s + wave_start; while (s_in_wave < 0 || s_in_wave >= wave_dim) { // reflect around the beginning or end of the wave. // e.g. -1 -> 0, -2 -> 1. // dim -> dim - 1, dim + 1 -> dim - 2. // the code supports repeated reflections, although this // would only be needed in pathological cases. if (s_in_wave < 0) s_in_wave = -s_in_wave - 1; else s_in_wave = 2 * wave_dim - 1 - s_in_wave; } (*window)[s] = wave[s_in_wave]; } } ProcessWindow(opts, window_function, window->data(), log_energy_pre_window); } static void RemoveDcOffset(float *d, int32_t n) { float sum = 0; for (int32_t i = 0; i != n; ++i) { sum += d[i]; } float mean = sum / n; for (int32_t i = 0; i != n; ++i) { d[i] -= mean; } } float InnerProduct(const float *a, const float *b, int32_t n) { float sum = 0; for (int32_t i = 0; i != n; ++i) { sum += a[i] * b[i]; } return sum; } static void Preemphasize(float *d, int32_t n, float preemph_coeff) { if (preemph_coeff == 0.0) { return; } KNF_CHECK(preemph_coeff >= 0.0 && preemph_coeff <= 1.0); for (int32_t i = n - 1; i > 0; --i) { d[i] -= preemph_coeff * d[i - 1]; } d[0] -= preemph_coeff * d[0]; } void ProcessWindow(const FrameExtractionOptions &opts, const FeatureWindowFunction &window_function, float *window, float *log_energy_pre_window /*= nullptr*/) { int32_t frame_length = opts.WindowSize(); // TODO(fangjun): Remove dither KNF_CHECK_EQ(opts.dither, 0); if (opts.remove_dc_offset) { RemoveDcOffset(window, frame_length); } if (log_energy_pre_window != NULL) { float energy = std::max(InnerProduct(window, window, frame_length), std::numeric_limits::epsilon()); *log_energy_pre_window = std::log(energy); } if (opts.preemph_coeff != 0.0) { Preemphasize(window, frame_length, opts.preemph_coeff); } window_function.Apply(window); } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/feature-window.h ================================================ // kaldi-native-fbank/csrc/feature-window.h // // Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) // This file is copied/modified from kaldi/src/feat/feature-window.h #ifndef KALDI_NATIVE_FEAT_CSRC_FEATURE_WINDOW_H_ #define KALDI_NATIVE_FEAT_CSRC_FEATURE_WINDOW_H_ #include #include #include #include "kaldi-native-fbank/csrc/log.h" namespace knf { inline int32_t RoundUpToNearestPowerOfTwo(int32_t n) { // copied from kaldi/src/base/kaldi-math.cc KNF_CHECK_GT(n, 0); n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; return n + 1; } struct FrameExtractionOptions { float samp_freq = 16000; float frame_shift_ms = 10.0f; // in milliseconds. float frame_length_ms = 25.0f; // in milliseconds. float dither = 1.0f; // Amount of dithering, 0.0 means no dither. float preemph_coeff = 0.97f; // Preemphasis coefficient. bool remove_dc_offset = true; // Subtract mean of wave before FFT. std::string window_type = "povey"; // e.g. Hamming window // May be "hamming", "rectangular", "povey", "hanning", "sine", "blackman" // "povey" is a window I made to be similar to Hamming but to go to zero at // the edges, it's pow((0.5 - 0.5*cos(n/N*2*pi)), 0.85) I just don't think the // Hamming window makes sense as a windowing function. bool round_to_power_of_two = true; float blackman_coeff = 0.42f; bool snip_edges = true; // bool allow_downsample = false; // bool allow_upsample = false; // Used for streaming feature extraction. It indicates the number // of feature frames to keep in the recycling vector. -1 means to // keep all feature frames. int32_t max_feature_vectors = -1; int32_t WindowShift() const { return static_cast(samp_freq * 0.001f * frame_shift_ms); } int32_t WindowSize() const { return static_cast(samp_freq * 0.001f * frame_length_ms); } int32_t PaddedWindowSize() const { return (round_to_power_of_two ? RoundUpToNearestPowerOfTwo(WindowSize()) : WindowSize()); } std::string ToString() const { std::ostringstream os; #define KNF_PRINT(x) os << #x << ": " << x << "\n" KNF_PRINT(samp_freq); KNF_PRINT(frame_shift_ms); KNF_PRINT(frame_length_ms); KNF_PRINT(dither); KNF_PRINT(preemph_coeff); KNF_PRINT(remove_dc_offset); KNF_PRINT(window_type); KNF_PRINT(round_to_power_of_two); KNF_PRINT(blackman_coeff); KNF_PRINT(snip_edges); // KNF_PRINT(allow_downsample); // KNF_PRINT(allow_upsample); KNF_PRINT(max_feature_vectors); #undef KNF_PRINT return os.str(); } }; std::ostream &operator<<(std::ostream &os, const FrameExtractionOptions &opts); class FeatureWindowFunction { public: FeatureWindowFunction() = default; explicit FeatureWindowFunction(const FrameExtractionOptions &opts); /** * @param wave Pointer to a 1-D array of shape [window_size]. * It is modified in-place: wave[i] = wave[i] * window_[i]. * @param */ void Apply(float *wave) const; private: std::vector window_; // of size opts.WindowSize() }; int64_t FirstSampleOfFrame(int32_t frame, const FrameExtractionOptions &opts); /** This function returns the number of frames that we can extract from a wave file with the given number of samples in it (assumed to have the same sampling rate as specified in 'opts'). @param [in] num_samples The number of samples in the wave file. @param [in] opts The frame-extraction options class @param [in] flush True if we are asserting that this number of samples is 'all there is', false if we expecting more data to possibly come in. This only makes a difference to the answer if opts.snips_edges== false. For offline feature extraction you always want flush == true. In an online-decoding context, once you know (or decide) that no more data is coming in, you'd call it with flush == true at the end to flush out any remaining data. */ int32_t NumFrames(int64_t num_samples, const FrameExtractionOptions &opts, bool flush = true); /* ExtractWindow() extracts a windowed frame of waveform (possibly with a power-of-two, padded size, depending on the config), including all the processing done by ProcessWindow(). @param [in] sample_offset If 'wave' is not the entire waveform, but part of it to the left has been discarded, then the number of samples prior to 'wave' that we have already discarded. Set this to zero if you are processing the entire waveform in one piece, or if you get 'no matching function' compilation errors when updating the code. @param [in] wave The waveform @param [in] f The frame index to be extracted, with 0 <= f < NumFrames(sample_offset + wave.Dim(), opts, true) @param [in] opts The options class to be used @param [in] window_function The windowing function, as derived from the options class. @param [out] window The windowed, possibly-padded waveform to be extracted. Will be resized as needed. @param [out] log_energy_pre_window If non-NULL, the log-energy of the signal prior to pre-emphasis and multiplying by the windowing function will be written to here. */ void ExtractWindow(int64_t sample_offset, const std::vector &wave, int32_t f, const FrameExtractionOptions &opts, const FeatureWindowFunction &window_function, std::vector *window, float *log_energy_pre_window = nullptr); /** This function does all the windowing steps after actually extracting the windowed signal: depending on the configuration, it does dithering, dc offset removal, preemphasis, and multiplication by the windowing function. @param [in] opts The options class to be used @param [in] window_function The windowing function-- should have been initialized using 'opts'. @param [in,out] window A vector of size opts.WindowSize(). Note: it will typically be a sub-vector of a larger vector of size opts.PaddedWindowSize(), with the remaining samples zero, as the FFT code is more efficient if it operates on data with power-of-two size. @param [out] log_energy_pre_window If non-NULL, then after dithering and DC offset removal, this function will write to this pointer the log of the total energy (i.e. sum-squared) of the frame. */ void ProcessWindow(const FrameExtractionOptions &opts, const FeatureWindowFunction &window_function, float *window, float *log_energy_pre_window = nullptr); // Compute the inner product of two vectors float InnerProduct(const float *a, const float *b, int32_t n); } // namespace knf #endif // KALDI_NATIVE_FEAT_CSRC_FEATURE_WINDOW_H_ ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/fftsg.c ================================================ /* This file is copied from * https://www.kurims.kyoto-u.ac.jp/~ooura/fft.html */ /* Fast Fourier/Cosine/Sine Transform dimension :one data length :power of 2 decimation :frequency radix :split-radix data :inplace table :use functions cdft: Complex Discrete Fourier Transform rdft: Real Discrete Fourier Transform ddct: Discrete Cosine Transform ddst: Discrete Sine Transform dfct: Cosine Transform of RDFT (Real Symmetric DFT) dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) function prototypes void cdft(int, int, double *, int *, double *); void rdft(int, int, double *, int *, double *); void ddct(int, int, double *, int *, double *); void ddst(int, int, double *, int *, double *); void dfct(int, double *, double *, int *, double *); void dfst(int, double *, double *, int *, double *); macro definitions USE_CDFT_PTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 USE_CDFT_WINTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 -------- Complex DFT (Discrete Fourier Transform) -------- [definition] X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k ip[0] = 0; // first time only cdft(2*n, 1, a, ip, w); ip[0] = 0; // first time only cdft(2*n, -1, a, ip, w); [parameters] 2*n :data length (int) n >= 1, n = power of 2 a[0...2*n-1] :input/output data (double *) input data a[2*j] = Re(x[j]), a[2*j+1] = Im(x[j]), 0<=j= 2+sqrt(n) strictly, length of ip >= 2+(1<<(int)(log(n+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n/2-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of cdft(2*n, -1, a, ip, w); is cdft(2*n, 1, a, ip, w); for (j = 0; j <= 2 * n - 1; j++) { a[j] *= 1.0 / n; } . -------- Real DFT / Inverse of Real DFT -------- [definition] RDFT R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k ip[0] = 0; // first time only rdft(n, 1, a, ip, w); ip[0] = 0; // first time only rdft(n, -1, a, ip, w); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[2*k] = R[k], 0<=k input data a[2*j] = R[j], 0<=j= 2+sqrt(n/2) strictly, length of ip >= 2+(1<<(int)(log(n/2+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n/2-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of rdft(n, 1, a, ip, w); is rdft(n, -1, a, ip, w); for (j = 0; j <= n - 1; j++) { a[j] *= 2.0 / n; } . -------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- [definition] IDCT (excluding scale) C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k DCT C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k ip[0] = 0; // first time only ddct(n, 1, a, ip, w); ip[0] = 0; // first time only ddct(n, -1, a, ip, w); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = C[k], 0<=k= 2+sqrt(n/2) strictly, length of ip >= 2+(1<<(int)(log(n/2+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n*5/4-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of ddct(n, -1, a, ip, w); is a[0] *= 0.5; ddct(n, 1, a, ip, w); for (j = 0; j <= n - 1; j++) { a[j] *= 2.0 / n; } . -------- DST (Discrete Sine Transform) / Inverse of DST -------- [definition] IDST (excluding scale) S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k DST S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0 ip[0] = 0; // first time only ddst(n, 1, a, ip, w); ip[0] = 0; // first time only ddst(n, -1, a, ip, w); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) input data a[j] = A[j], 0 output data a[k] = S[k], 0= 2+sqrt(n/2) strictly, length of ip >= 2+(1<<(int)(log(n/2+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n*5/4-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of ddst(n, -1, a, ip, w); is a[0] *= 0.5; ddst(n, 1, a, ip, w); for (j = 0; j <= n - 1; j++) { a[j] *= 2.0 / n; } . -------- Cosine Transform of RDFT (Real Symmetric DFT) -------- [definition] C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n [usage] ip[0] = 0; // first time only dfct(n, a, t, ip, w); [parameters] n :data length - 1 (int) n >= 2, n = power of 2 a[0...n] :input/output data (double *) output data a[k] = C[k], 0<=k<=n t[0...n/2] :work area (double *) ip[0...*] :work area for bit reversal (int *) length of ip >= 2+sqrt(n/4) strictly, length of ip >= 2+(1<<(int)(log(n/4+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n*5/8-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); is a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); for (j = 0; j <= n; j++) { a[j] *= 2.0 / n; } . -------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- [definition] S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = S[k], 0= 2+sqrt(n/4) strictly, length of ip >= 2+(1<<(int)(log(n/4+0.5)/log(2))/2). ip[0],ip[1] are pointers of the cos/sin table. w[0...n*5/8-1] :cos/sin table (double *) w[],ip[] are initialized if ip[0] == 0. [remark] Inverse of dfst(n, a, t, ip, w); is dfst(n, a, t, ip, w); for (j = 1; j <= n - 1; j++) { a[j] *= 2.0 / n; } . Appendix : The cos/sin table is recalculated when the larger table required. w[] and ip[] are compatible with all routines. */ void cdft(int n, int isgn, double *a, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void cftfsub(int n, double *a, int *ip, int nw, double *w); void cftbsub(int n, double *a, int *ip, int nw, double *w); int nw; nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; makewt(nw, ip, w); } if (isgn >= 0) { cftfsub(n, a, ip, nw, w); } else { cftbsub(n, a, ip, nw, w); } } void rdft(int n, int isgn, double *a, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void makect(int nc, int *ip, double *c); void cftfsub(int n, double *a, int *ip, int nw, double *w); void cftbsub(int n, double *a, int *ip, int nw, double *w); void rftfsub(int n, double *a, int nc, double *c); void rftbsub(int n, double *a, int nc, double *c); int nw, nc; double xi; nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; makewt(nw, ip, w); } nc = ip[1]; if (n > (nc << 2)) { nc = n >> 2; makect(nc, ip, w + nw); } if (isgn >= 0) { if (n > 4) { cftfsub(n, a, ip, nw, w); rftfsub(n, a, nc, w + nw); } else if (n == 4) { cftfsub(n, a, ip, nw, w); } xi = a[0] - a[1]; a[0] += a[1]; a[1] = xi; } else { a[1] = 0.5 * (a[0] - a[1]); a[0] -= a[1]; if (n > 4) { rftbsub(n, a, nc, w + nw); cftbsub(n, a, ip, nw, w); } else if (n == 4) { cftbsub(n, a, ip, nw, w); } } } void ddct(int n, int isgn, double *a, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void makect(int nc, int *ip, double *c); void cftfsub(int n, double *a, int *ip, int nw, double *w); void cftbsub(int n, double *a, int *ip, int nw, double *w); void rftfsub(int n, double *a, int nc, double *c); void rftbsub(int n, double *a, int nc, double *c); void dctsub(int n, double *a, int nc, double *c); int j, nw, nc; double xr; nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; makewt(nw, ip, w); } nc = ip[1]; if (n > nc) { nc = n; makect(nc, ip, w + nw); } if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = a[j] - a[j - 1]; a[j] += a[j - 1]; } a[1] = a[0] - xr; a[0] += xr; if (n > 4) { rftbsub(n, a, nc, w + nw); cftbsub(n, a, ip, nw, w); } else if (n == 4) { cftbsub(n, a, ip, nw, w); } } dctsub(n, a, nc, w + nw); if (isgn >= 0) { if (n > 4) { cftfsub(n, a, ip, nw, w); rftfsub(n, a, nc, w + nw); } else if (n == 4) { cftfsub(n, a, ip, nw, w); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = a[j] - a[j + 1]; a[j] += a[j + 1]; } a[n - 1] = xr; } } void ddst(int n, int isgn, double *a, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void makect(int nc, int *ip, double *c); void cftfsub(int n, double *a, int *ip, int nw, double *w); void cftbsub(int n, double *a, int *ip, int nw, double *w); void rftfsub(int n, double *a, int nc, double *c); void rftbsub(int n, double *a, int nc, double *c); void dstsub(int n, double *a, int nc, double *c); int j, nw, nc; double xr; nw = ip[0]; if (n > (nw << 2)) { nw = n >> 2; makewt(nw, ip, w); } nc = ip[1]; if (n > nc) { nc = n; makect(nc, ip, w + nw); } if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = -a[j] - a[j - 1]; a[j] -= a[j - 1]; } a[1] = a[0] + xr; a[0] -= xr; if (n > 4) { rftbsub(n, a, nc, w + nw); cftbsub(n, a, ip, nw, w); } else if (n == 4) { cftbsub(n, a, ip, nw, w); } } dstsub(n, a, nc, w + nw); if (isgn >= 0) { if (n > 4) { cftfsub(n, a, ip, nw, w); rftfsub(n, a, nc, w + nw); } else if (n == 4) { cftfsub(n, a, ip, nw, w); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = -a[j] - a[j + 1]; a[j] -= a[j + 1]; } a[n - 1] = -xr; } } void dfct(int n, double *a, double *t, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void makect(int nc, int *ip, double *c); void cftfsub(int n, double *a, int *ip, int nw, double *w); void rftfsub(int n, double *a, int nc, double *c); void dctsub(int n, double *a, int nc, double *c); int j, k, l, m, mh, nw, nc; double xr, xi, yr, yi; nw = ip[0]; if (n > (nw << 3)) { nw = n >> 3; makewt(nw, ip, w); } nc = ip[1]; if (n > (nc << 1)) { nc = n >> 1; makect(nc, ip, w + nw); } m = n >> 1; yi = a[m]; xi = a[0] + a[n]; a[0] -= a[n]; t[0] = xi - yi; t[m] = xi + yi; if (n > 2) { mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; xr = a[j] - a[n - j]; xi = a[j] + a[n - j]; yr = a[k] - a[n - k]; yi = a[k] + a[n - k]; a[j] = xr; a[k] = yr; t[j] = xi - yi; t[k] = xi + yi; } t[mh] = a[mh] + a[n - mh]; a[mh] -= a[n - mh]; dctsub(m, a, nc, w + nw); if (m > 4) { cftfsub(m, a, ip, nw, w); rftfsub(m, a, nc, w + nw); } else if (m == 4) { cftfsub(m, a, ip, nw, w); } a[n - 1] = a[0] - a[1]; a[1] = a[0] + a[1]; for (j = m - 2; j >= 2; j -= 2) { a[2 * j + 1] = a[j] + a[j + 1]; a[2 * j - 1] = a[j] - a[j + 1]; } l = 2; m = mh; while (m >= 2) { dctsub(m, t, nc, w + nw); if (m > 4) { cftfsub(m, t, ip, nw, w); rftfsub(m, t, nc, w + nw); } else if (m == 4) { cftfsub(m, t, ip, nw, w); } a[n - l] = t[0] - t[1]; a[l] = t[0] + t[1]; k = 0; for (j = 2; j < m; j += 2) { k += l << 2; a[k - l] = t[j] - t[j + 1]; a[k + l] = t[j] + t[j + 1]; } l <<= 1; mh = m >> 1; for (j = 0; j < mh; j++) { k = m - j; t[j] = t[m + k] - t[m + j]; t[k] = t[m + k] + t[m + j]; } t[mh] = t[m + mh]; m = mh; } a[l] = t[0]; a[n] = t[2] - t[1]; a[0] = t[2] + t[1]; } else { a[1] = a[0]; a[2] = t[0]; a[0] = t[1]; } } void dfst(int n, double *a, double *t, int *ip, double *w) { void makewt(int nw, int *ip, double *w); void makect(int nc, int *ip, double *c); void cftfsub(int n, double *a, int *ip, int nw, double *w); void rftfsub(int n, double *a, int nc, double *c); void dstsub(int n, double *a, int nc, double *c); int j, k, l, m, mh, nw, nc; double xr, xi, yr, yi; nw = ip[0]; if (n > (nw << 3)) { nw = n >> 3; makewt(nw, ip, w); } nc = ip[1]; if (n > (nc << 1)) { nc = n >> 1; makect(nc, ip, w + nw); } if (n > 2) { m = n >> 1; mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; xr = a[j] + a[n - j]; xi = a[j] - a[n - j]; yr = a[k] + a[n - k]; yi = a[k] - a[n - k]; a[j] = xr; a[k] = yr; t[j] = xi + yi; t[k] = xi - yi; } t[0] = a[mh] - a[n - mh]; a[mh] += a[n - mh]; a[0] = a[m]; dstsub(m, a, nc, w + nw); if (m > 4) { cftfsub(m, a, ip, nw, w); rftfsub(m, a, nc, w + nw); } else if (m == 4) { cftfsub(m, a, ip, nw, w); } a[n - 1] = a[1] - a[0]; a[1] = a[0] + a[1]; for (j = m - 2; j >= 2; j -= 2) { a[2 * j + 1] = a[j] - a[j + 1]; a[2 * j - 1] = -a[j] - a[j + 1]; } l = 2; m = mh; while (m >= 2) { dstsub(m, t, nc, w + nw); if (m > 4) { cftfsub(m, t, ip, nw, w); rftfsub(m, t, nc, w + nw); } else if (m == 4) { cftfsub(m, t, ip, nw, w); } a[n - l] = t[1] - t[0]; a[l] = t[0] + t[1]; k = 0; for (j = 2; j < m; j += 2) { k += l << 2; a[k - l] = -t[j] - t[j + 1]; a[k + l] = t[j] - t[j + 1]; } l <<= 1; mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; t[j] = t[m + k] + t[m + j]; t[k] = t[m + k] - t[m + j]; } t[0] = t[m + mh]; m = mh; } a[l] = t[0]; } a[0] = 0; } /* -------- initializing routines -------- */ #include void makewt(int nw, int *ip, double *w) { void makeipt(int nw, int *ip); int j, nwh, nw0, nw1; double delta, wn4r, wk1r, wk1i, wk3r, wk3i; ip[0] = nw; ip[1] = 1; if (nw > 2) { nwh = nw >> 1; delta = atan(1.0) / nwh; wn4r = cos(delta * nwh); w[0] = 1; w[1] = wn4r; if (nwh == 4) { w[2] = cos(delta * 2); w[3] = sin(delta * 2); } else if (nwh > 4) { makeipt(nw, ip); w[2] = 0.5 / cos(delta * 2); w[3] = 0.5 / cos(delta * 6); for (j = 4; j < nwh; j += 4) { w[j] = cos(delta * j); w[j + 1] = sin(delta * j); w[j + 2] = cos(3 * delta * j); w[j + 3] = -sin(3 * delta * j); } } nw0 = 0; while (nwh > 2) { nw1 = nw0 + nwh; nwh >>= 1; w[nw1] = 1; w[nw1 + 1] = wn4r; if (nwh == 4) { wk1r = w[nw0 + 4]; wk1i = w[nw0 + 5]; w[nw1 + 2] = wk1r; w[nw1 + 3] = wk1i; } else if (nwh > 4) { wk1r = w[nw0 + 4]; wk3r = w[nw0 + 6]; w[nw1 + 2] = 0.5 / wk1r; w[nw1 + 3] = 0.5 / wk3r; for (j = 4; j < nwh; j += 4) { wk1r = w[nw0 + 2 * j]; wk1i = w[nw0 + 2 * j + 1]; wk3r = w[nw0 + 2 * j + 2]; wk3i = w[nw0 + 2 * j + 3]; w[nw1 + j] = wk1r; w[nw1 + j + 1] = wk1i; w[nw1 + j + 2] = wk3r; w[nw1 + j + 3] = wk3i; } } nw0 = nw1; } } } void makeipt(int nw, int *ip) { int j, l, m, m2, p, q; ip[2] = 0; ip[3] = 16; m = 2; for (l = nw; l > 32; l >>= 2) { m2 = m << 1; q = m2 << 3; for (j = m; j < m2; j++) { p = ip[j] << 2; ip[m + j] = p; ip[m2 + j] = p + q; } m = m2; } } void makect(int nc, int *ip, double *c) { int j, nch; double delta; ip[1] = nc; if (nc > 1) { nch = nc >> 1; delta = atan(1.0) / nch; c[0] = cos(delta * nch); c[nch] = 0.5 * c[0]; for (j = 1; j < nch; j++) { c[j] = 0.5 * cos(delta * j); c[nc - j] = 0.5 * sin(delta * j); } } } /* -------- child routines -------- */ #ifdef USE_CDFT_PTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 8192 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 65536 #endif #include #include #include #define cdft_thread_t pthread_t #define cdft_thread_create(thp, func, argp) \ { \ if (pthread_create(thp, NULL, func, (void *)argp) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) \ { \ if (pthread_join(th, NULL) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #endif /* USE_CDFT_PTHREADS */ #ifdef USE_CDFT_WINTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 32768 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 524288 #endif #include #include #include #define cdft_thread_t HANDLE #define cdft_thread_create(thp, func, argp) \ { \ DWORD thid; \ *(thp) = CreateThread( \ NULL, 0, (LPTHREAD_START_ROUTINE)func, (LPVOID)argp, 0, &thid); \ if (*(thp) == 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) \ { \ WaitForSingleObject(th, INFINITE); \ CloseHandle(th); \ } #endif /* USE_CDFT_WINTHREADS */ void cftfsub(int n, double *a, int *ip, int nw, double *w) { void bitrv2(int n, int *ip, double *a); void bitrv216(double *a); void bitrv208(double *a); void cftf1st(int n, double *a, double *w); void cftrec4(int n, double *a, int nw, double *w); void cftleaf(int n, int isplt, double *a, int nw, double *w); void cftfx41(int n, double *a, int nw, double *w); void cftf161(double *a, double *w); void cftf081(double *a, double *w); void cftf040(double *a); void cftx020(double *a); #ifdef USE_CDFT_THREADS void cftrec4_th(int n, double *a, int nw, double *w); #endif /* USE_CDFT_THREADS */ if (n > 8) { if (n > 32) { cftf1st(n, a, &w[nw - (n >> 2)]); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a, nw, w); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a, nw, w); } else if (n > 128) { cftleaf(n, 1, a, nw, w); } else { cftfx41(n, a, nw, w); } bitrv2(n, ip, a); } else if (n == 32) { cftf161(a, &w[nw - 8]); bitrv216(a); } else { cftf081(a, w); bitrv208(a); } } else if (n == 8) { cftf040(a); } else if (n == 4) { cftx020(a); } } void cftbsub(int n, double *a, int *ip, int nw, double *w) { void bitrv2conj(int n, int *ip, double *a); void bitrv216neg(double *a); void bitrv208neg(double *a); void cftb1st(int n, double *a, double *w); void cftrec4(int n, double *a, int nw, double *w); void cftleaf(int n, int isplt, double *a, int nw, double *w); void cftfx41(int n, double *a, int nw, double *w); void cftf161(double *a, double *w); void cftf081(double *a, double *w); void cftb040(double *a); void cftx020(double *a); #ifdef USE_CDFT_THREADS void cftrec4_th(int n, double *a, int nw, double *w); #endif /* USE_CDFT_THREADS */ if (n > 8) { if (n > 32) { cftb1st(n, a, &w[nw - (n >> 2)]); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a, nw, w); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a, nw, w); } else if (n > 128) { cftleaf(n, 1, a, nw, w); } else { cftfx41(n, a, nw, w); } bitrv2conj(n, ip, a); } else if (n == 32) { cftf161(a, &w[nw - 8]); bitrv216neg(a); } else { cftf081(a, w); bitrv208neg(a); } } else if (n == 8) { cftb040(a); } else if (n == 4) { cftx020(a); } } void bitrv2(int n, int *ip, double *a) { int j, j1, k, k1, l, m, nh, nm; double xr, xi, yr, yi; m = 1; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; nm = 4 * m; if (l == 8) { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 4 * j + 2 * ip[m + k]; k1 = 4 * k + 2 * ip[m + j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh; k1 += 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 += nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += 2; k1 += nh; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh; k1 -= 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 += nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 4 * k + 2 * ip[m + k]; j1 = k1 + 2; k1 += nh; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= 2; k1 -= nh; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh + 2; k1 += nh + 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh - nm; k1 += 2 * nm - 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } else { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 4 * j + ip[m + k]; k1 = 4 * k + ip[m + j]; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh; k1 += 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += 2; k1 += nh; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh; k1 -= 2; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 4 * k + ip[m + k]; j1 = k1 + 2; k1 += nh; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += nm; xr = a[j1]; xi = a[j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } } } void bitrv2conj(int n, int *ip, double *a) { int j, j1, k, k1, l, m, nh, nm; double xr, xi, yr, yi; m = 1; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; nm = 4 * m; if (l == 8) { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 4 * j + 2 * ip[m + k]; k1 = 4 * k + 2 * ip[m + j]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh; k1 += 2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 += nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += 2; k1 += nh; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh; k1 -= 2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 += nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 4 * k + 2 * ip[m + k]; j1 = k1 + 2; k1 += nh; a[j1 - 1] = -a[j1 - 1]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; j1 += nm; k1 += 2 * nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 -= nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= 2; k1 -= nh; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh + 2; k1 += nh + 2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh - nm; k1 += 2 * nm - 2; a[j1 - 1] = -a[j1 - 1]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; } } else { for (k = 0; k < m; k++) { for (j = 0; j < k; j++) { j1 = 4 * j + ip[m + k]; k1 = 4 * k + ip[m + j]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nh; k1 += 2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += 2; k1 += nh; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 += nm; k1 += nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nh; k1 -= 2; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; j1 -= nm; k1 -= nm; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; } k1 = 4 * k + ip[m + k]; j1 = k1 + 2; k1 += nh; a[j1 - 1] = -a[j1 - 1]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; j1 += nm; k1 += nm; a[j1 - 1] = -a[j1 - 1]; xr = a[j1]; xi = -a[j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[j1] = yr; a[j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; } } } void bitrv216(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; a[2] = x8r; a[3] = x8i; a[4] = x4r; a[5] = x4i; a[6] = x12r; a[7] = x12i; a[8] = x2r; a[9] = x2i; a[10] = x10r; a[11] = x10i; a[14] = x14r; a[15] = x14i; a[16] = x1r; a[17] = x1i; a[20] = x5r; a[21] = x5i; a[22] = x13r; a[23] = x13i; a[24] = x3r; a[25] = x3i; a[26] = x11r; a[27] = x11i; a[28] = x7r; a[29] = x7i; } void bitrv216neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x9r = a[18]; x9i = a[19]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; x15r = a[30]; x15i = a[31]; a[2] = x15r; a[3] = x15i; a[4] = x7r; a[5] = x7i; a[6] = x11r; a[7] = x11i; a[8] = x3r; a[9] = x3i; a[10] = x13r; a[11] = x13i; a[12] = x5r; a[13] = x5i; a[14] = x9r; a[15] = x9i; a[16] = x1r; a[17] = x1i; a[18] = x14r; a[19] = x14i; a[20] = x6r; a[21] = x6i; a[22] = x10r; a[23] = x10i; a[24] = x2r; a[25] = x2i; a[26] = x12r; a[27] = x12i; a[28] = x4r; a[29] = x4i; a[30] = x8r; a[31] = x8i; } void bitrv208(double *a) { double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; x1r = a[2]; x1i = a[3]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x6r = a[12]; x6i = a[13]; a[2] = x4r; a[3] = x4i; a[6] = x6r; a[7] = x6i; a[8] = x1r; a[9] = x1i; a[12] = x3r; a[13] = x3i; } void bitrv208neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; a[2] = x7r; a[3] = x7i; a[4] = x3r; a[5] = x3i; a[6] = x5r; a[7] = x5i; a[8] = x1r; a[9] = x1i; a[10] = x6r; a[11] = x6i; a[12] = x2r; a[13] = x2i; a[14] = x4r; a[15] = x4i; } void cftf1st(int n, double *a, double *w) { int j, j0, j1, j2, j3, k, m, mh; double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; mh = n >> 3; m = 2 * mh; j1 = m; j2 = j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = a[1] + a[j2 + 1]; x1r = a[0] - a[j2]; x1i = a[1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; a[j2] = x1r - x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; wn4r = w[1]; csc1 = w[2]; csc3 = w[3]; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; k = 0; for (j = 2; j < mh - 2; j += 4) { k += 4; wk1r = csc1 * (wd1r + w[k]); wk1i = csc1 * (wd1i + w[k + 1]); wk3r = csc3 * (wd3r + w[k + 2]); wk3i = csc3 * (wd3i + w[k + 3]); wd1r = w[k]; wd1i = w[k + 1]; wd3r = w[k + 2]; wd3i = w[k + 3]; j1 = j + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = a[j + 1] + a[j2 + 1]; x1r = a[j] - a[j2]; x1i = a[j + 1] - a[j2 + 1]; y0r = a[j + 2] + a[j2 + 2]; y0i = a[j + 3] + a[j2 + 3]; y1r = a[j + 2] - a[j2 + 2]; y1i = a[j + 3] - a[j2 + 3]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; y2r = a[j1 + 2] + a[j3 + 2]; y2i = a[j1 + 3] + a[j3 + 3]; y3r = a[j1 + 2] - a[j3 + 2]; y3i = a[j1 + 3] - a[j3 + 3]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j + 2] = y0r + y2r; a[j + 3] = y0i + y2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; a[j1 + 2] = y0r - y2r; a[j1 + 3] = y0i - y2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = y1r - y3i; x0i = y1i + y3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = y1r + y3i; x0i = y1i - y3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; j0 = m - j; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] + a[j2]; x0i = a[j0 + 1] + a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = a[j0 + 1] - a[j2 + 1]; y0r = a[j0 - 2] + a[j2 - 2]; y0i = a[j0 - 1] + a[j2 - 1]; y1r = a[j0 - 2] - a[j2 - 2]; y1i = a[j0 - 1] - a[j2 - 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; y2r = a[j1 - 2] + a[j3 - 2]; y2i = a[j1 - 1] + a[j3 - 1]; y3r = a[j1 - 2] - a[j3 - 2]; y3i = a[j1 - 1] - a[j3 - 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i + x2i; a[j0 - 2] = y0r + y2r; a[j0 - 1] = y0i + y2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; a[j1 - 2] = y0r - y2r; a[j1 - 1] = y0i - y2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = y1r - y3i; x0i = y1i + y3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = y1r + y3i; x0i = y1i - y3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; } wk1r = csc1 * (wd1r + wn4r); wk1i = csc1 * (wd1i + wn4r); wk3r = csc3 * (wd3r - wn4r); wk3i = csc3 * (wd3i - wn4r); j0 = mh; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0 - 2] + a[j2 - 2]; x0i = a[j0 - 1] + a[j2 - 1]; x1r = a[j0 - 2] - a[j2 - 2]; x1i = a[j0 - 1] - a[j2 - 1]; x2r = a[j1 - 2] + a[j3 - 2]; x2i = a[j1 - 1] + a[j3 - 1]; x3r = a[j1 - 2] - a[j3 - 2]; x3i = a[j1 - 1] - a[j3 - 1]; a[j0 - 2] = x0r + x2r; a[j0 - 1] = x0i + x2i; a[j1 - 2] = x0r - x2r; a[j1 - 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[j0] + a[j2]; x0i = a[j0 + 1] + a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = a[j0 + 1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wn4r * (x0r - x0i); a[j2 + 1] = wn4r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = -wn4r * (x0r + x0i); a[j3 + 1] = -wn4r * (x0i - x0r); x0r = a[j0 + 2] + a[j2 + 2]; x0i = a[j0 + 3] + a[j2 + 3]; x1r = a[j0 + 2] - a[j2 + 2]; x1i = a[j0 + 3] - a[j2 + 3]; x2r = a[j1 + 2] + a[j3 + 2]; x2i = a[j1 + 3] + a[j3 + 3]; x3r = a[j1 + 2] - a[j3 + 2]; x3i = a[j1 + 3] - a[j3 + 3]; a[j0 + 2] = x0r + x2r; a[j0 + 3] = x0i + x2i; a[j1 + 2] = x0r - x2r; a[j1 + 3] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } void cftb1st(int n, double *a, double *w) { int j, j0, j1, j2, j3, k, m, mh; double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; mh = n >> 3; m = 2 * mh; j1 = m; j2 = j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = -a[1] - a[j2 + 1]; x1r = a[0] - a[j2]; x1i = -a[1] + a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i - x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i + x2i; a[j2] = x1r + x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r - x3i; a[j3 + 1] = x1i - x3r; wn4r = w[1]; csc1 = w[2]; csc3 = w[3]; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; k = 0; for (j = 2; j < mh - 2; j += 4) { k += 4; wk1r = csc1 * (wd1r + w[k]); wk1i = csc1 * (wd1i + w[k + 1]); wk3r = csc3 * (wd3r + w[k + 2]); wk3i = csc3 * (wd3i + w[k + 3]); wd1r = w[k]; wd1i = w[k + 1]; wd3r = w[k + 2]; wd3i = w[k + 3]; j1 = j + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = -a[j + 1] - a[j2 + 1]; x1r = a[j] - a[j2]; x1i = -a[j + 1] + a[j2 + 1]; y0r = a[j + 2] + a[j2 + 2]; y0i = -a[j + 3] - a[j2 + 3]; y1r = a[j + 2] - a[j2 + 2]; y1i = -a[j + 3] + a[j2 + 3]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; y2r = a[j1 + 2] + a[j3 + 2]; y2i = a[j1 + 3] + a[j3 + 3]; y3r = a[j1 + 2] - a[j3 + 2]; y3i = a[j1 + 3] - a[j3 + 3]; a[j] = x0r + x2r; a[j + 1] = x0i - x2i; a[j + 2] = y0r + y2r; a[j + 3] = y0i - y2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i + x2i; a[j1 + 2] = y0r - y2r; a[j1 + 3] = y0i + y2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = y1r + y3i; x0i = y1i + y3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = y1r - y3i; x0i = y1i - y3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; j0 = m - j; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] + a[j2]; x0i = -a[j0 + 1] - a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = -a[j0 + 1] + a[j2 + 1]; y0r = a[j0 - 2] + a[j2 - 2]; y0i = -a[j0 - 1] - a[j2 - 1]; y1r = a[j0 - 2] - a[j2 - 2]; y1i = -a[j0 - 1] + a[j2 - 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; y2r = a[j1 - 2] + a[j3 - 2]; y2i = a[j1 - 1] + a[j3 - 1]; y3r = a[j1 - 2] - a[j3 - 2]; y3i = a[j1 - 1] - a[j3 - 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i - x2i; a[j0 - 2] = y0r + y2r; a[j0 - 1] = y0i - y2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i + x2i; a[j1 - 2] = y0r - y2r; a[j1 - 1] = y0i + y2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = y1r + y3i; x0i = y1i + y3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = y1r - y3i; x0i = y1i - y3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; } wk1r = csc1 * (wd1r + wn4r); wk1i = csc1 * (wd1i + wn4r); wk3r = csc3 * (wd3r - wn4r); wk3i = csc3 * (wd3i - wn4r); j0 = mh; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0 - 2] + a[j2 - 2]; x0i = -a[j0 - 1] - a[j2 - 1]; x1r = a[j0 - 2] - a[j2 - 2]; x1i = -a[j0 - 1] + a[j2 - 1]; x2r = a[j1 - 2] + a[j3 - 2]; x2i = a[j1 - 1] + a[j3 - 1]; x3r = a[j1 - 2] - a[j3 - 2]; x3i = a[j1 - 1] - a[j3 - 1]; a[j0 - 2] = x0r + x2r; a[j0 - 1] = x0i - x2i; a[j1 - 2] = x0r - x2r; a[j1 - 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[j0] + a[j2]; x0i = -a[j0 + 1] - a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = -a[j0 + 1] + a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i - x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wn4r * (x0r - x0i); a[j2 + 1] = wn4r * (x0i + x0r); x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = -wn4r * (x0r + x0i); a[j3 + 1] = -wn4r * (x0i - x0r); x0r = a[j0 + 2] + a[j2 + 2]; x0i = -a[j0 + 3] - a[j2 + 3]; x1r = a[j0 + 2] - a[j2 + 2]; x1i = -a[j0 + 3] + a[j2 + 3]; x2r = a[j1 + 2] + a[j3 + 2]; x2i = a[j1 + 3] + a[j3 + 3]; x3r = a[j1 + 2] - a[j3 + 2]; x3i = a[j1 + 3] - a[j3 + 3]; a[j0 + 2] = x0r + x2r; a[j0 + 3] = x0i - x2i; a[j1 + 2] = x0r - x2r; a[j1 + 3] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } #ifdef USE_CDFT_THREADS struct cdft_arg_st { int n0; int n; double *a; int nw; double *w; }; typedef struct cdft_arg_st cdft_arg_t; void cftrec4_th(int n, double *a, int nw, double *w) { void *cftrec1_th(void *p); void *cftrec2_th(void *p); int i, idiv4, m, nthread; cdft_thread_t th[4]; cdft_arg_t ag[4]; nthread = 2; idiv4 = 0; m = n >> 1; if (n > CDFT_4THREADS_BEGIN_N) { nthread = 4; idiv4 = 1; m >>= 1; } for (i = 0; i < nthread; i++) { ag[i].n0 = n; ag[i].n = m; ag[i].a = &a[i * m]; ag[i].nw = nw; ag[i].w = w; if (i != idiv4) { cdft_thread_create(&th[i], cftrec1_th, &ag[i]); } else { cdft_thread_create(&th[i], cftrec2_th, &ag[i]); } } for (i = 0; i < nthread; i++) { cdft_thread_wait(th[i]); } } void *cftrec1_th(void *p) { int cfttree(int n, int j, int k, double *a, int nw, double *w); void cftleaf(int n, int isplt, double *a, int nw, double *w); void cftmdl1(int n, double *a, double *w); int isplt, j, k, m, n, n0, nw; double *a, *w; n0 = ((cdft_arg_t *)p)->n0; n = ((cdft_arg_t *)p)->n; a = ((cdft_arg_t *)p)->a; nw = ((cdft_arg_t *)p)->nw; w = ((cdft_arg_t *)p)->w; m = n0; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); } cftleaf(m, 1, &a[n - m], nw, w); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a, nw, w); cftleaf(m, isplt, &a[j - m], nw, w); } return (void *)0; } void *cftrec2_th(void *p) { int cfttree(int n, int j, int k, double *a, int nw, double *w); void cftleaf(int n, int isplt, double *a, int nw, double *w); void cftmdl2(int n, double *a, double *w); int isplt, j, k, m, n, n0, nw; double *a, *w; n0 = ((cdft_arg_t *)p)->n0; n = ((cdft_arg_t *)p)->n; a = ((cdft_arg_t *)p)->a; nw = ((cdft_arg_t *)p)->nw; w = ((cdft_arg_t *)p)->w; k = 1; m = n0; while (m > 512) { m >>= 2; k <<= 2; cftmdl2(m, &a[n - m], &w[nw - m]); } cftleaf(m, 0, &a[n - m], nw, w); k >>= 1; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a, nw, w); cftleaf(m, isplt, &a[j - m], nw, w); } return (void *)0; } #endif /* USE_CDFT_THREADS */ void cftrec4(int n, double *a, int nw, double *w) { int cfttree(int n, int j, int k, double *a, int nw, double *w); void cftleaf(int n, int isplt, double *a, int nw, double *w); void cftmdl1(int n, double *a, double *w); int isplt, j, k, m; m = n; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m], &w[nw - (m >> 1)]); } cftleaf(m, 1, &a[n - m], nw, w); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a, nw, w); cftleaf(m, isplt, &a[j - m], nw, w); } } int cfttree(int n, int j, int k, double *a, int nw, double *w) { void cftmdl1(int n, double *a, double *w); void cftmdl2(int n, double *a, double *w); int i, isplt, m; if ((k & 3) != 0) { isplt = k & 1; if (isplt != 0) { cftmdl1(n, &a[j - n], &w[nw - (n >> 1)]); } else { cftmdl2(n, &a[j - n], &w[nw - n]); } } else { m = n; for (i = k; (i & 3) == 0; i >>= 2) { m <<= 2; } isplt = i & 1; if (isplt != 0) { while (m > 128) { cftmdl1(m, &a[j - m], &w[nw - (m >> 1)]); m >>= 2; } } else { while (m > 128) { cftmdl2(m, &a[j - m], &w[nw - m]); m >>= 2; } } } return isplt; } void cftleaf(int n, int isplt, double *a, int nw, double *w) { void cftmdl1(int n, double *a, double *w); void cftmdl2(int n, double *a, double *w); void cftf161(double *a, double *w); void cftf162(double *a, double *w); void cftf081(double *a, double *w); void cftf082(double *a, double *w); if (n == 512) { cftmdl1(128, a, &w[nw - 64]); cftf161(a, &w[nw - 8]); cftf162(&a[32], &w[nw - 32]); cftf161(&a[64], &w[nw - 8]); cftf161(&a[96], &w[nw - 8]); cftmdl2(128, &a[128], &w[nw - 128]); cftf161(&a[128], &w[nw - 8]); cftf162(&a[160], &w[nw - 32]); cftf161(&a[192], &w[nw - 8]); cftf162(&a[224], &w[nw - 32]); cftmdl1(128, &a[256], &w[nw - 64]); cftf161(&a[256], &w[nw - 8]); cftf162(&a[288], &w[nw - 32]); cftf161(&a[320], &w[nw - 8]); cftf161(&a[352], &w[nw - 8]); if (isplt != 0) { cftmdl1(128, &a[384], &w[nw - 64]); cftf161(&a[480], &w[nw - 8]); } else { cftmdl2(128, &a[384], &w[nw - 128]); cftf162(&a[480], &w[nw - 32]); } cftf161(&a[384], &w[nw - 8]); cftf162(&a[416], &w[nw - 32]); cftf161(&a[448], &w[nw - 8]); } else { cftmdl1(64, a, &w[nw - 32]); cftf081(a, &w[nw - 8]); cftf082(&a[16], &w[nw - 8]); cftf081(&a[32], &w[nw - 8]); cftf081(&a[48], &w[nw - 8]); cftmdl2(64, &a[64], &w[nw - 64]); cftf081(&a[64], &w[nw - 8]); cftf082(&a[80], &w[nw - 8]); cftf081(&a[96], &w[nw - 8]); cftf082(&a[112], &w[nw - 8]); cftmdl1(64, &a[128], &w[nw - 32]); cftf081(&a[128], &w[nw - 8]); cftf082(&a[144], &w[nw - 8]); cftf081(&a[160], &w[nw - 8]); cftf081(&a[176], &w[nw - 8]); if (isplt != 0) { cftmdl1(64, &a[192], &w[nw - 32]); cftf081(&a[240], &w[nw - 8]); } else { cftmdl2(64, &a[192], &w[nw - 64]); cftf082(&a[240], &w[nw - 8]); } cftf081(&a[192], &w[nw - 8]); cftf082(&a[208], &w[nw - 8]); cftf081(&a[224], &w[nw - 8]); } } void cftmdl1(int n, double *a, double *w) { int j, j0, j1, j2, j3, k, m, mh; double wn4r, wk1r, wk1i, wk3r, wk3i; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; mh = n >> 3; m = 2 * mh; j1 = m; j2 = j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = a[1] + a[j2 + 1]; x1r = a[0] - a[j2]; x1i = a[1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; a[j2] = x1r - x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; wn4r = w[1]; k = 0; for (j = 2; j < mh; j += 2) { k += 4; wk1r = w[k]; wk1i = w[k + 1]; wk3r = w[k + 2]; wk3i = w[k + 3]; j1 = j + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = a[j + 1] + a[j2 + 1]; x1r = a[j] - a[j2]; x1i = a[j + 1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; j0 = m - j; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] + a[j2]; x0i = a[j0 + 1] + a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = a[j0 + 1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; } j0 = mh; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] + a[j2]; x0i = a[j0 + 1] + a[j2 + 1]; x1r = a[j0] - a[j2]; x1i = a[j0 + 1] - a[j2 + 1]; x2r = a[j1] + a[j3]; x2i = a[j1 + 1] + a[j3 + 1]; x3r = a[j1] - a[j3]; x3i = a[j1 + 1] - a[j3 + 1]; a[j0] = x0r + x2r; a[j0 + 1] = x0i + x2i; a[j1] = x0r - x2r; a[j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wn4r * (x0r - x0i); a[j2 + 1] = wn4r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = -wn4r * (x0r + x0i); a[j3 + 1] = -wn4r * (x0i - x0r); } void cftmdl2(int n, double *a, double *w) { int j, j0, j1, j2, j3, k, kr, m, mh; double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; mh = n >> 3; m = 2 * mh; wn4r = w[1]; j1 = m; j2 = j1 + m; j3 = j2 + m; x0r = a[0] - a[j2 + 1]; x0i = a[1] + a[j2]; x1r = a[0] + a[j2 + 1]; x1i = a[1] - a[j2]; x2r = a[j1] - a[j3 + 1]; x2i = a[j1 + 1] + a[j3]; x3r = a[j1] + a[j3 + 1]; x3i = a[j1 + 1] - a[j3]; y0r = wn4r * (x2r - x2i); y0i = wn4r * (x2i + x2r); a[0] = x0r + y0r; a[1] = x0i + y0i; a[j1] = x0r - y0r; a[j1 + 1] = x0i - y0i; y0r = wn4r * (x3r - x3i); y0i = wn4r * (x3i + x3r); a[j2] = x1r - y0i; a[j2 + 1] = x1i + y0r; a[j3] = x1r + y0i; a[j3 + 1] = x1i - y0r; k = 0; kr = 2 * m; for (j = 2; j < mh; j += 2) { k += 4; wk1r = w[k]; wk1i = w[k + 1]; wk3r = w[k + 2]; wk3i = w[k + 3]; kr -= 4; wd1i = w[kr]; wd1r = w[kr + 1]; wd3i = w[kr + 2]; wd3r = w[kr + 3]; j1 = j + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j] - a[j2 + 1]; x0i = a[j + 1] + a[j2]; x1r = a[j] + a[j2 + 1]; x1i = a[j + 1] - a[j2]; x2r = a[j1] - a[j3 + 1]; x2i = a[j1 + 1] + a[j3]; x3r = a[j1] + a[j3 + 1]; x3i = a[j1 + 1] - a[j3]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wd1r * x2r - wd1i * x2i; y2i = wd1r * x2i + wd1i * x2r; a[j] = y0r + y2r; a[j + 1] = y0i + y2i; a[j1] = y0r - y2r; a[j1 + 1] = y0i - y2i; y0r = wk3r * x1r + wk3i * x1i; y0i = wk3r * x1i - wk3i * x1r; y2r = wd3r * x3r + wd3i * x3i; y2i = wd3r * x3i - wd3i * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; j0 = m - j; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] - a[j2 + 1]; x0i = a[j0 + 1] + a[j2]; x1r = a[j0] + a[j2 + 1]; x1i = a[j0 + 1] - a[j2]; x2r = a[j1] - a[j3 + 1]; x2i = a[j1 + 1] + a[j3]; x3r = a[j1] + a[j3 + 1]; x3i = a[j1 + 1] - a[j3]; y0r = wd1i * x0r - wd1r * x0i; y0i = wd1i * x0i + wd1r * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[j0] = y0r + y2r; a[j0 + 1] = y0i + y2i; a[j1] = y0r - y2r; a[j1 + 1] = y0i - y2i; y0r = wd3i * x1r + wd3r * x1i; y0i = wd3i * x1i - wd3r * x1r; y2r = wk3i * x3r + wk3r * x3i; y2i = wk3i * x3i - wk3r * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; } wk1r = w[m]; wk1i = w[m + 1]; j0 = mh; j1 = j0 + m; j2 = j1 + m; j3 = j2 + m; x0r = a[j0] - a[j2 + 1]; x0i = a[j0 + 1] + a[j2]; x1r = a[j0] + a[j2 + 1]; x1i = a[j0 + 1] - a[j2]; x2r = a[j1] - a[j3 + 1]; x2i = a[j1 + 1] + a[j3]; x3r = a[j1] + a[j3 + 1]; x3i = a[j1 + 1] - a[j3]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[j0] = y0r + y2r; a[j0 + 1] = y0i + y2i; a[j1] = y0r - y2r; a[j1 + 1] = y0i - y2i; y0r = wk1i * x1r - wk1r * x1i; y0i = wk1i * x1i + wk1r * x1r; y2r = wk1r * x3r - wk1i * x3i; y2i = wk1r * x3i + wk1i * x3r; a[j2] = y0r - y2r; a[j2 + 1] = y0i - y2i; a[j3] = y0r + y2r; a[j3 + 1] = y0i + y2i; } void cftfx41(int n, double *a, int nw, double *w) { void cftf161(double *a, double *w); void cftf162(double *a, double *w); void cftf081(double *a, double *w); void cftf082(double *a, double *w); if (n == 128) { cftf161(a, &w[nw - 8]); cftf162(&a[32], &w[nw - 32]); cftf161(&a[64], &w[nw - 8]); cftf161(&a[96], &w[nw - 8]); } else { cftf081(a, &w[nw - 8]); cftf082(&a[16], &w[nw - 8]); cftf081(&a[32], &w[nw - 8]); cftf081(&a[48], &w[nw - 8]); } } void cftf161(double *a, double *w) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = w[1]; wk1r = w[2]; wk1i = w[3]; x0r = a[0] + a[16]; x0i = a[1] + a[17]; x1r = a[0] - a[16]; x1i = a[1] - a[17]; x2r = a[8] + a[24]; x2i = a[9] + a[25]; x3r = a[8] - a[24]; x3i = a[9] - a[25]; y0r = x0r + x2r; y0i = x0i + x2i; y4r = x0r - x2r; y4i = x0i - x2i; y8r = x1r - x3i; y8i = x1i + x3r; y12r = x1r + x3i; y12i = x1i - x3r; x0r = a[2] + a[18]; x0i = a[3] + a[19]; x1r = a[2] - a[18]; x1i = a[3] - a[19]; x2r = a[10] + a[26]; x2i = a[11] + a[27]; x3r = a[10] - a[26]; x3i = a[11] - a[27]; y1r = x0r + x2r; y1i = x0i + x2i; y5r = x0r - x2r; y5i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y9r = wk1r * x0r - wk1i * x0i; y9i = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y13r = wk1i * x0r - wk1r * x0i; y13i = wk1i * x0i + wk1r * x0r; x0r = a[4] + a[20]; x0i = a[5] + a[21]; x1r = a[4] - a[20]; x1i = a[5] - a[21]; x2r = a[12] + a[28]; x2i = a[13] + a[29]; x3r = a[12] - a[28]; x3i = a[13] - a[29]; y2r = x0r + x2r; y2i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y10r = wn4r * (x0r - x0i); y10i = wn4r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; y14r = wn4r * (x0r + x0i); y14i = wn4r * (x0i - x0r); x0r = a[6] + a[22]; x0i = a[7] + a[23]; x1r = a[6] - a[22]; x1i = a[7] - a[23]; x2r = a[14] + a[30]; x2i = a[15] + a[31]; x3r = a[14] - a[30]; x3i = a[15] - a[31]; y3r = x0r + x2r; y3i = x0i + x2i; y7r = x0r - x2r; y7i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y11r = wk1i * x0r - wk1r * x0i; y11i = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y15r = wk1r * x0r - wk1i * x0i; y15i = wk1r * x0i + wk1i * x0r; x0r = y12r - y14r; x0i = y12i - y14i; x1r = y12r + y14r; x1i = y12i + y14i; x2r = y13r - y15r; x2i = y13i - y15i; x3r = y13r + y15r; x3i = y13i + y15i; a[24] = x0r + x2r; a[25] = x0i + x2i; a[26] = x0r - x2r; a[27] = x0i - x2i; a[28] = x1r - x3i; a[29] = x1i + x3r; a[30] = x1r + x3i; a[31] = x1i - x3r; x0r = y8r + y10r; x0i = y8i + y10i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; x3r = y9r - y11r; x3i = y9i - y11i; a[16] = x0r + x2r; a[17] = x0i + x2i; a[18] = x0r - x2r; a[19] = x0i - x2i; a[20] = x1r - x3i; a[21] = x1i + x3r; a[22] = x1r + x3i; a[23] = x1i - x3r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); x0r = y5r + y7i; x0i = y5i - y7r; x3r = wn4r * (x0r - x0i); x3i = wn4r * (x0i + x0r); x0r = y4r - y6i; x0i = y4i + y6r; x1r = y4r + y6i; x1i = y4i - y6r; a[8] = x0r + x2r; a[9] = x0i + x2i; a[10] = x0r - x2r; a[11] = x0i - x2i; a[12] = x1r - x3i; a[13] = x1i + x3r; a[14] = x1r + x3i; a[15] = x1i - x3r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r + y3r; x2i = y1i + y3i; x3r = y1r - y3r; x3i = y1i - y3i; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x0r - x2r; a[3] = x0i - x2i; a[4] = x1r - x3i; a[5] = x1i + x3r; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftf162(double *a, double *w) { double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = w[1]; wk1r = w[4]; wk1i = w[5]; wk3r = w[6]; wk3i = -w[7]; wk2r = w[8]; wk2i = w[9]; x1r = a[0] - a[17]; x1i = a[1] + a[16]; x0r = a[8] - a[25]; x0i = a[9] + a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y0r = x1r + x2r; y0i = x1i + x2i; y4r = x1r - x2r; y4i = x1i - x2i; x1r = a[0] + a[17]; x1i = a[1] - a[16]; x0r = a[8] + a[25]; x0i = a[9] - a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y8r = x1r - x2i; y8i = x1i + x2r; y12r = x1r + x2i; y12i = x1i - x2r; x0r = a[2] - a[19]; x0i = a[3] + a[18]; x1r = wk1r * x0r - wk1i * x0i; x1i = wk1r * x0i + wk1i * x0r; x0r = a[10] - a[27]; x0i = a[11] + a[26]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y1r = x1r + x2r; y1i = x1i + x2i; y5r = x1r - x2r; y5i = x1i - x2i; x0r = a[2] + a[19]; x0i = a[3] - a[18]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[10] + a[27]; x0i = a[11] - a[26]; x2r = wk1r * x0r + wk1i * x0i; x2i = wk1r * x0i - wk1i * x0r; y9r = x1r - x2r; y9i = x1i - x2i; y13r = x1r + x2r; y13i = x1i + x2i; x0r = a[4] - a[21]; x0i = a[5] + a[20]; x1r = wk2r * x0r - wk2i * x0i; x1i = wk2r * x0i + wk2i * x0r; x0r = a[12] - a[29]; x0i = a[13] + a[28]; x2r = wk2i * x0r - wk2r * x0i; x2i = wk2i * x0i + wk2r * x0r; y2r = x1r + x2r; y2i = x1i + x2i; y6r = x1r - x2r; y6i = x1i - x2i; x0r = a[4] + a[21]; x0i = a[5] - a[20]; x1r = wk2i * x0r - wk2r * x0i; x1i = wk2i * x0i + wk2r * x0r; x0r = a[12] + a[29]; x0i = a[13] - a[28]; x2r = wk2r * x0r - wk2i * x0i; x2i = wk2r * x0i + wk2i * x0r; y10r = x1r - x2r; y10i = x1i - x2i; y14r = x1r + x2r; y14i = x1i + x2i; x0r = a[6] - a[23]; x0i = a[7] + a[22]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[14] - a[31]; x0i = a[15] + a[30]; x2r = wk1i * x0r - wk1r * x0i; x2i = wk1i * x0i + wk1r * x0r; y3r = x1r + x2r; y3i = x1i + x2i; y7r = x1r - x2r; y7i = x1i - x2i; x0r = a[6] + a[23]; x0i = a[7] - a[22]; x1r = wk1i * x0r + wk1r * x0i; x1i = wk1i * x0i - wk1r * x0r; x0r = a[14] + a[31]; x0i = a[15] - a[30]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y11r = x1r + x2r; y11i = x1i + x2i; y15r = x1r - x2r; y15i = x1i - x2i; x1r = y0r + y2r; x1i = y0i + y2i; x2r = y1r + y3r; x2i = y1i + y3i; a[0] = x1r + x2r; a[1] = x1i + x2i; a[2] = x1r - x2r; a[3] = x1i - x2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r - y3r; x2i = y1i - y3i; a[4] = x1r - x2i; a[5] = x1i + x2r; a[6] = x1r + x2i; a[7] = x1i - x2r; x1r = y4r - y6i; x1i = y4i + y6r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[8] = x1r + x2r; a[9] = x1i + x2i; a[10] = x1r - x2r; a[11] = x1i - x2i; x1r = y4r + y6i; x1i = y4i - y6r; x0r = y5r + y7i; x0i = y5i - y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[12] = x1r - x2i; a[13] = x1i + x2r; a[14] = x1r + x2i; a[15] = x1i - x2r; x1r = y8r + y10r; x1i = y8i + y10i; x2r = y9r - y11r; x2i = y9i - y11i; a[16] = x1r + x2r; a[17] = x1i + x2i; a[18] = x1r - x2r; a[19] = x1i - x2i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; a[20] = x1r - x2i; a[21] = x1i + x2r; a[22] = x1r + x2i; a[23] = x1i - x2r; x1r = y12r - y14i; x1i = y12i + y14r; x0r = y13r + y15i; x0i = y13i - y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[24] = x1r + x2r; a[25] = x1i + x2i; a[26] = x1r - x2r; a[27] = x1i - x2i; x1r = y12r + y14i; x1i = y12i - y14r; x0r = y13r - y15i; x0i = y13i + y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[28] = x1r - x2i; a[29] = x1i + x2r; a[30] = x1r + x2i; a[31] = x1i - x2r; } void cftf081(double *a, double *w) { double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = w[1]; x0r = a[0] + a[8]; x0i = a[1] + a[9]; x1r = a[0] - a[8]; x1i = a[1] - a[9]; x2r = a[4] + a[12]; x2i = a[5] + a[13]; x3r = a[4] - a[12]; x3i = a[5] - a[13]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[2] + a[10]; x0i = a[3] + a[11]; x1r = a[2] - a[10]; x1i = a[3] - a[11]; x2r = a[6] + a[14]; x2i = a[7] + a[15]; x3r = a[6] - a[14]; x3i = a[7] - a[15]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[8] = y1r + y5r; a[9] = y1i + y5i; a[10] = y1r - y5r; a[11] = y1i - y5i; a[12] = y3r - y7i; a[13] = y3i + y7r; a[14] = y3r + y7i; a[15] = y3i - y7r; a[0] = y0r + y4r; a[1] = y0i + y4i; a[2] = y0r - y4r; a[3] = y0i - y4i; a[4] = y2r - y6i; a[5] = y2i + y6r; a[6] = y2r + y6i; a[7] = y2i - y6r; } void cftf082(double *a, double *w) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = w[1]; wk1r = w[2]; wk1i = w[3]; y0r = a[0] - a[9]; y0i = a[1] + a[8]; y1r = a[0] + a[9]; y1i = a[1] - a[8]; x0r = a[4] - a[13]; x0i = a[5] + a[12]; y2r = wn4r * (x0r - x0i); y2i = wn4r * (x0i + x0r); x0r = a[4] + a[13]; x0i = a[5] - a[12]; y3r = wn4r * (x0r - x0i); y3i = wn4r * (x0i + x0r); x0r = a[2] - a[11]; x0i = a[3] + a[10]; y4r = wk1r * x0r - wk1i * x0i; y4i = wk1r * x0i + wk1i * x0r; x0r = a[2] + a[11]; x0i = a[3] - a[10]; y5r = wk1i * x0r - wk1r * x0i; y5i = wk1i * x0i + wk1r * x0r; x0r = a[6] - a[15]; x0i = a[7] + a[14]; y6r = wk1i * x0r - wk1r * x0i; y6i = wk1i * x0i + wk1r * x0r; x0r = a[6] + a[15]; x0i = a[7] - a[14]; y7r = wk1r * x0r - wk1i * x0i; y7i = wk1r * x0i + wk1i * x0r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y4r + y6r; x1i = y4i + y6i; a[0] = x0r + x1r; a[1] = x0i + x1i; a[2] = x0r - x1r; a[3] = x0i - x1i; x0r = y0r - y2r; x0i = y0i - y2i; x1r = y4r - y6r; x1i = y4i - y6i; a[4] = x0r - x1i; a[5] = x0i + x1r; a[6] = x0r + x1i; a[7] = x0i - x1r; x0r = y1r - y3i; x0i = y1i + y3r; x1r = y5r - y7r; x1i = y5i - y7i; a[8] = x0r + x1r; a[9] = x0i + x1i; a[10] = x0r - x1r; a[11] = x0i - x1i; x0r = y1r + y3i; x0i = y1i - y3r; x1r = y5r + y7r; x1i = y5i + y7i; a[12] = x0r - x1i; a[13] = x0i + x1r; a[14] = x0r + x1i; a[15] = x0i - x1r; } void cftf040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r - x3i; a[3] = x1i + x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftb040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r + x3i; a[3] = x1i - x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r - x3i; a[7] = x1i + x3r; } void cftx020(double *a) { double x0r, x0i; x0r = a[0] - a[2]; x0i = a[1] - a[3]; a[0] += a[2]; a[1] += a[3]; a[2] = x0r; a[3] = x0i; } void rftfsub(int n, double *a, int nc, double *c) { int j, k, kk, ks, m; double wkr, wki, xr, xi, yr, yi; m = n >> 1; ks = 2 * nc / m; kk = 0; for (j = 2; j < m; j += 2) { k = n - j; kk += ks; wkr = 0.5 - c[nc - kk]; wki = c[kk]; xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; } } void rftbsub(int n, double *a, int nc, double *c) { int j, k, kk, ks, m; double wkr, wki, xr, xi, yr, yi; m = n >> 1; ks = 2 * nc / m; kk = 0; for (j = 2; j < m; j += 2) { k = n - j; kk += ks; wkr = 0.5 - c[nc - kk]; wki = c[kk]; xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr + wki * xi; yi = wkr * xi - wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; } } void dctsub(int n, double *a, int nc, double *c) { int j, k, kk, ks, m; double wkr, wki, xr; m = n >> 1; ks = nc / n; kk = 0; for (j = 1; j < m; j++) { k = n - j; kk += ks; wkr = c[kk] - c[nc - kk]; wki = c[kk] + c[nc - kk]; xr = wki * a[j] - wkr * a[k]; a[j] = wkr * a[j] + wki * a[k]; a[k] = xr; } a[m] *= c[0]; } void dstsub(int n, double *a, int nc, double *c) { int j, k, kk, ks, m; double wkr, wki, xr; m = n >> 1; ks = nc / n; kk = 0; for (j = 1; j < m; j++) { k = n - j; kk += ks; wkr = c[kk] - c[nc - kk]; wki = c[kk] + c[nc - kk]; xr = wki * a[k] - wkr * a[j]; a[k] = wkr * a[k] + wki * a[j]; a[j] = xr; } a[m] *= c[0]; } ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/log.cc ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ /* * Stack trace related stuff is from kaldi. * Refer to * https://github.com/kaldi-asr/kaldi/blob/master/src/base/kaldi-error.cc */ #include "kaldi-native-fbank/csrc/log.h" #ifdef KNF_HAVE_EXECINFO_H #include // To get stack trace in error messages. #ifdef KNF_HAVE_CXXABI_H #include // For name demangling. // Useful to decode the stack trace, but only used if we have execinfo.h #endif // KNF_HAVE_CXXABI_H #endif // KNF_HAVE_EXECINFO_H #include #include #include #include namespace knf { std::string GetDateTimeStr() { std::ostringstream os; std::time_t t = std::time(nullptr); std::tm tm = *std::localtime(&t); os << std::put_time(&tm, "%F %T"); // yyyy-mm-dd hh:mm:ss return os.str(); } static bool LocateSymbolRange(const std::string &trace_name, std::size_t *begin, std::size_t *end) { // Find the first '_' with leading ' ' or '('. *begin = std::string::npos; for (std::size_t i = 1; i < trace_name.size(); ++i) { if (trace_name[i] != '_') { continue; } if (trace_name[i - 1] == ' ' || trace_name[i - 1] == '(') { *begin = i; break; } } if (*begin == std::string::npos) { return false; } *end = trace_name.find_first_of(" +", *begin); return *end != std::string::npos; } #ifdef KNF_HAVE_EXECINFO_H static std::string Demangle(const std::string &trace_name) { #ifndef KNF_HAVE_CXXABI_H return trace_name; #else // KNF_HAVE_CXXABI_H // Try demangle the symbol. We are trying to support the following formats // produced by different platforms: // // Linux: // ./kaldi-error-test(_ZN5kaldi13UnitTestErrorEv+0xb) [0x804965d] // // Mac: // 0 server 0x000000010f67614d _ZNK5kaldi13MessageLogger10LogMessageEv + 813 // // We want to extract the name e.g., '_ZN5kaldi13UnitTestErrorEv' and // demangle it info a readable name like kaldi::UnitTextError. std::size_t begin, end; if (!LocateSymbolRange(trace_name, &begin, &end)) { return trace_name; } std::string symbol = trace_name.substr(begin, end - begin); int status; char *demangled_name = abi::__cxa_demangle(symbol.c_str(), 0, 0, &status); if (status == 0 && demangled_name != nullptr) { symbol = demangled_name; free(demangled_name); } return trace_name.substr(0, begin) + symbol + trace_name.substr(end, std::string::npos); #endif // KNF_HAVE_CXXABI_H } #endif // KNF_HAVE_EXECINFO_H std::string GetStackTrace() { std::string ans; #ifdef KNF_HAVE_EXECINFO_H constexpr const std::size_t kMaxTraceSize = 50; constexpr const std::size_t kMaxTracePrint = 50; // Must be even. // Buffer for the trace. void *trace[kMaxTraceSize]; // Get the trace. std::size_t size = backtrace(trace, kMaxTraceSize); // Get the trace symbols. char **trace_symbol = backtrace_symbols(trace, size); if (trace_symbol == nullptr) return ans; // Compose a human-readable backtrace string. ans += "[ Stack-Trace: ]\n"; if (size <= kMaxTracePrint) { for (std::size_t i = 0; i < size; ++i) { ans += Demangle(trace_symbol[i]) + "\n"; } } else { // Print out first+last (e.g.) 5. for (std::size_t i = 0; i < kMaxTracePrint / 2; ++i) { ans += Demangle(trace_symbol[i]) + "\n"; } ans += ".\n.\n.\n"; for (std::size_t i = size - kMaxTracePrint / 2; i < size; ++i) { ans += Demangle(trace_symbol[i]) + "\n"; } if (size == kMaxTraceSize) ans += ".\n.\n.\n"; // Stack was too long, probably a bug. } // We must free the array of pointers allocated by backtrace_symbols(), // but not the strings themselves. free(trace_symbol); #endif // KNF_HAVE_EXECINFO_H return ans; } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/log.h ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // The content in this file is copied/modified from // https://github.com/k2-fsa/k2/blob/master/k2/csrc/log.h #ifndef KALDI_NATIVE_FBANK_CSRC_LOG_H_ #define KALDI_NATIVE_FBANK_CSRC_LOG_H_ #include #include // NOLINT #include #include namespace knf { #if defined(NDEBUG) constexpr bool kDisableDebug = true; #else constexpr bool kDisableDebug = false; #endif enum class LogLevel { kTrace = 0, kDebug = 1, kInfo = 2, kWarning = 3, kError = 4, kFatal = 5, // print message and abort the program }; // They are used in KNF_LOG(xxx), so their names // do not follow the google c++ code style // // You can use them in the following way: // // KNF_LOG(TRACE) << "some message"; // KNF_LOG(DEBUG) << "some message"; #ifndef _MSC_VER constexpr LogLevel TRACE = LogLevel::kTrace; constexpr LogLevel DEBUG = LogLevel::kDebug; constexpr LogLevel INFO = LogLevel::kInfo; constexpr LogLevel WARNING = LogLevel::kWarning; constexpr LogLevel ERROR = LogLevel::kError; constexpr LogLevel FATAL = LogLevel::kFatal; #else #define TRACE LogLevel::kTrace #define DEBUG LogLevel::kDebug #define INFO LogLevel::kInfo #define WARNING LogLevel::kWarning #define ERROR LogLevel::kError #define FATAL LogLevel::kFatal #endif std::string GetStackTrace(); /* Return the current log level. If the current log level is TRACE, then all logged messages are printed out. If the current log level is DEBUG, log messages with "TRACE" level are not shown and all other levels are printed out. Similarly, if the current log level is INFO, log message with "TRACE" and "DEBUG" are not shown and all other levels are printed out. If it is FATAL, then only FATAL messages are shown. */ inline LogLevel GetCurrentLogLevel() { static LogLevel log_level = INFO; static std::once_flag init_flag; std::call_once(init_flag, []() { const char *env_log_level = std::getenv("KNF_LOG_LEVEL"); if (env_log_level == nullptr) return; std::string s = env_log_level; if (s == "TRACE") log_level = TRACE; else if (s == "DEBUG") log_level = DEBUG; else if (s == "INFO") log_level = INFO; else if (s == "WARNING") log_level = WARNING; else if (s == "ERROR") log_level = ERROR; else if (s == "FATAL") log_level = FATAL; else fprintf(stderr, "Unknown KNF_LOG_LEVEL: %s" "\nSupported values are: " "TRACE, DEBUG, INFO, WARNING, ERROR, FATAL", s.c_str()); }); return log_level; } inline bool EnableAbort() { static std::once_flag init_flag; static bool enable_abort = false; std::call_once(init_flag, []() { enable_abort = (std::getenv("KNF_ABORT") != nullptr); }); return enable_abort; } class Logger { public: Logger(const char *filename, const char *func_name, uint32_t line_num, LogLevel level) : filename_(filename), func_name_(func_name), line_num_(line_num), level_(level) { cur_level_ = GetCurrentLogLevel(); fprintf(stderr, "here\n"); switch (level) { case TRACE: if (cur_level_ <= TRACE) fprintf(stderr, "[T] "); break; case DEBUG: if (cur_level_ <= DEBUG) fprintf(stderr, "[D] "); break; case INFO: if (cur_level_ <= INFO) fprintf(stderr, "[I] "); break; case WARNING: if (cur_level_ <= WARNING) fprintf(stderr, "[W] "); break; case ERROR: if (cur_level_ <= ERROR) fprintf(stderr, "[E] "); break; case FATAL: if (cur_level_ <= FATAL) fprintf(stderr, "[F] "); break; } if (cur_level_ <= level_) { fprintf(stderr, "%s:%u:%s ", filename, line_num, func_name); } } ~Logger() noexcept(false) { static constexpr const char *kErrMsg = R"( Some bad things happened. Please read the above error messages and stack trace. If you are using Python, the following command may be helpful: gdb --args python /path/to/your/code.py (You can use `gdb` to debug the code. Please consider compiling a debug version of KNF.). If you are unable to fix it, please open an issue at: https://github.com/csukuangfj/kaldi-native-fbank/issues/new )"; fprintf(stderr, "\n"); if (level_ == FATAL) { std::string stack_trace = GetStackTrace(); if (!stack_trace.empty()) { fprintf(stderr, "\n\n%s\n", stack_trace.c_str()); } fflush(nullptr); #ifndef __ANDROID_API__ if (EnableAbort()) { // NOTE: abort() will terminate the program immediately without // printing the Python stack backtrace. abort(); } throw std::runtime_error(kErrMsg); #else abort(); #endif } } const Logger &operator<<(bool b) const { if (cur_level_ <= level_) { fprintf(stderr, b ? "true" : "false"); } return *this; } const Logger &operator<<(int8_t i) const { if (cur_level_ <= level_) fprintf(stderr, "%d", i); return *this; } const Logger &operator<<(const char *s) const { if (cur_level_ <= level_) fprintf(stderr, "%s", s); return *this; } const Logger &operator<<(int32_t i) const { if (cur_level_ <= level_) fprintf(stderr, "%d", i); return *this; } const Logger &operator<<(uint32_t i) const { if (cur_level_ <= level_) fprintf(stderr, "%u", i); return *this; } const Logger &operator<<(uint64_t i) const { if (cur_level_ <= level_) fprintf(stderr, "%llu", (long long unsigned int)i); // NOLINT return *this; } const Logger &operator<<(int64_t i) const { if (cur_level_ <= level_) fprintf(stderr, "%lli", (long long int)i); // NOLINT return *this; } const Logger &operator<<(float f) const { if (cur_level_ <= level_) fprintf(stderr, "%f", f); return *this; } const Logger &operator<<(double d) const { if (cur_level_ <= level_) fprintf(stderr, "%f", d); return *this; } template const Logger &operator<<(const T &t) const { // require T overloads operator<< std::ostringstream os; os << t; return *this << os.str().c_str(); } // specialization to fix compile error: `stringstream << nullptr` is ambiguous const Logger &operator<<(const std::nullptr_t &null) const { if (cur_level_ <= level_) *this << "(null)"; return *this; } private: const char *filename_; const char *func_name_; uint32_t line_num_; LogLevel level_; LogLevel cur_level_; }; class Voidifier { public: void operator&(const Logger &)const {} }; } // namespace knf #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || \ defined(__PRETTY_FUNCTION__) // for clang and GCC #define KNF_FUNC __PRETTY_FUNCTION__ #else // for other compilers #define KNF_FUNC __func__ #endif #define KNF_STATIC_ASSERT(x) static_assert(x, "") #define KNF_CHECK(x) \ (x) ? (void)0 \ : ::knf::Voidifier() & \ ::knf::Logger(__FILE__, KNF_FUNC, __LINE__, ::knf::FATAL) \ << "Check failed: " << #x << " " // WARNING: x and y may be evaluated multiple times, but this happens only // when the check fails. Since the program aborts if it fails, we don't think // the extra evaluation of x and y matters. // // CAUTION: we recommend the following use case: // // auto x = Foo(); // auto y = Bar(); // KNF_CHECK_EQ(x, y) << "Some message"; // // And please avoid // // KNF_CHECK_EQ(Foo(), Bar()); // // if `Foo()` or `Bar()` causes some side effects, e.g., changing some // local static variables or global variables. #define _KNF_CHECK_OP(x, y, op) \ ((x)op(y)) ? (void)0 \ : ::knf::Voidifier() & \ ::knf::Logger(__FILE__, KNF_FUNC, __LINE__, ::knf::FATAL) \ << "Check failed: " << #x << " " << #op << " " << #y \ << " (" << (x) << " vs. " << (y) << ") " #define KNF_CHECK_EQ(x, y) _KNF_CHECK_OP(x, y, ==) #define KNF_CHECK_NE(x, y) _KNF_CHECK_OP(x, y, !=) #define KNF_CHECK_LT(x, y) _KNF_CHECK_OP(x, y, <) #define KNF_CHECK_LE(x, y) _KNF_CHECK_OP(x, y, <=) #define KNF_CHECK_GT(x, y) _KNF_CHECK_OP(x, y, >) #define KNF_CHECK_GE(x, y) _KNF_CHECK_OP(x, y, >=) #define KNF_LOG(x) ::knf::Logger(__FILE__, KNF_FUNC, __LINE__, ::knf::x) // ------------------------------------------------------------ // For debug check // ------------------------------------------------------------ // If you define the macro "-D NDEBUG" while compiling kaldi-native-fbank, // the following macros are in fact empty and does nothing. #define KNF_DCHECK(x) ::knf::kDisableDebug ? (void)0 : KNF_CHECK(x) #define KNF_DCHECK_EQ(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_EQ(x, y) #define KNF_DCHECK_NE(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_NE(x, y) #define KNF_DCHECK_LT(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_LT(x, y) #define KNF_DCHECK_LE(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_LE(x, y) #define KNF_DCHECK_GT(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_GT(x, y) #define KNF_DCHECK_GE(x, y) ::knf::kDisableDebug ? (void)0 : KNF_CHECK_GE(x, y) #define KNF_DLOG(x) \ ::knf::kDisableDebug ? (void)0 : ::knf::Voidifier() & KNF_LOG(x) #endif // KALDI_NATIVE_FBANK_CSRC_LOG_H_ ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/mel-computations.cc ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/mel-computations.cc #include "kaldi-native-fbank/csrc/mel-computations.h" #include #include #include "kaldi-native-fbank/csrc/feature-window.h" namespace knf { std::ostream &operator<<(std::ostream &os, const MelBanksOptions &opts) { os << opts.ToString(); return os; } float MelBanks::VtlnWarpFreq( float vtln_low_cutoff, // upper+lower frequency cutoffs for VTLN. float vtln_high_cutoff, float low_freq, // upper+lower frequency cutoffs in mel computation float high_freq, float vtln_warp_factor, float freq) { /// This computes a VTLN warping function that is not the same as HTK's one, /// but has similar inputs (this function has the advantage of never producing /// empty bins). /// This function computes a warp function F(freq), defined between low_freq /// and high_freq inclusive, with the following properties: /// F(low_freq) == low_freq /// F(high_freq) == high_freq /// The function is continuous and piecewise linear with two inflection /// points. /// The lower inflection point (measured in terms of the unwarped /// frequency) is at frequency l, determined as described below. /// The higher inflection point is at a frequency h, determined as /// described below. /// If l <= f <= h, then F(f) = f/vtln_warp_factor. /// If the higher inflection point (measured in terms of the unwarped /// frequency) is at h, then max(h, F(h)) == vtln_high_cutoff. /// Since (by the last point) F(h) == h/vtln_warp_factor, then /// max(h, h/vtln_warp_factor) == vtln_high_cutoff, so /// h = vtln_high_cutoff / max(1, 1/vtln_warp_factor). /// = vtln_high_cutoff * min(1, vtln_warp_factor). /// If the lower inflection point (measured in terms of the unwarped /// frequency) is at l, then min(l, F(l)) == vtln_low_cutoff /// This implies that l = vtln_low_cutoff / min(1, 1/vtln_warp_factor) /// = vtln_low_cutoff * max(1, vtln_warp_factor) if (freq < low_freq || freq > high_freq) return freq; // in case this gets called // for out-of-range frequencies, just return the freq. KNF_CHECK_GT(vtln_low_cutoff, low_freq); KNF_CHECK_LT(vtln_high_cutoff, high_freq); float one = 1.0f; float l = vtln_low_cutoff * std::max(one, vtln_warp_factor); float h = vtln_high_cutoff * std::min(one, vtln_warp_factor); float scale = 1.0f / vtln_warp_factor; float Fl = scale * l; // F(l); float Fh = scale * h; // F(h); KNF_CHECK(l > low_freq && h < high_freq); // slope of left part of the 3-piece linear function float scale_left = (Fl - low_freq) / (l - low_freq); // [slope of center part is just "scale"] // slope of right part of the 3-piece linear function float scale_right = (high_freq - Fh) / (high_freq - h); if (freq < l) { return low_freq + scale_left * (freq - low_freq); } else if (freq < h) { return scale * freq; } else { // freq >= h return high_freq + scale_right * (freq - high_freq); } } float MelBanks::VtlnWarpMelFreq( float vtln_low_cutoff, // upper+lower frequency cutoffs for VTLN. float vtln_high_cutoff, float low_freq, // upper+lower frequency cutoffs in mel computation float high_freq, float vtln_warp_factor, float mel_freq) { return MelScale(VtlnWarpFreq(vtln_low_cutoff, vtln_high_cutoff, low_freq, high_freq, vtln_warp_factor, InverseMelScale(mel_freq))); } MelBanks::MelBanks(const MelBanksOptions &opts, const FrameExtractionOptions &frame_opts, float vtln_warp_factor) : htk_mode_(opts.htk_mode) { int32_t num_bins = opts.num_bins; if (num_bins < 3) KNF_LOG(FATAL) << "Must have at least 3 mel bins"; float sample_freq = frame_opts.samp_freq; int32_t window_length_padded = frame_opts.PaddedWindowSize(); KNF_CHECK_EQ(window_length_padded % 2, 0); int32_t num_fft_bins = window_length_padded / 2; float nyquist = 0.5f * sample_freq; float low_freq = opts.low_freq, high_freq; if (opts.high_freq > 0.0f) high_freq = opts.high_freq; else high_freq = nyquist + opts.high_freq; if (low_freq < 0.0f || low_freq >= nyquist || high_freq <= 0.0f || high_freq > nyquist || high_freq <= low_freq) { KNF_LOG(FATAL) << "Bad values in options: low-freq " << low_freq << " and high-freq " << high_freq << " vs. nyquist " << nyquist; } float fft_bin_width = sample_freq / window_length_padded; // fft-bin width [think of it as Nyquist-freq / half-window-length] float mel_low_freq = MelScale(low_freq); float mel_high_freq = MelScale(high_freq); debug_ = opts.debug_mel; // divide by num_bins+1 in next line because of end-effects where the bins // spread out to the sides. float mel_freq_delta = (mel_high_freq - mel_low_freq) / (num_bins + 1); float vtln_low = opts.vtln_low, vtln_high = opts.vtln_high; if (vtln_high < 0.0f) { vtln_high += nyquist; } if (vtln_warp_factor != 1.0f && (vtln_low < 0.0f || vtln_low <= low_freq || vtln_low >= high_freq || vtln_high <= 0.0f || vtln_high >= high_freq || vtln_high <= vtln_low)) { KNF_LOG(FATAL) << "Bad values in options: vtln-low " << vtln_low << " and vtln-high " << vtln_high << ", versus " << "low-freq " << low_freq << " and high-freq " << high_freq; } bins_.resize(num_bins); center_freqs_.resize(num_bins); for (int32_t bin = 0; bin < num_bins; ++bin) { float left_mel = mel_low_freq + bin * mel_freq_delta, center_mel = mel_low_freq + (bin + 1) * mel_freq_delta, right_mel = mel_low_freq + (bin + 2) * mel_freq_delta; if (vtln_warp_factor != 1.0f) { left_mel = VtlnWarpMelFreq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, left_mel); center_mel = VtlnWarpMelFreq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, center_mel); right_mel = VtlnWarpMelFreq(vtln_low, vtln_high, low_freq, high_freq, vtln_warp_factor, right_mel); } center_freqs_[bin] = InverseMelScale(center_mel); // this_bin will be a vector of coefficients that is only // nonzero where this mel bin is active. std::vector this_bin(num_fft_bins); int32_t first_index = -1, last_index = -1; for (int32_t i = 0; i < num_fft_bins; ++i) { float freq = (fft_bin_width * i); // Center frequency of this fft // bin. float mel = MelScale(freq); if (mel > left_mel && mel < right_mel) { float weight; if (mel <= center_mel) weight = (mel - left_mel) / (center_mel - left_mel); else weight = (right_mel - mel) / (right_mel - center_mel); this_bin[i] = weight; if (first_index == -1) first_index = i; last_index = i; } } KNF_CHECK(first_index != -1 && last_index >= first_index && "You may have set num_mel_bins too large."); bins_[bin].first = first_index; int32_t size = last_index + 1 - first_index; bins_[bin].second.insert(bins_[bin].second.end(), this_bin.begin() + first_index, this_bin.begin() + first_index + size); // Replicate a bug in HTK, for testing purposes. if (opts.htk_mode && bin == 0 && mel_low_freq != 0.0f) { bins_[bin].second[0] = 0.0; } } // for (int32_t bin = 0; bin < num_bins; ++bin) { if (debug_) { std::ostringstream os; for (size_t i = 0; i < bins_.size(); i++) { os << "bin " << i << ", offset = " << bins_[i].first << ", vec = "; for (auto k : bins_[i].second) os << k << ", "; os << "\n"; } KNF_LOG(INFO) << os.str(); } } // "power_spectrum" contains fft energies. void MelBanks::Compute(const float *power_spectrum, float *mel_energies_out) const { int32_t num_bins = bins_.size(); for (int32_t i = 0; i < num_bins; i++) { int32_t offset = bins_[i].first; const auto &v = bins_[i].second; float energy = 0; for (int32_t k = 0; k != v.size(); ++k) { energy += v[k] * power_spectrum[k + offset]; } // HTK-like flooring- for testing purposes (we prefer dither) if (htk_mode_ && energy < 1.0) { energy = 1.0; } mel_energies_out[i] = energy; // The following assert was added due to a problem with OpenBlas that // we had at one point (it was a bug in that library). Just to detect // it early. KNF_CHECK_EQ(energy, energy); // check that energy is not nan } if (debug_) { fprintf(stderr, "MEL BANKS:\n"); for (int32_t i = 0; i < num_bins; i++) fprintf(stderr, " %f", mel_energies_out[i]); fprintf(stderr, "\n"); } } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/mel-computations.h ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ // This file is copied/modified from kaldi/src/feat/mel-computations.h #ifndef KALDI_NATIVE_FBANK_CSRC_MEL_COMPUTATIONS_H_ #define KALDI_NATIVE_FBANK_CSRC_MEL_COMPUTATIONS_H_ #include #include #include "kaldi-native-fbank/csrc/feature-window.h" namespace knf { struct MelBanksOptions { int32_t num_bins = 25; // e.g. 25; number of triangular bins float low_freq = 20; // e.g. 20; lower frequency cutoff // an upper frequency cutoff; 0 -> no cutoff, negative // ->added to the Nyquist frequency to get the cutoff. float high_freq = 0; float vtln_low = 100; // vtln lower cutoff of warping function. // vtln upper cutoff of warping function: if negative, added // to the Nyquist frequency to get the cutoff. float vtln_high = -500; bool debug_mel = false; // htk_mode is a "hidden" config, it does not show up on command line. // Enables more exact compatibility with HTK, for testing purposes. Affects // mel-energy flooring and reproduces a bug in HTK. bool htk_mode = false; std::string ToString() const { std::ostringstream os; os << "num_bins: " << num_bins << "\n"; os << "low_freq: " << low_freq << "\n"; os << "high_freq: " << high_freq << "\n"; os << "vtln_low: " << vtln_low << "\n"; os << "vtln_high: " << vtln_high << "\n"; os << "debug_mel: " << debug_mel << "\n"; os << "htk_mode: " << htk_mode << "\n"; return os.str(); } }; std::ostream &operator<<(std::ostream &os, const MelBanksOptions &opts); class MelBanks { public: static inline float InverseMelScale(float mel_freq) { return 700.0f * (expf(mel_freq / 1127.0f) - 1.0f); } static inline float MelScale(float freq) { return 1127.0f * logf(1.0f + freq / 700.0f); } static float VtlnWarpFreq( float vtln_low_cutoff, float vtln_high_cutoff, // discontinuities in warp func float low_freq, float high_freq, // upper+lower frequency cutoffs in // the mel computation float vtln_warp_factor, float freq); static float VtlnWarpMelFreq(float vtln_low_cutoff, float vtln_high_cutoff, float low_freq, float high_freq, float vtln_warp_factor, float mel_freq); // TODO(fangjun): Remove vtln_warp_factor MelBanks(const MelBanksOptions &opts, const FrameExtractionOptions &frame_opts, float vtln_warp_factor); /// Compute Mel energies (note: not log energies). /// At input, "fft_energies" contains the FFT energies (not log). /// /// @param fft_energies 1-D array of size num_fft_bins/2+1 /// @param mel_energies_out 1-D array of size num_mel_bins void Compute(const float *fft_energies, float *mel_energies_out) const; int32_t NumBins() const { return bins_.size(); } private: // center frequencies of bins, numbered from 0 ... num_bins-1. // Needed by GetCenterFreqs(). std::vector center_freqs_; // the "bins_" vector is a vector, one for each bin, of a pair: // (the first nonzero fft-bin), (the vector of weights). std::vector>> bins_; // TODO(fangjun): Remove debug_ and htk_mode_ bool debug_; bool htk_mode_; }; } // namespace knf #endif // KALDI_NATIVE_FBANK_CSRC_MEL_COMPUTATIONS_H_ ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/rfft.cc ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ #include "kaldi-native-fbank/csrc/rfft.h" #include #include #include "kaldi-native-fbank/csrc/log.h" // see fftsg.c #ifdef __cplusplus extern "C" void rdft(int n, int isgn, double *a, int *ip, double *w); #else void rdft(int n, int isgn, double *a, int *ip, double *w); #endif namespace knf { class Rfft::RfftImpl { public: explicit RfftImpl(int32_t n) : n_(n), ip_(2 + std::sqrt(n / 2)), w_(n / 2) { KNF_CHECK_EQ(n & (n - 1), 0); } void Compute(float *in_out) { std::vector d(in_out, in_out + n_); Compute(d.data()); std::copy(d.begin(), d.end(), in_out); } void Compute(double *in_out) { // 1 means forward fft rdft(n_, 1, in_out, ip_.data(), w_.data()); } private: int32_t n_; std::vector ip_; std::vector w_; }; Rfft::Rfft(int32_t n) : impl_(std::make_unique(n)) {} Rfft::~Rfft() = default; void Rfft::Compute(float *in_out) { impl_->Compute(in_out); } void Rfft::Compute(double *in_out) { impl_->Compute(in_out); } } // namespace knf ================================================ FILE: audio/paddleaudio/third_party/kaldi-native-fbank/csrc/rfft.h ================================================ /** * Copyright (c) 2022 Xiaomi Corporation (authors: Fangjun Kuang) * * 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. */ #ifndef KALDI_NATIVE_FBANK_CSRC_RFFT_H_ #define KALDI_NATIVE_FBANK_CSRC_RFFT_H_ #include namespace knf { // n-point Real discrete Fourier transform // where n is a power of 2. n >= 2 // // R[k] = sum_j=0^n-1 in[j]*cos(2*pi*j*k/n), 0<=k<=n/2 // I[k] = sum_j=0^n-1 in[j]*sin(2*pi*j*k/n), 0 impl_; }; } // namespace knf #endif // KALDI_NATIVE_FBANK_CSRC_RFFT_H_ ================================================ FILE: audio/paddleaudio/third_party/patches/config.guess ================================================ #! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-09' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 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." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI=${LIBC}x32 fi fi GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; x86_64:Haiku:*:*) GUESS=x86_64-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ================================================ FILE: audio/paddleaudio/third_party/patches/config.sub ================================================ #! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 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." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ================================================ FILE: audio/paddleaudio/third_party/patches/libmad.patch ================================================ See the followings for the origin of this patch http://www.linuxfromscratch.org/blfs/view/svn/multimedia/libmad.html http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch --- src/libmad/configure 2004-02-05 09:34:07.000000000 +0000 +++ src/libmad/configure.new 2020-06-30 21:10:28.528018931 +0000 @@ -19083,71 +19083,7 @@ if test "$GCC" = yes then - if test -z "$arch" - then - case "$host" in - i386-*) ;; - i?86-*) arch="-march=i486" ;; - arm*-empeg-*) arch="-march=armv4 -mtune=strongarm1100" ;; - armv4*-*) arch="-march=armv4 -mtune=strongarm" ;; - powerpc-*) ;; - mips*-agenda-*) arch="-mcpu=vr4100" ;; - mips*-luxsonor-*) arch="-mips1 -mcpu=r3000 -Wa,-m4010" ;; - esac - fi - - case "$optimize" in - -O|"-O "*) - optimize="-O" - optimize="$optimize -fforce-mem" - optimize="$optimize -fforce-addr" - : #x optimize="$optimize -finline-functions" - : #- optimize="$optimize -fstrength-reduce" - optimize="$optimize -fthread-jumps" - optimize="$optimize -fcse-follow-jumps" - optimize="$optimize -fcse-skip-blocks" - : #x optimize="$optimize -frerun-cse-after-loop" - : #x optimize="$optimize -frerun-loop-opt" - : #x optimize="$optimize -fgcse" - optimize="$optimize -fexpensive-optimizations" - optimize="$optimize -fregmove" - : #* optimize="$optimize -fdelayed-branch" - : #x optimize="$optimize -fschedule-insns" - optimize="$optimize -fschedule-insns2" - : #? optimize="$optimize -ffunction-sections" - : #? optimize="$optimize -fcaller-saves" - : #> optimize="$optimize -funroll-loops" - : #> optimize="$optimize -funroll-all-loops" - : #x optimize="$optimize -fmove-all-movables" - : #x optimize="$optimize -freduce-all-givs" - : #? optimize="$optimize -fstrict-aliasing" - : #* optimize="$optimize -fstructure-noalias" - - case "$host" in - arm*-*) - optimize="$optimize -fstrength-reduce" - ;; - mips*-*) - optimize="$optimize -fstrength-reduce" - optimize="$optimize -finline-functions" - ;; - i?86-*) - optimize="$optimize -fstrength-reduce" - ;; - powerpc-apple-*) - # this triggers an internal compiler error with gcc2 - : #optimize="$optimize -fstrength-reduce" - - # this is really only beneficial with gcc3 - : #optimize="$optimize -finline-functions" - ;; - *) - # this sometimes provokes bugs in gcc 2.95.2 - : #optimize="$optimize -fstrength-reduce" - ;; - esac - ;; - esac + optimize="-O2" fi case "$host" in @@ -21497,6 +21433,7 @@ then case "$host" in i?86-*) FPM="INTEL" ;; + x86_64*) FPM="64BIT" ;; arm*-*) FPM="ARM" ;; mips*-*) FPM="MIPS" ;; sparc*-*) FPM="SPARC" ;; ================================================ FILE: audio/paddleaudio/third_party/patches/sox.patch ================================================ See https://github.com/pytorch/audio/pull/1297 diff -ru sox/src/formats.c sox/src/formats.c --- sox/src/formats.c 2014-10-26 19:55:50.000000000 -0700 +++ sox/src/formats.c 2021-02-22 16:01:02.833144070 -0800 @@ -333,6 +333,10 @@ assert(ft); if (!ft->fp) return sox_false; - fstat(fileno((FILE*)ft->fp), &st); + int fd = fileno((FILE*)ft->fp); + if (fd < 0) + return sox_false; + if (fstat(fd, &st) < 0) + return sox_false; return ((st.st_mode & S_IFMT) == S_IFREG); } ================================================ FILE: audio/paddleaudio/third_party/sox/CMakeLists.txt ================================================ find_package(PkgConfig REQUIRED) include(ExternalProject) set(INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../install) set(ARCHIVE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../archives) set(patch_dir ${CMAKE_CURRENT_SOURCE_DIR}/../patches) set(COMMON_ARGS --quiet --disable-shared --enable-static --prefix=${INSTALL_DIR} --with-pic --disable-dependency-tracking --disable-debug --disable-examples --disable-doc) # To pass custom environment variables to ExternalProject_Add command, # we need to do `${CMAKE_COMMAND} -E env ${envs} `. # https://stackoverflow.com/a/62437353 # We construct the custom environment variables here set(envs "PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig" "LDFLAGS=-L${INSTALL_DIR}/lib $ENV{LDFLAGS}" "CFLAGS=-I${INSTALL_DIR}/include -fvisibility=hidden $ENV{CFLAGS}" ) if (BUILD_MAD) ExternalProject_Add(mad PREFIX ${CMAKE_CURRENT_BINARY_DIR} DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://downloads.sourceforge.net/project/mad/libmad/0.15.1b/libmad-0.15.1b.tar.gz URL_HASH SHA256=bbfac3ed6bfbc2823d3775ebb931087371e142bb0e9bb1bee51a76a6e0078690 PATCH_COMMAND patch < ${patch_dir}/libmad.patch && cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/mad/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/mad/configure ${COMMON_ARGS} DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) endif (BUILD_MAD) ExternalProject_Add(amr PREFIX ${CMAKE_CURRENT_BINARY_DIR} DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.5.tar.gz URL_HASH SHA256=2c006cb9d5f651bfb5e60156dbff6af3c9d35c7bbcc9015308c0aff1e14cd341 PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/amr/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/amr/configure ${COMMON_ARGS} DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(lame PREFIX ${CMAKE_CURRENT_BINARY_DIR} DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz URL_HASH SHA256=24346b4158e4af3bd9f2e194bb23eb473c75fb7377011523353196b19b9a23ff PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/lame/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/lame/configure ${COMMON_ARGS} --enable-nasm DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(ogg PREFIX ${CMAKE_CURRENT_BINARY_DIR} DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gz URL_HASH SHA256=c2e8a485110b97550f453226ec644ebac6cb29d1caef2902c007edab4308d985 PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/ogg/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/ogg/configure ${COMMON_ARGS} DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(flac PREFIX ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ogg DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.2.tar.xz URL_HASH SHA256=91cfc3ed61dc40f47f050a109b08610667d73477af6ef36dcad31c31a4a8d53f PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/flac/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/flac/configure ${COMMON_ARGS} --with-ogg --disable-cpplibs DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(vorbis PREFIX ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ogg DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gz URL_HASH SHA256=6ed40e0241089a42c48604dc00e362beee00036af2d8b3f46338031c9e0351cb PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/vorbis/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/vorbis/configure ${COMMON_ARGS} --with-ogg DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(opus PREFIX ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ogg DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://ftp.osuosl.org/pub/xiph/releases/opus/opus-1.3.1.tar.gz URL_HASH SHA256=65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/opus/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/opus/configure ${COMMON_ARGS} --with-ogg DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) ExternalProject_Add(opusfile PREFIX ${CMAKE_CURRENT_BINARY_DIR} DEPENDS opus DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://ftp.osuosl.org/pub/xiph/releases/opus/opusfile-0.12.tar.gz URL_HASH SHA256=118d8601c12dd6a44f52423e68ca9083cc9f2bfe72da7a8c1acb22a80ae3550b PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/opusfile/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/opusfile/configure ${COMMON_ARGS} --disable-http DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) # OpenMP is by default compiled against GNU OpenMP, which conflicts with the version of OpenMP that PyTorch uses. # See https://github.com/pytorch/audio/pull/1026 # TODO: Add flags like https://github.com/suphoff/pytorch_parallel_extension_cpp/blob/master/setup.py set(SOX_OPTIONS --disable-openmp --with-amrnb --with-amrwb --with-flac --with-lame --with-oggvorbis --with-opus --without-alsa --without-ao --without-coreaudio --without-oss --without-id3tag --without-ladspa --without-magic --without-png --without-pulseaudio --without-sndfile --without-sndio --without-sunaudio --without-waveaudio --without-wavpack --without-twolame ) set(SOX_LIBRARIES ${INSTALL_DIR}/lib/libsox.a ${INSTALL_DIR}/lib/libopencore-amrnb.a ${INSTALL_DIR}/lib/libopencore-amrwb.a ${INSTALL_DIR}/lib/libmp3lame.a ${INSTALL_DIR}/lib/libFLAC.a ${INSTALL_DIR}/lib/libopusfile.a ${INSTALL_DIR}/lib/libopus.a ${INSTALL_DIR}/lib/libvorbisenc.a ${INSTALL_DIR}/lib/libvorbisfile.a ${INSTALL_DIR}/lib/libvorbis.a ${INSTALL_DIR}/lib/libogg.a ) set(sox_depends ogg flac vorbis opusfile lame amr ) if (BUILD_MAD) list( APPEND SOX_OPTIONS --with-mad ) list( APPEND SOX_LIBRARIES ${INSTALL_DIR}/lib/libmad.a ) list( APPEND sox_depends mad ) else () list( APPEND SOX_OPTIONS --without-mad ) endif (BUILD_MAD) ExternalProject_Add(sox PREFIX ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${sox_depends} DOWNLOAD_DIR ${ARCHIVE_DIR} URL https://downloads.sourceforge.net/project/sox/sox/14.4.2/sox-14.4.2.tar.bz2 URL_HASH SHA256=81a6956d4330e75b5827316e44ae381e6f1e8928003c6aa45896da9041ea149c PATCH_COMMAND patch -p1 < ${patch_dir}/sox.patch && cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/sox/ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/sox/configure ${COMMON_ARGS} ${SOX_OPTIONS} BUILD_BYPRODUCTS ${SOX_LIBRARIES} DOWNLOAD_NO_PROGRESS ON LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_MERGED_STDOUTERR ON LOG_OUTPUT_ON_FAILURE ON ) add_library(libsox INTERFACE) add_dependencies(libsox sox) target_include_directories(libsox INTERFACE ${INSTALL_DIR}/include) target_link_libraries(libsox INTERFACE ${SOX_LIBRARIES}) ================================================ FILE: audio/paddleaudio/utils/__init__.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. from .download import decompress from .download import download_and_decompress from .download import load_state_dict_from_url from .env import DATA_HOME from .env import MODEL_HOME from .env import PPAUDIO_HOME from .env import USER_HOME from .error import ParameterError from .log import Logger from .log import logger from .numeric import depth_convert from .numeric import pcm16to32 from .time import seconds_to_hms from .time import Timer ================================================ FILE: audio/paddleaudio/utils/download.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import os from typing import Dict from typing import List from paddle.framework import load as load_state_dict from paddle.utils import download from .log import logger download.logger = logger __all__ = [ 'decompress', 'download_and_decompress', 'load_state_dict_from_url', ] def decompress(file: str): """ Extracts all files from a compressed file. """ assert os.path.isfile(file), "File: {} not exists.".format(file) download._decompress(file) def download_and_decompress(archives: List[Dict[str, str]], path: str, decompress: bool=True): """ Download archives and decompress to specific path. """ if not os.path.isdir(path): os.makedirs(path) for archive in archives: assert 'url' in archive and 'md5' in archive, \ 'Dictionary keys of "url" and "md5" are required in the archive, but got: {list(archive.keys())}' download.get_path_from_url( archive['url'], path, archive['md5'], decompress=decompress) def load_state_dict_from_url(url: str, path: str, md5: str=None): """ Download and load a state dict from url """ if not os.path.isdir(path): os.makedirs(path) download.get_path_from_url(url, path, md5) return load_state_dict(os.path.join(path, os.path.basename(url))) ================================================ FILE: audio/paddleaudio/utils/env.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. ''' This module is used to store environmental variables in PaddleAudio. PPAUDIO_HOME --> the root directory for storing PaddleAudio related data. Default to ~/.paddleaudio. Users can change the ├ default value through the PPAUDIO_HOME environment variable. ├─ MODEL_HOME --> Store model files. └─ DATA_HOME --> Store automatically downloaded datasets. ''' import os __all__ = [ 'USER_HOME', 'PPAUDIO_HOME', 'MODEL_HOME', 'DATA_HOME', ] def _get_user_home(): return os.path.expanduser('~') def _get_ppaudio_home(): if 'PPAUDIO_HOME' in os.environ: home_path = os.environ['PPAUDIO_HOME'] if os.path.exists(home_path): if os.path.isdir(home_path): return home_path else: raise RuntimeError( 'The environment variable PPAUDIO_HOME {} is not a directory.'. format(home_path)) else: return home_path return os.path.join(_get_user_home(), '.paddleaudio') def _get_sub_home(directory): home = os.path.join(_get_ppaudio_home(), directory) if not os.path.exists(home): os.makedirs(home) return home USER_HOME = _get_user_home() PPAUDIO_HOME = _get_ppaudio_home() MODEL_HOME = _get_sub_home('models') DATA_HOME = _get_sub_home('datasets') ================================================ FILE: audio/paddleaudio/utils/error.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. __all__ = ['ParameterError'] class ParameterError(Exception): """Exception class for Parameter checking""" pass ================================================ FILE: audio/paddleaudio/utils/log.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import contextlib import functools import logging import threading import time import colorlog __all__ = [ 'Logger', 'logger', ] log_config = { 'DEBUG': { 'level': 10, 'color': 'purple' }, 'INFO': { 'level': 20, 'color': 'green' }, 'TRAIN': { 'level': 21, 'color': 'cyan' }, 'EVAL': { 'level': 22, 'color': 'blue' }, 'WARNING': { 'level': 30, 'color': 'yellow' }, 'ERROR': { 'level': 40, 'color': 'red' }, 'CRITICAL': { 'level': 50, 'color': 'bold_red' } } class Logger(object): ''' Default logger in PaddleAudio Args: name(str) : Logger name, default is 'PaddleAudio' ''' def __init__(self, name: str=None): name = 'PaddleAudio' if not name else name self.logger = logging.getLogger(name) for key, conf in log_config.items(): logging.addLevelName(conf['level'], key) self.__dict__[key] = functools.partial(self.__call__, conf['level']) self.__dict__[key.lower()] = functools.partial(self.__call__, conf['level']) self.format = colorlog.ColoredFormatter( '%(log_color)s[%(asctime)-15s] [%(levelname)8s]%(reset)s - %(message)s', log_colors={key: conf['color'] for key, conf in log_config.items()}) self.handler = logging.StreamHandler() self.handler.setFormatter(self.format) self.logger.addHandler(self.handler) self.logLevel = 'DEBUG' self.logger.setLevel(logging.DEBUG) self.logger.propagate = False self._is_enable = True def disable(self): self._is_enable = False def enable(self): self._is_enable = True @property def is_enable(self) -> bool: return self._is_enable def __call__(self, log_level: str, msg: str): if not self.is_enable: return self.logger.log(log_level, msg) @contextlib.contextmanager def use_terminator(self, terminator: str): old_terminator = self.handler.terminator self.handler.terminator = terminator yield self.handler.terminator = old_terminator @contextlib.contextmanager def processing(self, msg: str, interval: float=0.1): ''' Continuously print a progress bar with rotating special effects. Args: msg(str): Message to be printed. interval(float): Rotation interval. Default to 0.1. ''' end = False def _printer(): index = 0 flags = ['\\', '|', '/', '-'] while not end: flag = flags[index % len(flags)] with self.use_terminator('\r'): self.info('{}: {}'.format(msg, flag)) time.sleep(interval) index += 1 t = threading.Thread(target=_printer) t.start() yield end = True logger = Logger() ================================================ FILE: audio/paddleaudio/utils/numeric.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. from typing import Union import numpy as np __all__ = ["pcm16to32", "depth_convert"] def pcm16to32(audio: np.ndarray) -> np.ndarray: """pcm int16 to float32 Args: audio (np.ndarray): Waveform with dtype of int16. Returns: np.ndarray: Waveform with dtype of float32. """ if audio.dtype == np.int16: audio = audio.astype("float32") bits = np.iinfo(np.int16).bits audio = audio / (2**(bits - 1)) return audio def _safe_cast(y: np.ndarray, dtype: Union[type, str]) -> np.ndarray: """Data type casting in a safe way, i.e., prevent overflow or underflow. Args: y (np.ndarray): Input waveform array in 1D or 2D. dtype (Union[type, str]): Data type of waveform. Returns: np.ndarray: `y` after safe casting. """ if 'float' in str(y.dtype): return np.clip(y, np.finfo(dtype).min, np.finfo(dtype).max).astype(dtype) else: return np.clip(y, np.iinfo(dtype).min, np.iinfo(dtype).max).astype(dtype) def depth_convert(y: np.ndarray, dtype: Union[type, str]) -> np.ndarray: """Convert audio array to target dtype safely. This function convert audio waveform to a target dtype, with addition steps of preventing overflow/underflow and preserving audio range. Args: y (np.ndarray): Input waveform array in 1D or 2D. dtype (Union[type, str]): Data type of waveform. Returns: np.ndarray: `y` after safe casting. """ SUPPORT_DTYPE = ['int16', 'int8', 'float32', 'float64'] if y.dtype not in SUPPORT_DTYPE: raise ParameterError( 'Unsupported audio dtype, ' f'y.dtype is {y.dtype}, supported dtypes are {SUPPORT_DTYPE}') if dtype not in SUPPORT_DTYPE: raise ParameterError( 'Unsupported audio dtype, ' f'target dtype is {dtype}, supported dtypes are {SUPPORT_DTYPE}') if dtype == y.dtype: return y if dtype == 'float64' and y.dtype == 'float32': return _safe_cast(y, dtype) if dtype == 'float32' and y.dtype == 'float64': return _safe_cast(y, dtype) if dtype == 'int16' or dtype == 'int8': if y.dtype in ['float64', 'float32']: factor = np.iinfo(dtype).max y = np.clip(y * factor, np.iinfo(dtype).min, np.iinfo(dtype).max).astype(dtype) y = y.astype(dtype) else: if dtype == 'int16' and y.dtype == 'int8': factor = np.iinfo('int16').max / np.iinfo('int8').max - EPS y = y.astype('float32') * factor y = y.astype('int16') else: # dtype == 'int8' and y.dtype=='int16': y = y.astype('int32') * np.iinfo('int8').max / \ np.iinfo('int16').max y = y.astype('int8') if dtype in ['float32', 'float64']: org_dtype = y.dtype y = y.astype(dtype) / np.iinfo(org_dtype).max return y ================================================ FILE: audio/paddleaudio/utils/sox_utils.py ================================================ from typing import Dict from typing import List import paddleaudio from paddleaudio._internal import module_utils as _mod_utils @_mod_utils.requires_sox() def set_seed(seed: int): """Set libsox's PRNG Args: seed (int): seed value. valid range is int32. See Also: http://sox.sourceforge.net/sox.html """ paddleaudio._paddleaudio.sox_utils_set_seed(seed) @_mod_utils.requires_sox() def set_verbosity(verbosity: int): """Set libsox's verbosity Args: verbosity (int): Set verbosity level of libsox. * ``1`` failure messages * ``2`` warnings * ``3`` details of processing * ``4``-``6`` increasing levels of debug messages See Also: http://sox.sourceforge.net/sox.html """ paddleaudio._paddleaudio.sox_utils_set_verbosity(verbosity) @_mod_utils.requires_sox() def set_buffer_size(buffer_size: int): """Set buffer size for sox effect chain Args: buffer_size (int): Set the size in bytes of the buffers used for processing audio. See Also: http://sox.sourceforge.net/sox.html """ paddleaudio._paddleaudio.sox_utils_set_buffer_size(buffer_size) @_mod_utils.requires_sox() def set_use_threads(use_threads: bool): """Set multithread option for sox effect chain Args: use_threads (bool): When ``True``, enables ``libsox``'s parallel effects channels processing. To use multithread, the underlying ``libsox`` has to be compiled with OpenMP support. See Also: http://sox.sourceforge.net/sox.html """ paddleaudio._paddleaudio.sox_utils_set_use_threads(use_threads) @_mod_utils.requires_sox() def list_effects() -> Dict[str, str]: """List the available sox effect names Returns: Dict[str, str]: Mapping from ``effect name`` to ``usage`` """ return dict(paddleaudio._paddleaudio.sox_utils_list_effects()) @_mod_utils.requires_sox() def list_read_formats() -> List[str]: """List the supported audio formats for read Returns: List[str]: List of supported audio formats """ return paddleaudio._paddleaudio.sox_utils_list_read_formats() @_mod_utils.requires_sox() def list_write_formats() -> List[str]: """List the supported audio formats for write Returns: List[str]: List of supported audio formats """ return paddleaudio._paddleaudio.sox_utils_list_write_formats() @_mod_utils.requires_sox() def get_buffer_size() -> int: """Get buffer size for sox effect chain Returns: int: size in bytes of buffers used for processing audio. """ return paddleaudio._paddleaudio.sox_utils_get_buffer_size() ================================================ FILE: audio/paddleaudio/utils/tensor_utils.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Utility functions for Transformer.""" from typing import List from typing import Tuple import paddle from .log import Logger __all__ = ["pad_sequence", "add_sos_eos", "th_accuracy", "has_tensor"] logger = Logger(__name__) def has_tensor(val): if isinstance(val, (list, tuple)): for item in val: if has_tensor(item): return True elif isinstance(val, dict): for k, v in val.items(): print(k) if has_tensor(v): return True else: return paddle.is_tensor(val) def pad_sequence(sequences: List[paddle.Tensor], batch_first: bool=False, padding_value: float=0.0) -> paddle.Tensor: r"""Pad a list of variable length Tensors with ``padding_value`` ``pad_sequence`` stacks a list of Tensors along a new dimension, and pads them to equal length. For example, if the input is list of sequences with size ``L x *`` and if batch_first is False, and ``T x B x *`` otherwise. `B` is batch size. It is equal to the number of elements in ``sequences``. `T` is length of the longest sequence. `L` is length of the sequence. `*` is any number of trailing dimensions, including none. Example: >>> from paddle.nn.utils.rnn import pad_sequence >>> a = paddle.ones(25, 300) >>> b = paddle.ones(22, 300) >>> c = paddle.ones(15, 300) >>> pad_sequence([a, b, c]).shape paddle.Tensor([25, 3, 300]) Note: This function returns a Tensor of size ``T x B x *`` or ``B x T x *`` where `T` is the length of the longest sequence. This function assumes trailing dimensions and type of all the Tensors in sequences are same. Args: sequences (list[Tensor]): list of variable length sequences. batch_first (bool, optional): output will be in ``B x T x *`` if True, or in ``T x B x *`` otherwise padding_value (float, optional): value for padded elements. Default: 0. Returns: Tensor of size ``T x B x *`` if :attr:`batch_first` is ``False``. Tensor of size ``B x T x *`` otherwise """ # assuming trailing dimensions and type of all the Tensors # in sequences are same and fetching those from sequences[0] max_size = paddle.shape(sequences[0]) # (TODO Hui Zhang): slice not support `end==start` # trailing_dims = max_size[1:] trailing_dims = tuple( max_size[1:].numpy().tolist()) if sequences[0].ndim >= 2 else () max_len = max([s.shape[0] for s in sequences]) if batch_first: out_dims = (len(sequences), max_len) + trailing_dims else: out_dims = (max_len, len(sequences)) + trailing_dims out_tensor = paddle.full(out_dims, padding_value, sequences[0].dtype) for i, tensor in enumerate(sequences): length = tensor.shape[0] # use index notation to prevent duplicate references to the tensor if batch_first: # TODO (Hui Zhang): set_value op not support `end==start` # TODO (Hui Zhang): set_value op not support int16 # TODO (Hui Zhang): set_varbase 2 rank not support [0,0,...] # out_tensor[i, :length, ...] = tensor if length != 0: out_tensor[i, :length] = tensor else: out_tensor[i, length] = tensor else: # TODO (Hui Zhang): set_value op not support `end==start` # out_tensor[:length, i, ...] = tensor if length != 0: out_tensor[:length, i] = tensor else: out_tensor[length, i] = tensor return out_tensor def add_sos_eos(ys_pad: paddle.Tensor, sos: int, eos: int, ignore_id: int) -> Tuple[paddle.Tensor, paddle.Tensor]: """Add and labels. Args: ys_pad (paddle.Tensor): batch of padded target sequences (B, Lmax) sos (int): index of eos (int): index of ignore_id (int): index of padding Returns: ys_in (paddle.Tensor) : (B, Lmax + 1) ys_out (paddle.Tensor) : (B, Lmax + 1) Examples: >>> sos_id = 10 >>> eos_id = 11 >>> ignore_id = -1 >>> ys_pad tensor([[ 1, 2, 3, 4, 5], [ 4, 5, 6, -1, -1], [ 7, 8, 9, -1, -1]], dtype=paddle.int32) >>> ys_in,ys_out=add_sos_eos(ys_pad, sos_id , eos_id, ignore_id) >>> ys_in tensor([[10, 1, 2, 3, 4, 5], [10, 4, 5, 6, 11, 11], [10, 7, 8, 9, 11, 11]]) >>> ys_out tensor([[ 1, 2, 3, 4, 5, 11], [ 4, 5, 6, 11, -1, -1], [ 7, 8, 9, 11, -1, -1]]) """ # TODO(Hui Zhang): using comment code, #_sos = paddle.to_tensor( # [sos], dtype=paddle.long, stop_gradient=True, place=ys_pad.place) #_eos = paddle.to_tensor( # [eos], dtype=paddle.long, stop_gradient=True, place=ys_pad.place) #ys = [y[y != ignore_id] for y in ys_pad] # parse padded ys #ys_in = [paddle.cat([_sos, y], dim=0) for y in ys] #ys_out = [paddle.cat([y, _eos], dim=0) for y in ys] #return pad_sequence(ys_in, padding_value=eos), pad_sequence(ys_out, padding_value=ignore_id) B = ys_pad.shape[0] _sos = paddle.ones([B, 1], dtype=ys_pad.dtype) * sos _eos = paddle.ones([B, 1], dtype=ys_pad.dtype) * eos ys_in = paddle.cat([_sos, ys_pad], dim=1) mask_pad = (ys_in == ignore_id) ys_in = ys_in.masked_fill(mask_pad, eos) ys_out = paddle.cat([ys_pad, _eos], dim=1) ys_out = ys_out.masked_fill(mask_pad, eos) mask_eos = (ys_out == ignore_id) ys_out = ys_out.masked_fill(mask_eos, eos) ys_out = ys_out.masked_fill(mask_pad, ignore_id) return ys_in, ys_out def th_accuracy(pad_outputs: paddle.Tensor, pad_targets: paddle.Tensor, ignore_label: int) -> float: """Calculate accuracy. Args: pad_outputs (Tensor): Prediction tensors (B * Lmax, D). pad_targets (LongTensor): Target label tensors (B, Lmax, D). ignore_label (int): Ignore label id. Returns: float: Accuracy value (0.0 - 1.0). """ pad_pred = pad_outputs.reshape( [pad_targets.shape[0], pad_targets.shape[1], pad_outputs.shape[1]]).argmax(2) mask = pad_targets != ignore_label #TODO(Hui Zhang): sum not support bool type # numerator = paddle.sum( # pad_pred.masked_select(mask) == pad_targets.masked_select(mask)) numerator = ( pad_pred.masked_select(mask) == pad_targets.masked_select(mask)) numerator = paddle.sum(numerator.type_as(pad_targets)) #TODO(Hui Zhang): sum not support bool type # denominator = paddle.sum(mask) denominator = paddle.sum(mask.type_as(pad_targets)) return float(numerator) / float(denominator) ================================================ FILE: audio/paddleaudio/utils/time.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. import math import time __all__ = [ 'Timer', 'seconds_to_hms', ] class Timer(object): '''Calculate running speed and estimated time of arrival(ETA)''' def __init__(self, total_step: int): self.total_step = total_step self.last_start_step = 0 self.current_step = 0 self._is_running = True def start(self): self.last_time = time.time() self.start_time = time.time() def stop(self): self._is_running = False self.end_time = time.time() def count(self) -> int: if not self.current_step >= self.total_step: self.current_step += 1 return self.current_step @property def timing(self) -> float: run_steps = self.current_step - self.last_start_step self.last_start_step = self.current_step time_used = time.time() - self.last_time self.last_time = time.time() return run_steps / time_used @property def is_running(self) -> bool: return self._is_running @property def eta(self) -> str: if not self.is_running: return '00:00:00' scale = self.total_step / self.current_step remaining_time = (time.time() - self.start_time) * scale return seconds_to_hms(remaining_time) def seconds_to_hms(seconds: int) -> str: '''Convert the number of seconds to hh:mm:ss''' h = math.floor(seconds / 3600) m = math.floor((seconds - h * 3600) / 60) s = int(seconds - h * 3600 - m * 60) hms_str = '{:0>2}:{:0>2}:{:0>2}'.format(h, m, s) return hms_str ================================================ FILE: audio/setup.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import contextlib import inspect import io import os import platform import subprocess as sp import sys from pathlib import Path from typing import List from typing import Tuple from typing import Union import distutils.command.clean from setuptools import Command from setuptools import find_packages from setuptools import setup from setuptools.command.develop import develop from setuptools.command.test import test from tools import setup_helpers ROOT_DIR = Path(__file__).parent.resolve() VERSION = '1.2.0' COMMITID = 'none' base = [ # paddleaudio align with librosa==0.8.1, which need numpy==1.23.x "librosa==0.8.1", "numpy==1.23.5", "kaldiio", "pathos", "pybind11", "parameterized", ] requirements = { "install": base, "develop": [ "sox", "soxbindings", "pre-commit", ], } def check_call(cmd: str, shell=False, executable=None): try: sp.check_call( cmd.split(), shell=shell, executable="/bin/bash" if shell else executable) except sp.CalledProcessError as e: print( f"{__file__}:{inspect.currentframe().f_lineno}: CMD: {cmd}, Error:", e.output, file=sys.stderr) raise e def check_output(cmd: Union[str, List[str], Tuple[str]], shell=False): try: if isinstance(cmd, (list, tuple)): cmds = cmd else: cmds = cmd.split() out_bytes = sp.check_output(cmds) except sp.CalledProcessError as e: out_bytes = e.output # Output generated before error code = e.returncode # Return code print( f"{__file__}:{inspect.currentframe().f_lineno}: CMD: {cmd}, Error:", out_bytes, file=sys.stderr) return out_bytes.strip().decode('utf8') def _run_cmd(cmd): try: return subprocess.check_output( cmd, cwd=ROOT_DIR, stderr=subprocess.DEVNULL).decode("ascii").strip() except Exception: return None @contextlib.contextmanager def pushd(new_dir): old_dir = os.getcwd() os.chdir(new_dir) print(new_dir) yield os.chdir(old_dir) print(old_dir) def read(*names, **kwargs): with io.open( os.path.join(os.path.dirname(__file__), *names), encoding=kwargs.get("encoding", "utf8")) as fp: return fp.read() def _remove(files: str): for f in files: f.unlink() ################################# Install ################################## def _post_install(install_lib_dir): pass class DevelopCommand(develop): def run(self): develop.run(self) # must after develop.run, or pkg install by shell will not see self.execute(_post_install, (self.install_lib, ), msg="Post Install...") class TestCommand(test): def finalize_options(self): test.finalize_options(self) self.test_args = [] self.test_suite = True def run_tests(self): # Run nose ensuring that argv simulates running nosetests directly import nose nose.run_exit(argv=['nosetests', '-w', 'tests']) def run_benchmark(self): for benchmark_item in glob.glob('tests/benchmark/*py'): os.system(f'pytest {benchmark_item}') # cmd: python setup.py upload class UploadCommand(Command): description = "Build and publish the package." user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): try: print("Removing previous dist/ ...") shutil.rmtree(str(ROOT_DIR / "dist")) except OSError: pass print("Building source distribution...") sp.check_call([sys.executable, "setup.py", "sdist"]) print("Uploading package to PyPi...") sp.check_call(["twine", "upload", "dist/*"]) sys.exit() ################################# Version ################################## def _get_version(sha): version = VERSION if os.getenv("BUILD_VERSION"): version = os.getenv("BUILD_VERSION") elif sha is not None: version += "+" + sha[:7] return version def _make_version_file(version, sha): sha = "Unknown" if sha is None else sha version_path = ROOT_DIR / "paddleaudio" / "__init__.py" with open(version_path, "a") as f: f.write(f"__version__ = '{version}'\n") def _rm_version(): file_ = ROOT_DIR / "paddleaudio" / "__init__.py" with open(file_, "r") as f: lines = f.readlines() with open(file_, "w") as f: for line in lines: if "__version__" not in line: f.write(line) ################################# Steup ################################## class clean(distutils.command.clean.clean): def run(self): # Run default behavior first distutils.command.clean.clean.run(self) # Remove paddleaudio extension for path in (ROOT_DIR / "paddleaudio").glob("**/*.so"): print(f"removing '{path}'") path.unlink() # Remove build directory build_dirs = [ ROOT_DIR / "build", ] for path in build_dirs: if path.exists(): print(f"removing '{path}' (and everything under it)") shutil.rmtree(str(path), ignore_errors=True) def main(): sha = _run_cmd(["git", "rev-parse", "HEAD"]) # commit id branch = _run_cmd(["git", "rev-parse", "--abbrev-ref", "HEAD"]) tag = _run_cmd(["git", "describe", "--tags", "--exact-match", "@"]) print("-- Git branch:", branch) print("-- Git SHA:", sha) print("-- Git tag:", tag) version = _get_version(sha) print("-- Building version", version) _rm_version() _make_version_file(version, sha) lib_package_data = {} if platform.system() != 'Windows' and platform.system() != 'Linux': lib_package_data = {'paddleaudio': ['lib/libgcc_s.1.1.dylib']} #if platform.system() == 'Linux': # lib_package_data = {'paddleaudio': ['lib/lib*']} setup_info = dict( # Metadata name='paddleaudio', version=VERSION, author='PaddlePaddle Speech and Language Team', author_email='paddlesl@baidu.com', url='https://github.com/PaddlePaddle/PaddleSpeech/audio', license='Apache 2.0', description='Speech audio tools based on Paddlepaddle', keywords=[ "audio process" "paddlepaddle", ], python_requires='>=3.7', install_requires=requirements["install"], extras_require={ 'develop': requirements["develop"], #'test': ["nose", "torchaudio==0.10.2", "pytest-benchmark", "librosa=0.8.1", "parameterized", "paddlepaddle"], }, cmdclass={ "build_ext": setup_helpers.CMakeBuild, 'develop': DevelopCommand, 'test': TestCommand, 'upload': UploadCommand, "clean": clean, }, # Package info packages=find_packages(include=['paddleaudio*']), package_data=lib_package_data, ext_modules=setup_helpers.get_ext_modules(), zip_safe=True, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'Topic :: Scientific/Engineering :: Artificial Intelligence', 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', ], ) setup(**setup_info) _rm_version() if __name__ == '__main__': main() ================================================ FILE: audio/tests/backends/base.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import unittest import urllib.request mono_channel_wav = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' multi_channels_wav = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/cat.wav' class BackendTest(unittest.TestCase): def setUp(self): self.initWavInput() def initWavInput(self): self.files = [] for url in [mono_channel_wav, multi_channels_wav]: if not os.path.isfile(os.path.basename(url)): urllib.request.urlretrieve(url, os.path.basename(url)) self.files.append(os.path.basename(url)) def initParams(self): raise NotImplementedError ================================================ FILE: audio/tests/backends/common.py ================================================ def get_encoding(ext, dtype): exts = { "mp3", "flac", "vorbis", } encodings = { "float32": "PCM_F", "int32": "PCM_S", "int16": "PCM_S", "uint8": "PCM_U", } return ext.upper() if ext in exts else encodings[dtype] def get_bit_depth(dtype): bit_depths = { "float32": 32, "int32": 32, "int16": 16, "uint8": 8, } return bit_depths[dtype] def get_bits_per_sample(ext, dtype): bits_per_samples = { "flac": 24, "mp3": 0, "vorbis": 0, } return bits_per_samples.get(ext, get_bit_depth(dtype)) ================================================ FILE: audio/tests/backends/soundfile/base.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import unittest import urllib.request mono_channel_wav = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' multi_channels_wav = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/cat.wav' class BackendTest(unittest.TestCase): def setUp(self): self.initWavInput() def initWavInput(self): self.files = [] for url in [mono_channel_wav, multi_channels_wav]: if not os.path.isfile(os.path.basename(url)): urllib.request.urlretrieve(url, os.path.basename(url)) self.files.append(os.path.basename(url)) def initParams(self): raise NotImplementedError ================================================ FILE: audio/tests/backends/soundfile/common.py ================================================ import itertools from unittest import skipIf from paddleaudio._internal.module_utils import is_module_available from parameterized import parameterized def name_func(func, _, params): return f'{func.__name__}_{"_".join(str(arg) for arg in params.args)}' def dtype2subtype(dtype): return { "float64": "DOUBLE", "float32": "FLOAT", "int32": "PCM_32", "int16": "PCM_16", "uint8": "PCM_U8", "int8": "PCM_S8", }[dtype] def skipIfFormatNotSupported(fmt): fmts = [] if is_module_available("soundfile"): import soundfile fmts = soundfile.available_formats() return skipIf(fmt not in fmts, f'"{fmt}" is not supported by soundfile') return skipIf(True, '"soundfile" not available.') def parameterize(*params): return parameterized.expand( list(itertools.product(*params)), name_func=name_func) def fetch_wav_subtype(dtype, encoding, bits_per_sample): subtype = { (None, None): dtype2subtype(dtype), (None, 8): "PCM_U8", ("PCM_U", None): "PCM_U8", ("PCM_U", 8): "PCM_U8", ("PCM_S", None): "PCM_32", ("PCM_S", 16): "PCM_16", ("PCM_S", 32): "PCM_32", ("PCM_F", None): "FLOAT", ("PCM_F", 32): "FLOAT", ("PCM_F", 64): "DOUBLE", ("ULAW", None): "ULAW", ("ULAW", 8): "ULAW", ("ALAW", None): "ALAW", ("ALAW", 8): "ALAW", }.get((encoding, bits_per_sample)) if subtype: return subtype raise ValueError(f"wav does not support ({encoding}, {bits_per_sample}).") def get_encoding(ext, dtype): exts = { "mp3", "flac", "vorbis", } encodings = { "float32": "PCM_F", "int32": "PCM_S", "int16": "PCM_S", "uint8": "PCM_U", } return ext.upper() if ext in exts else encodings[dtype] def get_bit_depth(dtype): bit_depths = { "float32": 32, "int32": 32, "int16": 16, "uint8": 8, } return bit_depths[dtype] def get_bits_per_sample(ext, dtype): bits_per_samples = { "flac": 24, "mp3": 0, "vorbis": 0, } return bits_per_samples.get(ext, get_bit_depth(dtype)) ================================================ FILE: audio/tests/backends/soundfile/info_test.py ================================================ #this code is from: https://github.com/pytorch/audio/blob/main/test/torchaudio_unittest/backend/soundfile/info_test.py import tarfile import unittest import warnings from unittest.mock import patch import paddle import soundfile from common import get_bits_per_sample from common import get_encoding from common import parameterize from common import skipIfFormatNotSupported from common_utils import get_wav_data from common_utils import nested_params from common_utils import save_wav from common_utils import TempDirMixin from paddleaudio.backends import soundfile_backend class TestInfo(TempDirMixin, unittest.TestCase): @parameterize( ["float32", "int32"], [8000, 16000], [1, 2], ) def test_wav(self, dtype, sample_rate, num_channels): """`soundfile_backend.info` can check wav file correctly""" duration = 1 path = self.get_temp_path("data.wav") data = get_wav_data( dtype, num_channels, normalize=False, num_frames=duration * sample_rate) save_wav(path, data, sample_rate) info = soundfile_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == get_bits_per_sample("wav", dtype) assert info.encoding == get_encoding("wav", dtype) @parameterize([8000, 16000], [1, 2]) @skipIfFormatNotSupported("FLAC") def test_flac(self, sample_rate, num_channels): """`soundfile_backend.info` can check flac file correctly""" duration = 1 num_frames = sample_rate * duration #data = torch.randn(num_frames, num_channels).numpy() data = paddle.randn(shape=[num_frames, num_channels]).numpy() path = self.get_temp_path("data.flac") soundfile.write(path, data, sample_rate) info = soundfile_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == num_frames assert info.num_channels == num_channels assert info.bits_per_sample == 16 assert info.encoding == "FLAC" #@parameterize([8000, 16000], [1, 2]) #@skipIfFormatNotSupported("OGG") #def test_ogg(self, sample_rate, num_channels): #"""`soundfile_backend.info` can check ogg file correctly""" #duration = 1 #num_frames = sample_rate * duration ##data = torch.randn(num_frames, num_channels).numpy() #data = paddle.randn(shape=[num_frames, num_channels]).numpy() #print(len(data)) #path = self.get_temp_path("data.ogg") #soundfile.write(path, data, sample_rate) #info = soundfile_backend.info(path) #print(info) #assert info.sample_rate == sample_rate #print("info") #print(info.num_frames) #print("jiji") #print(sample_rate*duration) ##assert info.num_frames == sample_rate * duration #assert info.num_channels == num_channels #assert info.bits_per_sample == 0 #assert info.encoding == "VORBIS" @nested_params( [8000, 16000], [1, 2], [("PCM_24", 24), ("PCM_32", 32)], ) @skipIfFormatNotSupported("NIST") def test_sphere(self, sample_rate, num_channels, subtype_and_bit_depth): """`soundfile_backend.info` can check sph file correctly""" duration = 1 num_frames = sample_rate * duration #data = torch.randn(num_frames, num_channels).numpy() data = paddle.randn(shape=[num_frames, num_channels]).numpy() path = self.get_temp_path("data.nist") subtype, bits_per_sample = subtype_and_bit_depth soundfile.write(path, data, sample_rate, subtype=subtype) info = soundfile_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == bits_per_sample assert info.encoding == "PCM_S" def test_unknown_subtype_warning(self): """soundfile_backend.info issues a warning when the subtype is unknown This will happen if a new subtype is supported in SoundFile: the _SUBTYPE_TO_BITS_PER_SAMPLE dict should be updated. """ def _mock_info_func(_): class MockSoundFileInfo: samplerate = 8000 frames = 356 channels = 2 subtype = "UNSEEN_SUBTYPE" format = "UNKNOWN" return MockSoundFileInfo() with patch("soundfile.info", _mock_info_func): with warnings.catch_warnings(record=True) as w: info = soundfile_backend.info("foo") assert len(w) == 1 assert "UNSEEN_SUBTYPE subtype is unknown to PaddleAudio" in str( w[-1].message) assert info.bits_per_sample == 0 class TestFileObject(TempDirMixin, unittest.TestCase): def _test_fileobj(self, ext, subtype, bits_per_sample): """Query audio via file-like object works""" duration = 2 sample_rate = 16000 num_channels = 2 num_frames = sample_rate * duration path = self.get_temp_path(f"test.{ext}") #data = torch.randn(num_frames, num_channels).numpy() data = paddle.randn(shape=[num_frames, num_channels]).numpy() soundfile.write(path, data, sample_rate, subtype=subtype) with open(path, "rb") as fileobj: info = soundfile_backend.info(fileobj) assert info.sample_rate == sample_rate assert info.num_frames == num_frames assert info.num_channels == num_channels assert info.bits_per_sample == bits_per_sample assert info.encoding == "FLAC" if ext == "flac" else "PCM_S" def test_fileobj_wav(self): """Loading audio via file-like object works""" self._test_fileobj("wav", "PCM_16", 16) @skipIfFormatNotSupported("FLAC") def test_fileobj_flac(self): """Loading audio via file-like object works""" self._test_fileobj("flac", "PCM_16", 16) def _test_tarobj(self, ext, subtype, bits_per_sample): """Query compressed audio via file-like object works""" duration = 2 sample_rate = 16000 num_channels = 2 num_frames = sample_rate * duration audio_file = f"test.{ext}" audio_path = self.get_temp_path(audio_file) archive_path = self.get_temp_path("archive.tar.gz") #data = torch.randn(num_frames, num_channels).numpy() data = paddle.randn(shape=[num_frames, num_channels]).numpy() soundfile.write(audio_path, data, sample_rate, subtype=subtype) with tarfile.TarFile(archive_path, "w") as tarobj: tarobj.add(audio_path, arcname=audio_file) with tarfile.TarFile(archive_path, "r") as tarobj: fileobj = tarobj.extractfile(audio_file) info = soundfile_backend.info(fileobj) assert info.sample_rate == sample_rate assert info.num_frames == num_frames assert info.num_channels == num_channels assert info.bits_per_sample == bits_per_sample assert info.encoding == "FLAC" if ext == "flac" else "PCM_S" def test_tarobj_wav(self): """Query compressed audio via file-like object works""" self._test_tarobj("wav", "PCM_16", 16) @skipIfFormatNotSupported("FLAC") def test_tarobj_flac(self): """Query compressed audio via file-like object works""" self._test_tarobj("flac", "PCM_16", 16) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/soundfile/load_test.py ================================================ #this code is from: https://github.com/pytorch/audio/blob/main/test/torchaudio_unittest/backend/soundfile/load_test.py import os import tarfile import unittest from unittest.mock import patch import numpy as np import paddle import soundfile from common import dtype2subtype from common import parameterize from common import skipIfFormatNotSupported from common_utils import get_wav_data from common_utils import load_wav from common_utils import normalize_wav from common_utils import save_wav from common_utils import TempDirMixin from paddleaudio.backends import soundfile_backend from parameterized import parameterized def _get_mock_path( ext: str, dtype: str, sample_rate: int, num_channels: int, num_frames: int, ): return f"{dtype}_{sample_rate}_{num_channels}_{num_frames}.{ext}" def _get_mock_params(path: str): filename, ext = path.split(".") parts = filename.split("_") return { "ext": ext, "dtype": parts[0], "sample_rate": int(parts[1]), "num_channels": int(parts[2]), "num_frames": int(parts[3]), } class SoundFileMock: def __init__(self, path, mode): assert mode == "r" self.path = path self._params = _get_mock_params(path) self._start = None @property def samplerate(self): return self._params["sample_rate"] @property def format(self): if self._params["ext"] == "wav": return "WAV" if self._params["ext"] == "flac": return "FLAC" if self._params["ext"] == "ogg": return "OGG" if self._params["ext"] in ["sph", "nis", "nist"]: return "NIST" @property def subtype(self): if self._params["ext"] == "ogg": return "VORBIS" return dtype2subtype(self._params["dtype"]) def _prepare_read(self, start, stop, frames): assert stop is None self._start = start return frames def read(self, frames, dtype, always_2d): assert always_2d data = get_wav_data( dtype, self._params["num_channels"], normalize=False, num_frames=self._params["num_frames"], channels_first=False, ).numpy() return data[self._start:self._start + frames] def __enter__(self): return self def __exit__(self, *args, **kwargs): pass class MockedLoadTest(unittest.TestCase): def assert_dtype(self, ext, dtype, sample_rate, num_channels, normalize, channels_first): """When format is WAV or NIST, normalize=False will return the native dtype Tensor, otherwise float32""" num_frames = 3 * sample_rate path = _get_mock_path(ext, dtype, sample_rate, num_channels, num_frames) expected_dtype = paddle.float32 if normalize or ext not in [ "wav", "nist" ] else getattr(paddle, dtype) with patch("soundfile.SoundFile", SoundFileMock): found, sr = soundfile_backend.load( path, normalize=normalize, channels_first=channels_first) assert found.dtype == expected_dtype assert sample_rate == sr @parameterize( ["int32", "float32", "float64"], [8000, 16000], [1, 2], [True, False], [True, False], ) def test_wav(self, dtype, sample_rate, num_channels, normalize, channels_first): """Returns native dtype when normalize=False else float32""" self.assert_dtype("wav", dtype, sample_rate, num_channels, normalize, channels_first) @parameterize( ["int32"], [8000, 16000], [1, 2], [True, False], [True, False], ) def test_sphere(self, dtype, sample_rate, num_channels, normalize, channels_first): """Returns float32 always""" self.assert_dtype("sph", dtype, sample_rate, num_channels, normalize, channels_first) @parameterize([8000, 16000], [1, 2], [True, False], [True, False]) def test_ogg(self, sample_rate, num_channels, normalize, channels_first): """Returns float32 always""" self.assert_dtype("ogg", "int16", sample_rate, num_channels, normalize, channels_first) @parameterize([8000, 16000], [1, 2], [True, False], [True, False]) def test_flac(self, sample_rate, num_channels, normalize, channels_first): """`soundfile_backend.load` can load ogg format.""" self.assert_dtype("flac", "int16", sample_rate, num_channels, normalize, channels_first) class LoadTestBase(TempDirMixin, unittest.TestCase): def assert_wav( self, dtype, sample_rate, num_channels, normalize, channels_first=True, duration=1, ): """`soundfile_backend.load` can load wav format correctly. Wav data loaded with soundfile backend should match those with scipy """ path = self.get_temp_path("reference.wav") num_frames = duration * sample_rate data = get_wav_data( dtype, num_channels, normalize=normalize, num_frames=num_frames, channels_first=channels_first, ) save_wav(path, data, sample_rate, channels_first=channels_first) expected = load_wav( path, normalize=normalize, channels_first=channels_first)[0] data, sr = soundfile_backend.load( path, normalize=normalize, channels_first=channels_first) assert sr == sample_rate np.testing.assert_array_almost_equal(data.numpy(), expected.numpy()) def assert_sphere( self, dtype, sample_rate, num_channels, channels_first=True, duration=1, ): """`soundfile_backend.load` can load SPHERE format correctly.""" path = self.get_temp_path("reference.sph") num_frames = duration * sample_rate raw = get_wav_data( dtype, num_channels, num_frames=num_frames, normalize=False, channels_first=False, ) soundfile.write( path, raw, sample_rate, subtype=dtype2subtype(dtype), format="NIST") expected = normalize_wav(raw.t() if channels_first else raw) data, sr = soundfile_backend.load(path, channels_first=channels_first) assert sr == sample_rate #self.assertEqual(data, expected, atol=1e-4, rtol=1e-8) np.testing.assert_array_almost_equal(data.numpy(), expected.numpy()) def assert_flac( self, dtype, sample_rate, num_channels, channels_first=True, duration=1, ): """`soundfile_backend.load` can load FLAC format correctly.""" path = self.get_temp_path("reference.flac") num_frames = duration * sample_rate raw = get_wav_data( dtype, num_channels, num_frames=num_frames, normalize=False, channels_first=False, ) soundfile.write(path, raw, sample_rate) expected = normalize_wav(raw.t() if channels_first else raw) data, sr = soundfile_backend.load(path, channels_first=channels_first) assert sr == sample_rate #self.assertEqual(data, expected, atol=1e-4, rtol=1e-8) np.testing.assert_array_almost_equal(data.numpy(), expected.numpy()) class TestLoad(LoadTestBase): """Test the correctness of `soundfile_backend.load` for various formats""" @parameterize( ["float32", "int32"], [8000, 16000], [1, 2], [False, True], [False, True], ) def test_wav(self, dtype, sample_rate, num_channels, normalize, channels_first): """`soundfile_backend.load` can load wav format correctly.""" self.assert_wav(dtype, sample_rate, num_channels, normalize, channels_first) @parameterize( ["int32"], [16000], [2], [False], ) def test_wav_large(self, dtype, sample_rate, num_channels, normalize): """`soundfile_backend.load` can load large wav file correctly.""" two_hours = 2 * 60 * 60 self.assert_wav( dtype, sample_rate, num_channels, normalize, duration=two_hours) @parameterize(["float32", "int32"], [4, 8, 16, 32], [False, True]) def test_multiple_channels(self, dtype, num_channels, channels_first): """`soundfile_backend.load` can load wav file with more than 2 channels.""" sample_rate = 8000 normalize = False self.assert_wav(dtype, sample_rate, num_channels, normalize, channels_first) #@parameterize(["int32"], [8000, 16000], [1, 2], [False, True]) #@skipIfFormatNotSupported("NIST") #def test_sphere(self, dtype, sample_rate, num_channels, channels_first): #"""`soundfile_backend.load` can load sphere format correctly.""" #self.assert_sphere(dtype, sample_rate, num_channels, channels_first) #@parameterize(["int32"], [8000, 16000], [1, 2], [False, True]) #@skipIfFormatNotSupported("FLAC") #def test_flac(self, dtype, sample_rate, num_channels, channels_first): #"""`soundfile_backend.load` can load flac format correctly.""" #self.assert_flac(dtype, sample_rate, num_channels, channels_first) class TestLoadFormat(TempDirMixin, unittest.TestCase): """Given `format` parameter, `so.load` can load files without extension""" original = None path = None def _make_file(self, format_): sample_rate = 8000 path_with_ext = self.get_temp_path(f"test.{format_}") data = get_wav_data("float32", num_channels=2).numpy().T soundfile.write(path_with_ext, data, sample_rate) expected = soundfile.read(path_with_ext, dtype="float32")[0].T path = os.path.splitext(path_with_ext)[0] os.rename(path_with_ext, path) return path, expected def _test_format(self, format_): """Providing format allows to read file without extension""" path, expected = self._make_file(format_) found, _ = soundfile_backend.load(path) #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(found, expected) @parameterized.expand([ ("WAV", ), ("wav", ), ]) def test_wav(self, format_): self._test_format(format_) @parameterized.expand([ ("FLAC", ), ("flac", ), ]) @skipIfFormatNotSupported("FLAC") def test_flac(self, format_): self._test_format(format_) class TestFileObject(TempDirMixin, unittest.TestCase): def _test_fileobj(self, ext): """Loading audio via file-like object works""" sample_rate = 16000 path = self.get_temp_path(f"test.{ext}") data = get_wav_data("float32", num_channels=2).numpy().T soundfile.write(path, data, sample_rate) expected = soundfile.read(path, dtype="float32")[0].T with open(path, "rb") as fileobj: found, sr = soundfile_backend.load(fileobj) assert sr == sample_rate #self.assertEqual(expected, found) np.testing.assert_array_almost_equal(found, expected) def test_fileobj_wav(self): """Loading audio via file-like object works""" self._test_fileobj("wav") def test_fileobj_flac(self): """Loading audio via file-like object works""" self._test_fileobj("flac") def _test_tarfile(self, ext): """Loading audio via file-like object works""" sample_rate = 16000 audio_file = f"test.{ext}" audio_path = self.get_temp_path(audio_file) archive_path = self.get_temp_path("archive.tar.gz") data = get_wav_data("float32", num_channels=2).numpy().T soundfile.write(audio_path, data, sample_rate) expected = soundfile.read(audio_path, dtype="float32")[0].T with tarfile.TarFile(archive_path, "w") as tarobj: tarobj.add(audio_path, arcname=audio_file) with tarfile.TarFile(archive_path, "r") as tarobj: fileobj = tarobj.extractfile(audio_file) found, sr = soundfile_backend.load(fileobj) assert sr == sample_rate #self.assertEqual(expected, found) np.testing.assert_array_almost_equal(found.numpy(), expected) def test_tarfile_wav(self): """Loading audio via file-like object works""" self._test_tarfile("wav") def test_tarfile_flac(self): """Loading audio via file-like object works""" self._test_tarfile("flac") if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/soundfile/save_test.py ================================================ import io import unittest from unittest.mock import patch import numpy as np import paddle import soundfile from common import fetch_wav_subtype from common import parameterize from common import skipIfFormatNotSupported from common_utils import get_wav_data from common_utils import load_wav from common_utils import nested_params from common_utils import TempDirMixin from paddleaudio.backends import soundfile_backend class MockedSaveTest(unittest.TestCase): @nested_params( ["float32", "int32"], [8000, 16000], [1, 2], [False, True], [ (None, None), ("PCM_U", None), ("PCM_U", 8), ("PCM_S", None), ("PCM_S", 16), ("PCM_S", 32), ("PCM_F", None), ("PCM_F", 32), ("PCM_F", 64), ("ULAW", None), ("ULAW", 8), ("ALAW", None), ("ALAW", 8), ], ) @patch("soundfile.write") def test_wav(self, dtype, sample_rate, num_channels, channels_first, enc_params, mocked_write): """soundfile_backend.save passes correct subtype to soundfile.write when WAV""" filepath = "foo.wav" input_tensor = get_wav_data( dtype, num_channels, num_frames=3 * sample_rate, normalize=dtype == "float32", channels_first=channels_first, ) input_tensor = paddle.transpose(input_tensor, [1, 0]) encoding, bits_per_sample = enc_params soundfile_backend.save( filepath, input_tensor, sample_rate, channels_first=channels_first, encoding=encoding, bits_per_sample=bits_per_sample, ) # on +Py3.8 call_args.kwargs is more descriptive args = mocked_write.call_args[1] assert args["file"] == filepath assert args["samplerate"] == sample_rate assert args["subtype"] == fetch_wav_subtype(dtype, encoding, bits_per_sample) assert args["format"] is None tensor_result = paddle.transpose( input_tensor, [1, 0]) if channels_first else input_tensor #self.assertEqual(args["data"], tensor_result.numpy()) np.testing.assert_array_almost_equal(args["data"].numpy(), tensor_result.numpy()) @patch("soundfile.write") def assert_non_wav( self, fmt, dtype, sample_rate, num_channels, channels_first, mocked_write, encoding=None, bits_per_sample=None, ): """soundfile_backend.save passes correct subtype and format to soundfile.write when SPHERE""" filepath = f"foo.{fmt}" input_tensor = get_wav_data( dtype, num_channels, num_frames=3 * sample_rate, normalize=False, channels_first=channels_first, ) input_tensor = paddle.transpose(input_tensor, [1, 0]) expected_data = paddle.transpose( input_tensor, [1, 0]) if channels_first else input_tensor soundfile_backend.save( filepath, input_tensor, sample_rate, channels_first, encoding=encoding, bits_per_sample=bits_per_sample, ) # on +Py3.8 call_args.kwargs is more descriptive args = mocked_write.call_args[1] assert args["file"] == filepath assert args["samplerate"] == sample_rate if fmt in ["sph", "nist", "nis"]: assert args["format"] == "NIST" else: assert args["format"] is None np.testing.assert_array_almost_equal(args["data"].numpy(), expected_data.numpy()) #self.assertEqual(args["data"], expected_data) @nested_params( ["sph", "nist", "nis"], ["int32"], [8000, 16000], [1, 2], [False, True], [ ("PCM_S", 8), ("PCM_S", 16), ("PCM_S", 24), ("PCM_S", 32), ("ULAW", 8), ("ALAW", 8), ("ALAW", 16), ("ALAW", 24), ("ALAW", 32), ], ) def test_sph(self, fmt, dtype, sample_rate, num_channels, channels_first, enc_params): """soundfile_backend.save passes default format and subtype (None-s) to soundfile.write when not WAV""" encoding, bits_per_sample = enc_params self.assert_non_wav( fmt, dtype, sample_rate, num_channels, channels_first, encoding=encoding, bits_per_sample=bits_per_sample) @parameterize( ["int32"], [8000, 16000], [1, 2], [False, True], [8, 16, 24], ) def test_flac(self, dtype, sample_rate, num_channels, channels_first, bits_per_sample): """soundfile_backend.save passes default format and subtype (None-s) to soundfile.write when not WAV""" self.assert_non_wav( "flac", dtype, sample_rate, num_channels, channels_first, bits_per_sample=bits_per_sample) @parameterize( ["int32"], [8000, 16000], [1, 2], [False, True], ) def test_ogg(self, dtype, sample_rate, num_channels, channels_first): """soundfile_backend.save passes default format and subtype (None-s) to soundfile.write when not WAV""" self.assert_non_wav("ogg", dtype, sample_rate, num_channels, channels_first) class SaveTestBase(TempDirMixin, unittest.TestCase): def assert_wav(self, dtype, sample_rate, num_channels, num_frames): """`soundfile_backend.save` can save wav format.""" path = self.get_temp_path("data.wav") expected = get_wav_data( dtype, num_channels, num_frames=num_frames, normalize=False) soundfile_backend.save(path, expected, sample_rate) found, sr = load_wav(path, normalize=False) assert sample_rate == sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) def _assert_non_wav(self, fmt, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save non-wav format. Due to precision mismatch, and the lack of alternative way to decode the resulting files without using soundfile, only meta data are validated. """ num_frames = sample_rate * 3 path = self.get_temp_path(f"data.{fmt}") expected = get_wav_data( dtype, num_channels, num_frames=num_frames, normalize=False) soundfile_backend.save(path, expected, sample_rate) sinfo = soundfile.info(path) assert sinfo.format == fmt.upper() #assert sinfo.frames == num_frames this go wrong assert sinfo.channels == num_channels assert sinfo.samplerate == sample_rate def assert_flac(self, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save flac format.""" self._assert_non_wav("flac", dtype, sample_rate, num_channels) def assert_sphere(self, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save sph format.""" self._assert_non_wav("nist", dtype, sample_rate, num_channels) def assert_ogg(self, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save ogg format. As we cannot inspect the OGG format (it's lossy), we only check the metadata. """ self._assert_non_wav("ogg", dtype, sample_rate, num_channels) class TestSave(SaveTestBase): @parameterize( ["float32", "int32"], [8000, 16000], [1, 2], ) def test_wav(self, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save wav format.""" self.assert_wav(dtype, sample_rate, num_channels, num_frames=None) @parameterize( ["float32", "int32"], [4, 8, 16, 32], ) def test_multiple_channels(self, dtype, num_channels): """`soundfile_backend.save` can save wav with more than 2 channels.""" sample_rate = 8000 self.assert_wav(dtype, sample_rate, num_channels, num_frames=None) @parameterize( ["int32"], [8000, 16000], [1, 2], ) @skipIfFormatNotSupported("NIST") def test_sphere(self, dtype, sample_rate, num_channels): """`soundfile_backend.save` can save sph format.""" self.assert_sphere(dtype, sample_rate, num_channels) @parameterize( [8000, 16000], [1, 2], ) @skipIfFormatNotSupported("FLAC") def test_flac(self, sample_rate, num_channels): """`soundfile_backend.save` can save flac format.""" self.assert_flac("float32", sample_rate, num_channels) @parameterize( [8000, 16000], [1, 2], ) @skipIfFormatNotSupported("OGG") def test_ogg(self, sample_rate, num_channels): """`soundfile_backend.save` can save ogg/vorbis format.""" self.assert_ogg("float32", sample_rate, num_channels) class TestSaveParams(TempDirMixin, unittest.TestCase): """Test the correctness of optional parameters of `soundfile_backend.save`""" @parameterize([True, False]) def test_channels_first(self, channels_first): """channels_first swaps axes""" path = self.get_temp_path("data.wav") data = get_wav_data("int32", 2, channels_first=channels_first) soundfile_backend.save(path, data, 8000, channels_first=channels_first) found = load_wav(path)[0] expected = data if channels_first else data.transpose([1, 0]) #self.assertEqual(found, expected, atol=1e-4, rtol=1e-8) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) class TestFileObject(TempDirMixin, unittest.TestCase): def _test_fileobj(self, ext): """Saving audio to file-like object works""" sample_rate = 16000 path = self.get_temp_path(f"test.{ext}") subtype = "FLOAT" if ext == "wav" else None data = get_wav_data("float32", num_channels=2) soundfile.write(path, data.numpy().T, sample_rate, subtype=subtype) expected = soundfile.read(path, dtype="float32")[0] fileobj = io.BytesIO() soundfile_backend.save(fileobj, data, sample_rate, format=ext) fileobj.seek(0) found, sr = soundfile.read(fileobj, dtype="float32") assert sr == sample_rate #self.assertEqual(expected, found, atol=1e-4, rtol=1e-8) np.testing.assert_array_almost_equal(found, expected) def test_fileobj_wav(self): """Saving audio via file-like object works""" self._test_fileobj("wav") @skipIfFormatNotSupported("FLAC") def test_fileobj_flac(self): """Saving audio via file-like object works""" self._test_fileobj("flac") @skipIfFormatNotSupported("NIST") def test_fileobj_nist(self): """Saving audio via file-like object works""" self._test_fileobj("NIST") @skipIfFormatNotSupported("OGG") def test_fileobj_ogg(self): """Saving audio via file-like object works""" self._test_fileobj("OGG") if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/soundfile/test_io.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import filecmp import os import unittest import numpy as np from paddleaudio.backends import soundfile_load as load from paddleaudio.backends import soundfile_save as save import soundfile as sf from base import BackendTest class TestIO(BackendTest): def test_load_mono_channel(self): sf_data, sf_sr = sf.read(self.files[0]) pa_data, pa_sr = load( self.files[0], normal=False, dtype='float64') self.assertEqual(sf_data.dtype, pa_data.dtype) self.assertEqual(sf_sr, pa_sr) np.testing.assert_array_almost_equal(sf_data, pa_data) def test_load_multi_channels(self): sf_data, sf_sr = sf.read(self.files[1]) sf_data = sf_data.T # Channel dim first pa_data, pa_sr = load( self.files[1], mono=False, normal=False, dtype='float64') self.assertEqual(sf_data.dtype, pa_data.dtype) self.assertEqual(sf_sr, pa_sr) np.testing.assert_array_almost_equal(sf_data, pa_data) def test_save_mono_channel(self): waveform, sr = np.random.randint( low=-32768, high=32768, size=(48000), dtype=np.int16), 16000 sf_tmp_file = 'sf_tmp.wav' pa_tmp_file = 'pa_tmp.wav' sf.write(sf_tmp_file, waveform, sr) save(waveform, sr, pa_tmp_file) self.assertTrue(filecmp.cmp(sf_tmp_file, pa_tmp_file)) for file in [sf_tmp_file, pa_tmp_file]: os.remove(file) def test_save_multi_channels(self): waveform, sr = np.random.randint( low=-32768, high=32768, size=(2, 48000), dtype=np.int16), 16000 sf_tmp_file = 'sf_tmp.wav' pa_tmp_file = 'pa_tmp.wav' sf.write(sf_tmp_file, waveform.T, sr) save(waveform.T, sr, pa_tmp_file) self.assertTrue(filecmp.cmp(sf_tmp_file, pa_tmp_file)) for file in [sf_tmp_file, pa_tmp_file]: os.remove(file) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/sox_io/common.py ================================================ import itertools from unittest import skipIf from paddleaudio._internal.module_utils import is_module_available from parameterized import parameterized def name_func(func, _, params): return f'{func.__name__}_{"_".join(str(arg) for arg in params.args)}' def dtype2subtype(dtype): return { "float64": "DOUBLE", "float32": "FLOAT", "int32": "PCM_32", "int16": "PCM_16", "uint8": "PCM_U8", "int8": "PCM_S8", }[dtype] def skipIfFormatNotSupported(fmt): fmts = [] if is_module_available("soundfile"): import soundfile fmts = soundfile.available_formats() return skipIf(fmt not in fmts, f'"{fmt}" is not supported by soundfile') return skipIf(True, '"soundfile" not available.') def parameterize(*params): return parameterized.expand( list(itertools.product(*params)), name_func=name_func) def fetch_wav_subtype(dtype, encoding, bits_per_sample): subtype = { (None, None): dtype2subtype(dtype), (None, 8): "PCM_U8", ("PCM_U", None): "PCM_U8", ("PCM_U", 8): "PCM_U8", ("PCM_S", None): "PCM_32", ("PCM_S", 16): "PCM_16", ("PCM_S", 32): "PCM_32", ("PCM_F", None): "FLOAT", ("PCM_F", 32): "FLOAT", ("PCM_F", 64): "DOUBLE", ("ULAW", None): "ULAW", ("ULAW", 8): "ULAW", ("ALAW", None): "ALAW", ("ALAW", 8): "ALAW", }.get((encoding, bits_per_sample)) if subtype: return subtype raise ValueError(f"wav does not support ({encoding}, {bits_per_sample}).") def get_encoding(ext, dtype): exts = { "mp3", "flac", "vorbis", } encodings = { "float32": "PCM_F", "int32": "PCM_S", "int16": "PCM_S", "uint8": "PCM_U", } return ext.upper() if ext in exts else encodings[dtype] def get_bit_depth(dtype): bit_depths = { "float32": 32, "int32": 32, "int16": 16, "uint8": 8, } return bit_depths[dtype] def get_bits_per_sample(ext, dtype): bits_per_samples = { "flac": 24, "mp3": 0, "vorbis": 0, } return bits_per_samples.get(ext, get_bit_depth(dtype)) ================================================ FILE: audio/tests/backends/sox_io/info_test.py ================================================ import io import itertools import os import platform import tarfile import unittest from contextlib import contextmanager if platform.system() == "Windows": import warnings warnings.warn("sox io not support in Windows, please skip test.") exit() from parameterized import parameterized from common import get_bits_per_sample, get_encoding from paddleaudio.backends import sox_io_backend from common_utils import ( get_wav_data, save_wav, TempDirMixin, sox_utils, ) #code is from:https://github.com/pytorch/audio/blob/main/torchaudio/test/torchaudio_unittest/backend/sox_io/info_test.py class TestInfo(TempDirMixin, unittest.TestCase): @parameterized.expand( list( itertools.product( [ "float32", "int32", ], [8000, 16000], [1, 2], )), ) def test_wav(self, dtype, sample_rate, num_channels): """`sox_io_backend.info` can check wav file correctly""" duration = 1 path = self.get_temp_path("data.wav") data = get_wav_data( dtype, num_channels, normalize=False, num_frames=duration * sample_rate) save_wav(path, data, sample_rate) info = sox_io_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == sox_utils.get_bit_depth(dtype) assert info.encoding == get_encoding("wav", dtype) @parameterized.expand( list( itertools.product( ["float32", "int32"], [8000, 16000], [4, 8, 16, 32], )), ) def test_wav_multiple_channels(self, dtype, sample_rate, num_channels): """`sox_io_backend.info` can check wav file with channels more than 2 correctly""" duration = 1 path = self.get_temp_path("data.wav") data = get_wav_data( dtype, num_channels, normalize=False, num_frames=duration * sample_rate) save_wav(path, data, sample_rate) info = sox_io_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == sox_utils.get_bit_depth(dtype) def test_ulaw(self): """`sox_io_backend.info` can check ulaw file correctly""" duration = 1 num_channels = 1 sample_rate = 8000 path = self.get_temp_path("data.wav") sox_utils.gen_audio_file( path, sample_rate=sample_rate, num_channels=num_channels, bit_depth=8, encoding="u-law", duration=duration) info = sox_io_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == 8 assert info.encoding == "ULAW" def test_alaw(self): """`sox_io_backend.info` can check alaw file correctly""" duration = 1 num_channels = 1 sample_rate = 8000 path = self.get_temp_path("data.wav") sox_utils.gen_audio_file( path, sample_rate=sample_rate, num_channels=num_channels, bit_depth=8, encoding="a-law", duration=duration) info = sox_io_backend.info(path) assert info.sample_rate == sample_rate assert info.num_frames == sample_rate * duration assert info.num_channels == num_channels assert info.bits_per_sample == 8 assert info.encoding == "ALAW" #class TestInfoOpus(unittest.TestCase): #@parameterized.expand( #list( #itertools.product( #["96k"], #[1, 2], #[0, 5, 10], #) #), #) #def test_opus(self, bitrate, num_channels, compression_level): #"""`sox_io_backend.info` can check opus file correcty""" #path = data_utils.get_asset_path("io", f"{bitrate}_{compression_level}_{num_channels}ch.opus") #info = sox_io_backend.info(path) #assert info.sample_rate == 48000 #assert info.num_frames == 32768 #assert info.num_channels == num_channels #assert info.bits_per_sample == 0 # bit_per_sample is irrelevant for compressed formats #assert info.encoding == "OPUS" class FileObjTestBase(TempDirMixin): def _gen_file(self, ext, dtype, sample_rate, num_channels, num_frames, *, comments=None): path = self.get_temp_path(f"test.{ext}") bit_depth = sox_utils.get_bit_depth(dtype) duration = num_frames / sample_rate comment_file = self._gen_comment_file(comments) if comments else None sox_utils.gen_audio_file( path, sample_rate, num_channels=num_channels, encoding=sox_utils.get_encoding(dtype), bit_depth=bit_depth, duration=duration, comment_file=comment_file, ) return path def _gen_comment_file(self, comments): comment_path = self.get_temp_path("comment.txt") with open(comment_path, "w") as file_: file_.writelines(comments) return comment_path class Unseekable: def __init__(self, fileobj): self.fileobj = fileobj def read(self, n): return self.fileobj.read(n) class TestFileObject(FileObjTestBase, unittest.TestCase): def _query_fileobj(self, ext, dtype, sample_rate, num_channels, num_frames, *, comments=None): path = self._gen_file( ext, dtype, sample_rate, num_channels, num_frames, comments=comments) format_ = ext if ext in ["mp3"] else None with open(path, "rb") as fileobj: return sox_io_backend.info(fileobj, format_) def _query_bytesio(self, ext, dtype, sample_rate, num_channels, num_frames): path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames) format_ = ext if ext in ["mp3"] else None with open(path, "rb") as file_: fileobj = io.BytesIO(file_.read()) return sox_io_backend.info(fileobj, format_) def _query_tarfile(self, ext, dtype, sample_rate, num_channels, num_frames): audio_path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames) audio_file = os.path.basename(audio_path) archive_path = self.get_temp_path("archive.tar.gz") with tarfile.TarFile(archive_path, "w") as tarobj: tarobj.add(audio_path, arcname=audio_file) format_ = ext if ext in ["mp3"] else None with tarfile.TarFile(archive_path, "r") as tarobj: fileobj = tarobj.extractfile(audio_file) return sox_io_backend.info(fileobj, format_) @contextmanager def _set_buffer_size(self, buffer_size): try: original_buffer_size = get_buffer_size() set_buffer_size(buffer_size) yield finally: set_buffer_size(original_buffer_size) @parameterized.expand([ ("wav", "float32"), ("wav", "int32"), ("wav", "int16"), ("wav", "uint8"), ]) def test_fileobj(self, ext, dtype): """Querying audio via file object works""" sample_rate = 16000 num_frames = 3 * sample_rate num_channels = 2 sinfo = self._query_fileobj(ext, dtype, sample_rate, num_channels, num_frames) bits_per_sample = get_bits_per_sample(ext, dtype) num_frames = 0 if ext in ["mp3", "vorbis"] else num_frames assert sinfo.sample_rate == sample_rate assert sinfo.num_channels == num_channels assert sinfo.num_frames == num_frames assert sinfo.bits_per_sample == bits_per_sample assert sinfo.encoding == get_encoding(ext, dtype) @parameterized.expand([ ("wav", "float32"), ("wav", "int32"), ("wav", "int16"), ("wav", "uint8"), ]) def test_bytesio(self, ext, dtype): """Querying audio via ByteIO object works for small data""" sample_rate = 16000 num_frames = 3 * sample_rate num_channels = 2 sinfo = self._query_bytesio(ext, dtype, sample_rate, num_channels, num_frames) bits_per_sample = get_bits_per_sample(ext, dtype) num_frames = 0 if ext in ["mp3", "vorbis"] else num_frames assert sinfo.sample_rate == sample_rate assert sinfo.num_channels == num_channels assert sinfo.num_frames == num_frames assert sinfo.bits_per_sample == bits_per_sample assert sinfo.encoding == get_encoding(ext, dtype) @parameterized.expand([ ("wav", "float32"), ("wav", "int32"), ("wav", "int16"), ("wav", "uint8"), ]) def test_bytesio_tiny(self, ext, dtype): """Querying audio via ByteIO object works for small data""" sample_rate = 8000 num_frames = 4 num_channels = 2 sinfo = self._query_bytesio(ext, dtype, sample_rate, num_channels, num_frames) bits_per_sample = get_bits_per_sample(ext, dtype) num_frames = 0 if ext in ["mp3", "vorbis"] else num_frames assert sinfo.sample_rate == sample_rate assert sinfo.num_channels == num_channels assert sinfo.num_frames == num_frames assert sinfo.bits_per_sample == bits_per_sample assert sinfo.encoding == get_encoding(ext, dtype) @parameterized.expand([ ("wav", "float32"), ("wav", "int32"), ("wav", "int16"), ("wav", "uint8"), ("flac", "float32"), ("vorbis", "float32"), ("amb", "int16"), ]) def test_tarfile(self, ext, dtype): """Querying compressed audio via file-like object works""" sample_rate = 16000 num_frames = 3.0 * sample_rate num_channels = 2 sinfo = self._query_tarfile(ext, dtype, sample_rate, num_channels, num_frames) bits_per_sample = get_bits_per_sample(ext, dtype) num_frames = 0 if ext in ["vorbis"] else num_frames assert sinfo.sample_rate == sample_rate assert sinfo.num_channels == num_channels assert sinfo.num_frames == num_frames assert sinfo.bits_per_sample == bits_per_sample assert sinfo.encoding == get_encoding(ext, dtype) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/sox_io/load_test.py ================================================ import itertools import platform import unittest if platform.system() == "Windows": import warnings warnings.warn("sox io not support in Windows, please skip test.") exit() from parameterized import parameterized import numpy as np from paddleaudio.backends import sox_io_backend from common_utils import ( get_wav_data, load_wav, save_wav, ) #code is from:https://github.com/pytorch/audio/blob/main/torchaudio/test/torchaudio_unittest/backend/sox_io/load_test.py class TestLoad(unittest.TestCase): def assert_wav(self, dtype, sample_rate, num_channels, normalize, duration): """`sox_io_backend.load` can load wav format correctly. Wav data loaded with sox_io backend should match those with scipy """ path = 'testdata/reference.wav' data = get_wav_data( dtype, num_channels, normalize=normalize, num_frames=duration * sample_rate) save_wav(path, data, sample_rate) expected = load_wav(path, normalize=normalize)[0] data, sr = sox_io_backend.load(path, normalize=normalize) assert sr == sample_rate np.testing.assert_array_almost_equal(data, expected, decimal=4) @parameterized.expand( list( itertools.product( [ "float64", "float32", "int32", ], [8000, 16000], [1, 2], [False, True], )), ) def test_wav(self, dtype, sample_rate, num_channels, normalize): """`sox_io_backend.load` can load wav format correctly.""" self.assert_wav(dtype, sample_rate, num_channels, normalize, duration=1) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/sox_io/save_test.py ================================================ import io import platform import unittest if platform.system() == "Windows": import warnings warnings.warn("sox io not support in Windows, please skip test.") exit() import numpy as np from paddleaudio.backends import sox_io_backend from common_utils import (get_wav_data, load_wav, save_wav, nested_params, TempDirMixin, sox_utils) #code is from:https://github.com/pytorch/audio/blob/main/torchaudio/test/torchaudio_unittest/backend/sox_io/save_test.py def _get_sox_encoding(encoding): encodings = { "PCM_F": "floating-point", "PCM_S": "signed-integer", "PCM_U": "unsigned-integer", "ULAW": "u-law", "ALAW": "a-law", } return encodings.get(encoding) class TestSaveBase(TempDirMixin): def assert_save_consistency( self, format: str, *, compression: float=None, encoding: str=None, bits_per_sample: int=None, sample_rate: float=8000, num_channels: int=2, num_frames: float=3 * 8000, src_dtype: str="int32", test_mode: str="path", ): """`save` function produces file that is comparable with `sox` command To compare that the file produced by `save` function against the file produced by the equivalent `sox` command, we need to load both files. But there are many formats that cannot be opened with common Python modules (like SciPy). So we use `sox` command to prepare the original data and convert the saved files into a format that SciPy can read (PCM wav). The following diagram illustrates this process. The difference is 2.1. and 3.1. This assumes that - loading data with SciPy preserves the data well. - converting the resulting files into WAV format with `sox` preserve the data well. x | 1. Generate source wav file with SciPy | v -------------- wav ---------------- | | | 2.1. load with scipy | 3.1. Convert to the target | then save it into the target | format depth with sox | format with paddleaudio | v v target format target format | | | 2.2. Convert to wav with sox | 3.2. Convert to wav with sox | | v v wav wav | | | 2.3. load with scipy | 3.3. load with scipy | | v v tensor -------> compare <--------- tensor """ cmp_encoding = "floating-point" cmp_bit_depth = 32 src_path = self.get_temp_path("1.source.wav") tgt_path = self.get_temp_path(f"2.1.paddleaudio.{format}") tst_path = self.get_temp_path("2.2.result.wav") sox_path = self.get_temp_path(f"3.1.sox.{format}") ref_path = self.get_temp_path("3.2.ref.wav") # 1. Generate original wav data = get_wav_data( src_dtype, num_channels, normalize=False, num_frames=num_frames) save_wav(src_path, data, sample_rate) # 2.1. Convert the original wav to target format with paddleaudio data = load_wav(src_path, normalize=False)[0] if test_mode == "path": sox_io_backend.save( tgt_path, data, sample_rate, compression=compression, encoding=encoding, bits_per_sample=bits_per_sample) elif test_mode == "fileobj": with open(tgt_path, "bw") as file_: sox_io_backend.save( file_, data, sample_rate, format=format, compression=compression, encoding=encoding, bits_per_sample=bits_per_sample, ) elif test_mode == "bytesio": file_ = io.BytesIO() sox_io_backend.save( file_, data, sample_rate, format=format, compression=compression, encoding=encoding, bits_per_sample=bits_per_sample, ) file_.seek(0) with open(tgt_path, "bw") as f: f.write(file_.read()) else: raise ValueError(f"Unexpected test mode: {test_mode}") # 2.2. Convert the target format to wav with sox sox_utils.convert_audio_file( tgt_path, tst_path, encoding=cmp_encoding, bit_depth=cmp_bit_depth) # 2.3. Load with SciPy found = load_wav(tst_path, normalize=False)[0] # 3.1. Convert the original wav to target format with sox sox_encoding = _get_sox_encoding(encoding) sox_utils.convert_audio_file( src_path, sox_path, compression=compression, encoding=sox_encoding, bit_depth=bits_per_sample) # 3.2. Convert the target format to wav with sox sox_utils.convert_audio_file( sox_path, ref_path, encoding=cmp_encoding, bit_depth=cmp_bit_depth) # 3.3. Load with SciPy expected = load_wav(ref_path, normalize=False)[0] np.testing.assert_array_almost_equal(found, expected) class TestSave(TestSaveBase, unittest.TestCase): @nested_params( [ "path", ], [ ("PCM_U", 8), ("PCM_S", 16), ("PCM_S", 32), ("PCM_F", 32), ("PCM_F", 64), ("ULAW", 8), ("ALAW", 8), ], ) def test_save_wav(self, test_mode, enc_params): encoding, bits_per_sample = enc_params self.assert_save_consistency( "wav", encoding=encoding, bits_per_sample=bits_per_sample, test_mode=test_mode) @nested_params( [ "path", ], [ ("float32", ), ("int32", ), ], ) def test_save_wav_dtype(self, test_mode, params): (dtype, ) = params self.assert_save_consistency( "wav", src_dtype=dtype, test_mode=test_mode) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/sox_io/smoke_test.py ================================================ import io import itertools import platform import unittest if platform.system() == "Windows": import warnings warnings.warn("sox io not support in Windows, please skip test.") exit() from parameterized import parameterized from paddleaudio.backends import sox_io_backend from common_utils import (get_wav_data, TempDirMixin, name_func) class SmokeTest(TempDirMixin, unittest.TestCase): """Run smoke test on various audio format The purpose of this test suite is to verify that sox_io_backend functionalities do not exhibit abnormal behaviors. This test suite should be able to run without any additional tools (such as sox command), however without such tools, the correctness of each function cannot be verified. """ def run_smoke_test(self, ext, sample_rate, num_channels, *, compression=None, dtype="float32"): duration = 1 num_frames = sample_rate * duration #path = self.get_temp_path(f"test.{ext}") path = self.get_temp_path(f"test.{ext}") original = get_wav_data( dtype, num_channels, normalize=False, num_frames=num_frames) # 1. run save sox_io_backend.save( path, original, sample_rate, compression=compression) # 2. run info info = sox_io_backend.info(path) assert info.sample_rate == sample_rate assert info.num_channels == num_channels # 3. run load loaded, sr = sox_io_backend.load(path, normalize=False) assert sr == sample_rate assert loaded.shape[0] == num_channels @parameterized.expand( list( itertools.product( ["float32", "int32"], #["float32", "int32", "int16", "uint8"], [8000, 16000], [1, 2], )), name_func=name_func, ) def test_wav(self, dtype, sample_rate, num_channels): """Run smoke test on wav format""" self.run_smoke_test("wav", sample_rate, num_channels, dtype=dtype) #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #[-4.2, -0.2, 0, 0.2, 96, 128, 160, 192, 224, 256, 320], #) #) #) #def test_mp3(self, sample_rate, num_channels, bit_rate): #"""Run smoke test on mp3 format""" #self.run_smoke_test("mp3", sample_rate, num_channels, compression=bit_rate) #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #[-1, 0, 1, 2, 3, 3.6, 5, 10], #) #) #) #def test_vorbis(self, sample_rate, num_channels, quality_level): #"""Run smoke test on vorbis format""" #self.run_smoke_test("vorbis", sample_rate, num_channels, compression=quality_level) @parameterized.expand( list(itertools.product( [8000, 16000], [1, 2], list(range(9)), )), name_func=name_func, ) def test_flac(self, sample_rate, num_channels, compression_level): """Run smoke test on flac format""" self.run_smoke_test( "flac", sample_rate, num_channels, compression=compression_level) class SmokeTestFileObj(unittest.TestCase): """Run smoke test on various audio format The purpose of this test suite is to verify that sox_io_backend functionalities do not exhibit abnormal behaviors. This test suite should be able to run without any additional tools (such as sox command), however without such tools, the correctness of each function cannot be verified. """ def run_smoke_test(self, ext, sample_rate, num_channels, *, compression=None, dtype="float32"): duration = 1 num_frames = sample_rate * duration original = get_wav_data( dtype, num_channels, normalize=False, num_frames=num_frames) fileobj = io.BytesIO() # 1. run save sox_io_backend.save( fileobj, original, sample_rate, compression=compression, format=ext) # 2. run info fileobj.seek(0) info = sox_io_backend.info(fileobj, format=ext) assert info.sample_rate == sample_rate assert info.num_channels == num_channels # 3. run load fileobj.seek(0) loaded, sr = sox_io_backend.load(fileobj, normalize=False, format=ext) assert sr == sample_rate assert loaded.shape[0] == num_channels @parameterized.expand( list(itertools.product( ["float32", "int32"], [8000, 16000], [1, 2], )), name_func=name_func, ) def test_wav(self, dtype, sample_rate, num_channels): """Run smoke test on wav format""" self.run_smoke_test("wav", sample_rate, num_channels, dtype=dtype) # not support yet #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #[-4.2, -0.2, 0, 0.2, 96, 128, 160, 192, 224, 256, 320], #) #) #) #def test_mp3(self, sample_rate, num_channels, bit_rate): #"""Run smoke test on mp3 format""" #self.run_smoke_test("mp3", sample_rate, num_channels, compression=bit_rate) #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #[-1, 0, 1, 2, 3, 3.6, 5, 10], #) #) #) #def test_vorbis(self, sample_rate, num_channels, quality_level): #"""Run smoke test on vorbis format""" #self.run_smoke_test("vorbis", sample_rate, num_channels, compression=quality_level) @parameterized.expand( list(itertools.product( [8000, 16000], [1, 2], list(range(9)), )), name_func=name_func, ) def test_flac(self, sample_rate, num_channels, compression_level): #"""Run smoke test on flac format""" self.run_smoke_test( "flac", sample_rate, num_channels, compression=compression_level) if __name__ == '__main__': #test_func() unittest.main() ================================================ FILE: audio/tests/backends/sox_io/sox_effect_test.py ================================================ #code is from: https://github.com/pytorch/audio/blob/main/test/torchaudio_unittest/sox_effect/sox_effect_test.py import io import itertools import platform import tarfile import unittest from pathlib import Path import numpy as np if platform.system() == "Windows": import warnings warnings.warn("sox io not support in Windows, please skip test.") exit() from parameterized import parameterized from paddleaudio import sox_effects from common_utils import (get_sinusoid, get_wav_data, load_wav, save_wav, sox_utils, TempDirMixin, load_effects_params) class TestSoxEffects(unittest.TestCase): def test_init(self): """Calling init_sox_effects multiple times does not crush""" for _ in range(3): sox_effects.init_sox_effects() class TestSoxEffectsTensor(TempDirMixin, unittest.TestCase): """Test suite for `apply_effects_tensor` function""" @parameterized.expand( list( itertools.product(["float32", "int32"], [8000, 16000], [1, 2, 4, 8], [True, False])), ) def test_apply_no_effect(self, dtype, sample_rate, num_channels, channels_first): """`apply_effects_tensor` without effects should return identical data as input""" original = get_wav_data( dtype, num_channels, channels_first=channels_first) expected = original.clone() found, output_sample_rate = sox_effects.apply_effects_tensor( expected, sample_rate, [], channels_first) assert (output_sample_rate == sample_rate) # SoxEffect should not alter the input Tensor object #self.assertEqual(original, expected) np.testing.assert_array_almost_equal(original.numpy(), expected.numpy()) # SoxEffect should not return the same Tensor object assert expected is not found # Returned Tensor should equal to the input Tensor #self.assertEqual(expected, found) np.testing.assert_array_almost_equal(expected.numpy(), found.numpy()) @parameterized.expand( load_effects_params("sox_effect_test_args.jsonl"), name_func=lambda f, i, p: f'{f.__name__}_{i}_{p.args[0]["effects"][0][0]}', ) def test_apply_effects(self, args): """`apply_effects_tensor` should return identical data as sox command""" effects = args["effects"] num_channels = args.get("num_channels", 2) input_sr = args.get("input_sample_rate", 8000) output_sr = args.get("output_sample_rate") input_path = self.get_temp_path("input.wav") reference_path = self.get_temp_path("reference.wav") original = get_sinusoid( frequency=800, sample_rate=input_sr, n_channels=num_channels, dtype="float32") save_wav(input_path, original, input_sr) sox_utils.run_sox_effect( input_path, reference_path, effects, output_sample_rate=output_sr) expected, expected_sr = load_wav(reference_path) found, sr = sox_effects.apply_effects_tensor(original, input_sr, effects) assert sr == expected_sr #self.assertEqual(expected, found) np.testing.assert_array_almost_equal(expected.numpy(), found.numpy()) class TestSoxEffectsFile(TempDirMixin, unittest.TestCase): """Test suite for `apply_effects_file` function""" @parameterized.expand( list( itertools.product( ["float32", "int32"], [8000, 16000], [1, 2, 4, 8], [False, True], )), #name_func=name_func, ) def test_apply_no_effect(self, dtype, sample_rate, num_channels, channels_first): """`apply_effects_file` without effects should return identical data as input""" path = self.get_temp_path("input.wav") expected = get_wav_data( dtype, num_channels, channels_first=channels_first) save_wav(path, expected, sample_rate, channels_first=channels_first) found, output_sample_rate = sox_effects.apply_effects_file( path, [], normalize=False, channels_first=channels_first) assert output_sample_rate == sample_rate #self.assertEqual(expected, found) np.testing.assert_array_almost_equal(expected.numpy(), found.numpy()) @parameterized.expand( load_effects_params("sox_effect_test_args.jsonl"), #name_func=lambda f, i, p: f'{f.__name__}_{i}_{p.args[0]["effects"][0][0]}', ) def test_apply_effects_str(self, args): """`apply_effects_file` should return identical data as sox command""" dtype = "int32" channels_first = True effects = args["effects"] num_channels = args.get("num_channels", 2) input_sr = args.get("input_sample_rate", 8000) output_sr = args.get("output_sample_rate") input_path = self.get_temp_path("input.wav") reference_path = self.get_temp_path("reference.wav") data = get_wav_data(dtype, num_channels, channels_first=channels_first) save_wav(input_path, data, input_sr, channels_first=channels_first) sox_utils.run_sox_effect( input_path, reference_path, effects, output_sample_rate=output_sr) expected, expected_sr = load_wav(reference_path) found, sr = sox_effects.apply_effects_file( input_path, effects, normalize=False, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(expected.numpy(), found.numpy()) def test_apply_effects_path(self): """`apply_effects_file` should return identical data as sox command when file path is given as a Path Object""" dtype = "int32" channels_first = True effects = [["hilbert"]] num_channels = 2 input_sr = 8000 output_sr = 8000 input_path = self.get_temp_path("input.wav") reference_path = self.get_temp_path("reference.wav") data = get_wav_data(dtype, num_channels, channels_first=channels_first) save_wav(input_path, data, input_sr, channels_first=channels_first) sox_utils.run_sox_effect( input_path, reference_path, effects, output_sample_rate=output_sr) expected, expected_sr = load_wav(reference_path) found, sr = sox_effects.apply_effects_file( Path(input_path), effects, normalize=False, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(expected.numpy(), found.numpy()) class TestFileFormats(TempDirMixin, unittest.TestCase): """`apply_effects_file` gives the same result as sox on various file formats""" @parameterized.expand( list(itertools.product( ["float32", "int32"], [8000, 16000], [1, 2], )), #name_func=lambda f, _, p: f'{f.__name__}_{"_".join(str(arg) for arg in p.args)}', ) def test_wav(self, dtype, sample_rate, num_channels): """`apply_effects_file` works on various wav format""" channels_first = True effects = [["band", "300", "10"]] input_path = self.get_temp_path("input.wav") reference_path = self.get_temp_path("reference.wav") data = get_wav_data(dtype, num_channels, channels_first=channels_first) save_wav(input_path, data, sample_rate, channels_first=channels_first) sox_utils.run_sox_effect(input_path, reference_path, effects) expected, expected_sr = load_wav(reference_path) found, sr = sox_effects.apply_effects_file( input_path, effects, normalize=False, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) #not support now #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #) #), ##name_func=lambda f, _, p: f'{f.__name__}_{"_".join(str(arg) for arg in p.args)}', #) #def test_flac(self, sample_rate, num_channels): #"""`apply_effects_file` works on various flac format""" #channels_first = True #effects = [["band", "300", "10"]] #input_path = self.get_temp_path("input.flac") #reference_path = self.get_temp_path("reference.wav") #sox_utils.gen_audio_file(input_path, sample_rate, num_channels) #sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32) #expected, expected_sr = load_wav(reference_path) #found, sr = sox_effects.apply_effects_file(input_path, effects, channels_first=channels_first) #save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first) #assert sr == expected_sr ##self.assertEqual(found, expected) #np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) #@parameterized.expand( #list( #itertools.product( #[8000, 16000], #[1, 2], #) #), ##name_func=lambda f, _, p: f'{f.__name__}_{"_".join(str(arg) for arg in p.args)}', #) #def test_vorbis(self, sample_rate, num_channels): #"""`apply_effects_file` works on various vorbis format""" #channels_first = True #effects = [["band", "300", "10"]] #input_path = self.get_temp_path("input.vorbis") #reference_path = self.get_temp_path("reference.wav") #sox_utils.gen_audio_file(input_path, sample_rate, num_channels) #sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32) #expected, expected_sr = load_wav(reference_path) #found, sr = sox_effects.apply_effects_file(input_path, effects, channels_first=channels_first) #save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first) #assert sr == expected_sr ##self.assertEqual(found, expected) #np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) #@skipIfNoExec("sox") #@skipIfNoSox class TestFileObject(TempDirMixin, unittest.TestCase): @parameterized.expand([ ("wav", None), ]) def test_fileobj(self, ext, compression): """Applying effects via file object works""" sample_rate = 16000 channels_first = True effects = [["band", "300", "10"]] input_path = self.get_temp_path(f"input.{ext}") reference_path = self.get_temp_path("reference.wav") #sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression) data = get_wav_data("int32", 2, channels_first=channels_first) save_wav(input_path, data, sample_rate, channels_first=channels_first) sox_utils.run_sox_effect( input_path, reference_path, effects, output_bitdepth=32) expected, expected_sr = load_wav(reference_path) with open(input_path, "rb") as fileobj: found, sr = sox_effects.apply_effects_file( fileobj, effects, channels_first=channels_first) save_wav( self.get_temp_path("result.wav"), found, sr, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) @parameterized.expand([ ("wav", None), ]) def test_bytesio(self, ext, compression): """Applying effects via BytesIO object works""" sample_rate = 16000 channels_first = True effects = [["band", "300", "10"]] input_path = self.get_temp_path(f"input.{ext}") reference_path = self.get_temp_path("reference.wav") #sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression) data = get_wav_data("int32", 2, channels_first=channels_first) save_wav(input_path, data, sample_rate, channels_first=channels_first) sox_utils.run_sox_effect( input_path, reference_path, effects, output_bitdepth=32) expected, expected_sr = load_wav(reference_path) with open(input_path, "rb") as file_: fileobj = io.BytesIO(file_.read()) found, sr = sox_effects.apply_effects_file( fileobj, effects, channels_first=channels_first) save_wav( self.get_temp_path("result.wav"), found, sr, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) print("found") print(found) print("expected") print(expected) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) @parameterized.expand([ ("wav", None), ]) def test_tarfile(self, ext, compression): """Applying effects to compressed audio via file-like file works""" sample_rate = 16000 channels_first = True effects = [["band", "300", "10"]] audio_file = f"input.{ext}" input_path = self.get_temp_path(audio_file) reference_path = self.get_temp_path("reference.wav") archive_path = self.get_temp_path("archive.tar.gz") data = get_wav_data("int32", 2, channels_first=channels_first) save_wav(input_path, data, sample_rate, channels_first=channels_first) # sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression) sox_utils.run_sox_effect( input_path, reference_path, effects, output_bitdepth=32) expected, expected_sr = load_wav(reference_path) with tarfile.TarFile(archive_path, "w") as tarobj: tarobj.add(input_path, arcname=audio_file) with tarfile.TarFile(archive_path, "r") as tarobj: fileobj = tarobj.extractfile(audio_file) found, sr = sox_effects.apply_effects_file( fileobj, effects, channels_first=channels_first) save_wav( self.get_temp_path("result.wav"), found, sr, channels_first=channels_first) assert sr == expected_sr #self.assertEqual(found, expected) np.testing.assert_array_almost_equal(found.numpy(), expected.numpy()) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/backends/sox_io/sox_effect_test_args.jsonl ================================================ {"effects": [["allpass", "300", "10"]]} {"effects": [["band", "300", "10"]]} {"effects": [["bandpass", "300", "10"]]} {"effects": [["bandreject", "300", "10"]]} {"effects": [["bass", "-10"]]} {"effects": [["biquad", "0.4", "0.2", "0.9", "0.7", "0.2", "0.6"]]} {"effects": [["chorus", "0.7", "0.9", "55", "0.4", "0.25", "2", "-t"]]} {"effects": [["chorus", "0.6", "0.9", "50", "0.4", "0.25", "2", "-t", "60", "0.32", "0.4", "1.3", "-s"]]} {"effects": [["chorus", "0.5", "0.9", "50", "0.4", "0.25", "2", "-t", "60", "0.32", "0.4", "2.3", "-t", "40", "0.3", "0.3", "1.3", "-s"]]} {"effects": [["channels", "1"]]} {"effects": [["channels", "2"]]} {"effects": [["channels", "3"]]} {"effects": [["compand", "0.3,1", "6:-70,-60,-20", "-5", "-90", "0.2"]]} {"effects": [["compand", ".1,.2", "-inf,-50.1,-inf,-50,-50", "0", "-90", ".1"]]} {"effects": [["compand", ".1,.1", "-45.1,-45,-inf,0,-inf", "45", "-90", ".1"]]} {"effects": [["contrast", "0"]]} {"effects": [["contrast", "25"]]} {"effects": [["contrast", "50"]]} {"effects": [["contrast", "75"]]} {"effects": [["contrast", "100"]]} {"effects": [["dcshift", "1.0"]]} {"effects": [["dcshift", "-1.0"]]} {"effects": [["deemph"]], "input_sample_rate": 44100} {"effects": [["dither", "-s"]]} {"effects": [["dither", "-S"]]} {"effects": [["divide"]]} {"effects": [["downsample", "2"]], "input_sample_rate": 8000, "output_sample_rate": 4000} {"effects": [["earwax"]], "input_sample_rate": 44100} {"effects": [["echo", "0.8", "0.88", "60", "0.4"]]} {"effects": [["echo", "0.8", "0.88", "6", "0.4"]]} {"effects": [["echo", "0.8", "0.9", "1000", "0.3"]]} {"effects": [["echo", "0.8", "0.9", "1000", "0.3", "1800", "0.25"]]} {"effects": [["echos", "0.8", "0.7", "700", "0.25", "700", "0.3"]]} {"effects": [["echos", "0.8", "0.7", "700", "0.25", "900", "0.3"]]} {"effects": [["echos", "0.8", "0.7", "40", "0.25", "63", "0.3"]]} {"effects": [["equalizer", "300", "10", "5"]]} {"effects": [["fade", "q", "3"]]} {"effects": [["fade", "h", "3"]]} {"effects": [["fade", "t", "3"]]} {"effects": [["fade", "l", "3"]]} {"effects": [["fade", "p", "3"]]} {"effects": [["fir", "0.0195", "-0.082", "0.234", "0.891", "-0.145", "0.043"]]} {"effects": [["flanger"]]} {"effects": [["gain", "-l", "-6"]]} {"effects": [["highpass", "-1", "300"]]} {"effects": [["highpass", "-2", "300"]]} {"effects": [["hilbert"]]} {"effects": [["loudness"]]} {"effects": [["lowpass", "-1", "300"]]} {"effects": [["lowpass", "-2", "300"]]} {"effects": [["mcompand", "0.005,0.1 -47,-40,-34,-34,-17,-33", "100", "0.003,0.05 -47,-40,-34,-34,-17,-33", "400", "0.000625,0.0125 -47,-40,-34,-34,-15,-33", "1600", "0.0001,0.025 -47,-40,-34,-34,-31,-31,-0,-30", "6400", "0,0.025 -38,-31,-28,-28,-0,-25"]], "input_sample_rate": 44100} {"effects": [["oops"]]} {"effects": [["overdrive"]]} {"effects": [["pad"]]} {"effects": [["phaser"]]} {"effects": [["remix", "6", "7", "8", "0"]], "num_channels": 8} {"effects": [["remix", "1-3,7", "3"]], "num_channels": 8} {"effects": [["repeat"]]} {"effects": [["reverb"]]} {"effects": [["reverse"]]} {"effects": [["riaa"]], "input_sample_rate": 44100} {"effects": [["silence", "0"]]} {"effects": [["speed", "1.3"]], "input_sample_rate": 4000, "output_sample_rate": 5200} {"effects": [["speed", "0.7"]], "input_sample_rate": 4000, "output_sample_rate": 2800} {"effects": [["stat"]]} {"effects": [["stats"]]} {"effects": [["stretch"]]} {"effects": [["swap"]]} {"effects": [["synth"]]} {"effects": [["tempo", "0.9"]]} {"effects": [["tempo", "1.1"]]} {"effects": [["treble", "3"]]} {"effects": [["tremolo", "300", "40"]]} {"effects": [["tremolo", "300", "50"]]} {"effects": [["trim", "0", "0.1"]]} {"effects": [["upsample", "2"]], "input_sample_rate": 8000, "output_sample_rate": 16000} {"effects": [["vol", "3"]]} ================================================ FILE: audio/tests/benchmark/README.md ================================================ # 1. Prepare First, install `pytest-benchmark` via pip. ```sh pip install pytest-benchmark ``` # 2. Run Run the specific script for profiling. ```sh pytest melspectrogram.py ``` Result: ```sh ========================================================================== test session starts ========================================================================== platform linux -- Python 3.7.7, pytest-7.0.1, pluggy-1.0.0 benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000) rootdir: /ssd3/chenxiaojie06/PaddleSpeech/DeepSpeech/paddleaudio plugins: typeguard-2.12.1, benchmark-3.4.1, anyio-3.5.0 collected 4 items melspectrogram.py .... [100%] -------------------------------------------------------------------------------------------------- benchmark: 4 tests ------------------------------------------------------------------------------------------------- Name (time in us) Min Max Mean StdDev Median IQR Outliers OPS Rounds Iterations ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- test_melspect_gpu_torchaudio 202.0765 (1.0) 360.6230 (1.0) 218.1168 (1.0) 16.3022 (1.0) 214.2871 (1.0) 21.8451 (1.0) 40;3 4,584.7001 (1.0) 286 1 test_melspect_gpu 657.8509 (3.26) 908.0470 (2.52) 724.2545 (3.32) 106.5771 (6.54) 669.9096 (3.13) 113.4719 (5.19) 1;0 1,380.7300 (0.30) 5 1 test_melspect_cpu_torchaudio 1,247.6053 (6.17) 2,892.5799 (8.02) 1,443.2853 (6.62) 345.3732 (21.19) 1,262.7263 (5.89) 221.6385 (10.15) 56;53 692.8637 (0.15) 399 1 test_melspect_cpu 20,326.2549 (100.59) 20,607.8682 (57.15) 20,473.4125 (93.86) 63.8654 (3.92) 20,467.0429 (95.51) 68.4294 (3.13) 8;1 48.8438 (0.01) 29 1 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Legend: Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile. OPS: Operations Per Second, computed as 1 / Mean ========================================================================== 4 passed in 21.12s =========================================================================== ``` ================================================ FILE: audio/tests/benchmark/log_melspectrogram.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import urllib.request import librosa import numpy as np import paddle import paddleaudio import torch import torchaudio wav_url = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' if not os.path.isfile(os.path.basename(wav_url)): urllib.request.urlretrieve(wav_url, os.path.basename(wav_url)) waveform, sr = paddleaudio.backends.soundfile_load( os.path.abspath(os.path.basename(wav_url))) waveform_tensor = paddle.to_tensor(waveform).unsqueeze(0) waveform_tensor_torch = torch.from_numpy(waveform).unsqueeze(0) # Feature conf mel_conf = { 'sr': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, } mel_conf_torchaudio = { 'sample_rate': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, 'norm': 'slaney', 'mel_scale': 'slaney', } def enable_cpu_device(): paddle.set_device('cpu') def enable_gpu_device(): paddle.set_device('gpu') log_mel_extractor = paddle.audio.features.LogMelSpectrogram( **mel_conf, f_min=0.0, top_db=80.0, dtype=waveform_tensor.dtype) def log_melspectrogram(): return log_mel_extractor(waveform_tensor).squeeze(0) def test_log_melspect_cpu(benchmark): enable_cpu_device() feature_paddleaudio = benchmark(log_melspectrogram) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) feature_librosa = librosa.power_to_db(feature_librosa, top_db=80.0) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_log_melspect_gpu(benchmark): enable_gpu_device() feature_paddleaudio = benchmark(log_melspectrogram) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) feature_librosa = librosa.power_to_db(feature_librosa, top_db=80.0) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=2) mel_extractor_torchaudio = torchaudio.transforms.MelSpectrogram( **mel_conf_torchaudio, f_min=0.0) amplitude_to_DB = torchaudio.transforms.AmplitudeToDB('power', top_db=80.0) def melspectrogram_torchaudio(): return mel_extractor_torchaudio(waveform_tensor_torch).squeeze(0) def log_melspectrogram_torchaudio(): mel_specgram = mel_extractor_torchaudio(waveform_tensor_torch) return amplitude_to_DB(mel_specgram).squeeze(0) def test_log_melspect_cpu_torchaudio(benchmark): global waveform_tensor_torch, mel_extractor_torchaudio, amplitude_to_DB mel_extractor_torchaudio = mel_extractor_torchaudio.to('cpu') waveform_tensor_torch = waveform_tensor_torch.to('cpu') amplitude_to_DB = amplitude_to_DB.to('cpu') feature_paddleaudio = benchmark(log_melspectrogram_torchaudio) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) feature_librosa = librosa.power_to_db(feature_librosa, top_db=80.0) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_log_melspect_gpu_torchaudio(benchmark): global waveform_tensor_torch, mel_extractor_torchaudio, amplitude_to_DB mel_extractor_torchaudio = mel_extractor_torchaudio.to('cuda') waveform_tensor_torch = waveform_tensor_torch.to('cuda') amplitude_to_DB = amplitude_to_DB.to('cuda') feature_torchaudio = benchmark(log_melspectrogram_torchaudio) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) feature_librosa = librosa.power_to_db(feature_librosa, top_db=80.0) np.testing.assert_array_almost_equal( feature_librosa, feature_torchaudio.cpu(), decimal=2) ================================================ FILE: audio/tests/benchmark/melspectrogram.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import urllib.request import librosa import numpy as np import paddle import paddleaudio import torch import torchaudio wav_url = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' if not os.path.isfile(os.path.basename(wav_url)): urllib.request.urlretrieve(wav_url, os.path.basename(wav_url)) waveform, sr = paddleaudio.backends.soundfile_load( os.path.abspath(os.path.basename(wav_url))) waveform_tensor = paddle.to_tensor(waveform).unsqueeze(0) waveform_tensor_torch = torch.from_numpy(waveform).unsqueeze(0) # Feature conf mel_conf = { 'sr': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, } mel_conf_torchaudio = { 'sample_rate': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, 'norm': 'slaney', 'mel_scale': 'slaney', } def enable_cpu_device(): paddle.set_device('cpu') def enable_gpu_device(): paddle.set_device('gpu') mel_extractor = paddle.audio.features.MelSpectrogram( **mel_conf, f_min=0.0, dtype=waveform_tensor.dtype) def melspectrogram(): return mel_extractor(waveform_tensor).squeeze(0) def test_melspect_cpu(benchmark): enable_cpu_device() feature_paddleaudio = benchmark(melspectrogram) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_melspect_gpu(benchmark): enable_gpu_device() feature_paddleaudio = benchmark(melspectrogram) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) mel_extractor_torchaudio = torchaudio.transforms.MelSpectrogram( **mel_conf_torchaudio, f_min=0.0) def melspectrogram_torchaudio(): return mel_extractor_torchaudio(waveform_tensor_torch).squeeze(0) def test_melspect_cpu_torchaudio(benchmark): global waveform_tensor_torch, mel_extractor_torchaudio mel_extractor_torchaudio = mel_extractor_torchaudio.to('cpu') waveform_tensor_torch = waveform_tensor_torch.to('cpu') feature_paddleaudio = benchmark(melspectrogram_torchaudio) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_melspect_gpu_torchaudio(benchmark): global waveform_tensor_torch, mel_extractor_torchaudio mel_extractor_torchaudio = mel_extractor_torchaudio.to('cuda') waveform_tensor_torch = waveform_tensor_torch.to('cuda') feature_torchaudio = benchmark(melspectrogram_torchaudio) feature_librosa = librosa.feature.melspectrogram(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_torchaudio.cpu(), decimal=3) ================================================ FILE: audio/tests/benchmark/mfcc.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import urllib.request import librosa import numpy as np import paddle import paddleaudio import torch import torchaudio wav_url = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' if not os.path.isfile(os.path.basename(wav_url)): urllib.request.urlretrieve(wav_url, os.path.basename(wav_url)) waveform, sr = paddleaudio.backends.soundfile_load( os.path.abspath(os.path.basename(wav_url))) waveform_tensor = paddle.to_tensor(waveform).unsqueeze(0) waveform_tensor_torch = torch.from_numpy(waveform).unsqueeze(0) # Feature conf mel_conf = { 'sr': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, } mfcc_conf = { 'n_mfcc': 20, 'top_db': 80.0, } mfcc_conf.update(mel_conf) mel_conf_torchaudio = { 'sample_rate': sr, 'n_fft': 512, 'hop_length': 128, 'n_mels': 40, 'norm': 'slaney', 'mel_scale': 'slaney', } mfcc_conf_torchaudio = { 'sample_rate': sr, 'n_mfcc': 20, } def enable_cpu_device(): paddle.set_device('cpu') def enable_gpu_device(): paddle.set_device('gpu') mfcc_extractor = paddle.audio.features.MFCC( **mfcc_conf, f_min=0.0, dtype=waveform_tensor.dtype) def mfcc(): return mfcc_extractor(waveform_tensor).squeeze(0) def test_mfcc_cpu(benchmark): enable_cpu_device() feature_paddleaudio = benchmark(mfcc) feature_librosa = librosa.feature.mfcc(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_mfcc_gpu(benchmark): enable_gpu_device() feature_paddleaudio = benchmark(mfcc) feature_librosa = librosa.feature.mfcc(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) del mel_conf_torchaudio['sample_rate'] mfcc_extractor_torchaudio = torchaudio.transforms.MFCC( **mfcc_conf_torchaudio, melkwargs=mel_conf_torchaudio) def mfcc_torchaudio(): return mfcc_extractor_torchaudio(waveform_tensor_torch).squeeze(0) def test_mfcc_cpu_torchaudio(benchmark): global waveform_tensor_torch, mfcc_extractor_torchaudio mel_extractor_torchaudio = mfcc_extractor_torchaudio.to('cpu') waveform_tensor_torch = waveform_tensor_torch.to('cpu') feature_paddleaudio = benchmark(mfcc_torchaudio) feature_librosa = librosa.feature.mfcc(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_paddleaudio, decimal=3) def test_mfcc_gpu_torchaudio(benchmark): global waveform_tensor_torch, mfcc_extractor_torchaudio mel_extractor_torchaudio = mfcc_extractor_torchaudio.to('cuda') waveform_tensor_torch = waveform_tensor_torch.to('cuda') feature_torchaudio = benchmark(mfcc_torchaudio) feature_librosa = librosa.feature.mfcc(waveform, **mel_conf) np.testing.assert_array_almost_equal( feature_librosa, feature_torchaudio.cpu(), decimal=3) ================================================ FILE: audio/tests/common_utils/__init__.py ================================================ from .case_utils import name_func from .case_utils import TempDirMixin from .data_utils import get_sinusoid from .data_utils import load_effects_params from .data_utils import load_params from .parameterized_utils import nested_params from .wav_utils import get_wav_data from .wav_utils import load_wav from .wav_utils import normalize_wav from .wav_utils import save_wav __all__ = [ "get_wav_data", "load_wav", "save_wav", "normalize_wav", "load_params", "nested_params", "get_sinusoid", "name_func", "load_effects_params" ] ================================================ FILE: audio/tests/common_utils/case_utils.py ================================================ import os.path import tempfile #code is from:https://github.com/pytorch/audio/blob/main/test/torchaudio_unittest/common_utils/case_utils.py def name_func(func, _, params): return f'{func.__name__}_{"_".join(str(arg) for arg in params.args)}' class TempDirMixin: """Mixin to provide easy access to temp dir""" temp_dir_ = None @classmethod def get_base_temp_dir(cls): # If PADDLEAUDIO_TEST_TEMP_DIR is set, use it instead of temporary directory. # this is handy for debugging. key = "PADDLEAUDIO_TEST_TEMP_DIR" if key in os.environ: return os.environ[key] if cls.temp_dir_ is None: cls.temp_dir_ = tempfile.TemporaryDirectory() return cls.temp_dir_.name @classmethod def tearDownClass(cls): if cls.temp_dir_ is not None: try: cls.temp_dir_.cleanup() cls.temp_dir_ = None except PermissionError: # On Windows there is a know issue with `shutil.rmtree`, # which fails intermittenly. # # https://github.com/python/cpython/issues/74168 # # We observed this on CircleCI, where Windows job raises # PermissionError. # # Following the above thread, we ignore it. pass super().tearDownClass() def get_temp_path(self, *paths): temp_dir = os.path.join(self.get_base_temp_dir(), self.id()) path = os.path.join(temp_dir, *paths) os.makedirs(os.path.dirname(path), exist_ok=True) return path ================================================ FILE: audio/tests/common_utils/data_utils.py ================================================ import json import os.path import paddle from parameterized import param #code is from:https://github.com/pytorch/audio/blob/main/test/torchaudio_unittest/common_utils/data_utils.py with modification. _TEST_DIR_PATH = os.path.realpath(os.path.join(os.path.dirname(__file__), "..")) def get_asset_path(*paths): """Return full path of a test asset""" return os.path.join(_TEST_DIR_PATH, "assets", *paths) def load_params(*paths): with open(get_asset_path(*paths), "r") as file: return [param(json.loads(line)) for line in file] def load_effects_params(*paths): params = [] with open(*paths, "r") as file: for line in file: data = json.loads(line) for effect in data["effects"]: for i, arg in enumerate(effect): if arg.startswith(""): effect[i] = arg.replace("", get_asset_path()) params.append(param(data)) return params def convert_tensor_encoding( tensor: paddle.tensor, dtype: paddle.dtype, ): """Convert input tensor with values between -1 and 1 to integer encoding Args: tensor: input tensor, assumed between -1 and 1 dtype: desired output tensor dtype Returns: Tensor: shape of (n_channels, sample_rate * duration) """ if dtype == paddle.int32: tensor *= (tensor > 0) * 2147483647 + (tensor < 0) * 2147483648 if dtype == paddle.int16: tensor *= (tensor > 0) * 32767 + (tensor < 0) * 32768 if dtype == paddle.uint8: tensor *= (tensor > 0) * 127 + (tensor < 0) * 128 tensor += 128 tensor = paddle.to_tensor(tensor, dtype) return tensor #def get_whitenoise( #*, #sample_rate: int = 16000, #duration: float = 1, # seconds #n_channels: int = 1, #seed: int = 0, #dtype: Union[str, paddle.dtype] = "float32", #device: Union[str, paddle.device] = "cpu", #channels_first=True, #scale_factor: float = 1, #): #"""Generate pseudo audio data with whitenoise #Args: #sample_rate: Sampling rate #duration: Length of the resulting Tensor in seconds. #n_channels: Number of channels #seed: Seed value used for random number generation. #Note that this function does not modify global random generator state. #dtype: Torch dtype #device: device #channels_first: whether first dimension is n_channels #scale_factor: scale the Tensor before clamping and quantization #Returns: #Tensor: shape of (n_channels, sample_rate * duration) #""" #if isinstance(dtype, str): #dtype = getattr(paddle, dtype) #if dtype not in [paddle.float64, paddle.float32, paddle.int32, paddle.int16, paddle.uint8]: #raise NotImplementedError(f"dtype {dtype} is not supported.") ## According to the doc, forking rng on all CUDA devices is slow when there are many CUDA devices, ## so we only fork on CPU, generate values and move the data to the given device #with paddle.random.fork_rng([]): #paddle.random.manual_seed(seed) #tensor = paddle.randn([n_channels, int(sample_rate * duration)], dtype=paddle.float32, device="cpu") #tensor /= 2.0 #tensor *= scale_factor #tensor.clamp_(-1.0, 1.0) #if not channels_first: #tensor = tensor.t() #tensor = tensor.to(device) #return convert_tensor_encoding(tensor, dtype) def get_sinusoid( *, frequency: float=300, sample_rate: int=16000, duration: float=1, # seconds n_channels: int=1, dtype: str="float32", device: str="cpu", channels_first: bool=True, ): """Generate pseudo audio data with sine wave. Args: frequency: Frequency of sine wave sample_rate: Sampling rate duration: Length of the resulting Tensor in seconds. n_channels: Number of channels dtype: Torch dtype device: device Returns: Tensor: shape of (n_channels, sample_rate * duration) """ if isinstance(dtype, str): dtype = getattr(paddle, dtype) pie2 = 2 * 3.141592653589793 end = pie2 * frequency * duration num_frames = int(sample_rate * duration) # Randomize the initial phase. (except the first channel) theta0 = pie2 * paddle.randn([n_channels, 1], dtype=paddle.float32) theta0[0, :] = 0 theta = paddle.linspace(0, end, num_frames, dtype=paddle.float32) theta = theta0 + theta tensor = paddle.sin(theta) if not channels_first: tensor = paddle.t(tensor) return convert_tensor_encoding(tensor, dtype) ================================================ FILE: audio/tests/common_utils/parameterized_utils.py ================================================ from itertools import product from parameterized import param from parameterized import parameterized def _name_func(func, _, params): strs = [] for arg in params.args: if isinstance(arg, tuple): strs.append("_".join(str(a) for a in arg)) else: strs.append(str(arg)) # sanitize the test name name = "_".join(strs) return parameterized.to_safe_name(f"{func.__name__}_{name}") def nested_params(*params_set, name_func=_name_func): """Generate the cartesian product of the given list of parameters. Args: params_set (list of parameters): Parameters. When using ``parameterized.param`` class, all the parameters have to be specified with the class, only using kwargs. """ flatten = [p for params in params_set for p in params] # Parameters to be nested are given as list of plain objects if all(not isinstance(p, param) for p in flatten): args = list(product(*params_set)) return parameterized.expand(args, name_func=_name_func) # Parameters to be nested are given as list of `parameterized.param` if not all(isinstance(p, param) for p in flatten): raise TypeError("When using ``parameterized.param``, " "all the parameters have to be of the ``param`` type.") if any(p.args for p in flatten): raise ValueError( "When using ``parameterized.param``, " "all the parameters have to be provided as keyword argument.") args = [param()] for params in params_set: args = [param(**x.kwargs, **y.kwargs) for x in args for y in params] return parameterized.expand(args) ================================================ FILE: audio/tests/common_utils/sox_utils.py ================================================ import subprocess import sys import warnings def get_encoding(dtype): encodings = { "float32": "floating-point", "int32": "signed-integer", "int16": "signed-integer", "uint8": "unsigned-integer", } return encodings[dtype] def get_bit_depth(dtype): bit_depths = { "float32": 32, "int32": 32, "int16": 16, "uint8": 8, } return bit_depths[dtype] def gen_audio_file( path, sample_rate, num_channels, *, encoding=None, bit_depth=None, compression=None, attenuation=None, duration=1, comment_file=None, ): """Generate synthetic audio file with `sox` command.""" if path.endswith(".wav"): warnings.warn( "Use get_wav_data and save_wav to generate wav file for accurate result." ) command = [ "sox", "-V3", # verbose "--no-dither", # disable automatic dithering "-R", # -R is supposed to be repeatable, though the implementation looks suspicious # and not setting the seed to a fixed value. # https://fossies.org/dox/sox-14.4.2/sox_8c_source.html # search "sox_globals.repeatable" ] if bit_depth is not None: command += ["--bits", str(bit_depth)] command += [ "--rate", str(sample_rate), "--null", # no input "--channels", str(num_channels), ] if compression is not None: command += ["--compression", str(compression)] if bit_depth is not None: command += ["--bits", str(bit_depth)] if encoding is not None: command += ["--encoding", str(encoding)] if comment_file is not None: command += ["--comment-file", str(comment_file)] command += [ str(path), "synth", str(duration), # synthesizes for the given duration [sec] "sawtooth", "1", # saw tooth covers the both ends of value range, which is a good property for test. # similar to linspace(-1., 1.) # this introduces bigger boundary effect than sine when converted to mp3 ] if attenuation is not None: command += ["vol", f"-{attenuation}dB"] print(" ".join(command), file=sys.stderr) subprocess.run(command, check=True) def convert_audio_file(src_path, dst_path, *, encoding=None, bit_depth=None, compression=None): """Convert audio file with `sox` command.""" command = ["sox", "-V3", "--no-dither", "-R", str(src_path)] if encoding is not None: command += ["--encoding", str(encoding)] if bit_depth is not None: command += ["--bits", str(bit_depth)] if compression is not None: command += ["--compression", str(compression)] command += [dst_path] print(" ".join(command), file=sys.stderr) subprocess.run(command, check=True) def _flatten(effects): if not effects: return effects if isinstance(effects[0], str): return effects return [item for sublist in effects for item in sublist] def run_sox_effect(input_file, output_file, effect, *, output_sample_rate=None, output_bitdepth=None): """Run sox effects""" effect = _flatten(effect) command = ["sox", "-V", "--no-dither", input_file] if output_bitdepth: command += ["--bits", str(output_bitdepth)] command += [output_file] + effect if output_sample_rate: command += ["rate", str(output_sample_rate)] print(" ".join(command)) subprocess.run(command, check=True) ================================================ FILE: audio/tests/common_utils/wav_utils.py ================================================ from typing import Optional import paddle import scipy.io.wavfile def normalize_wav(tensor: paddle.Tensor) -> paddle.Tensor: if tensor.dtype == paddle.float32: pass elif tensor.dtype == paddle.int32: tensor = paddle.cast(tensor, paddle.float32) tensor[tensor > 0] /= 2147483647.0 tensor[tensor < 0] /= 2147483648.0 elif tensor.dtype == paddle.int16: tensor = paddle.cast(tensor, paddle.float32) tensor[tensor > 0] /= 32767.0 tensor[tensor < 0] /= 32768.0 elif tensor.dtype == paddle.uint8: tensor = paddle.cast(tensor, paddle.float32) - 128 tensor[tensor > 0] /= 127.0 tensor[tensor < 0] /= 128.0 return tensor def get_wav_data( dtype: str, num_channels: int, *, num_frames: Optional[int]=None, normalize: bool=True, channels_first: bool=True, ): """Generate linear signal of the given dtype and num_channels Data range is [-1.0, 1.0] for float32, [-2147483648, 2147483647] for int32 [-32768, 32767] for int16 [0, 255] for uint8 num_frames allow to change the linear interpolation parameter. Default values are 256 for uint8, else 1 << 16. 1 << 16 as default is so that int16 value range is completely covered. """ dtype_ = getattr(paddle, dtype) if num_frames is None: if dtype == "uint8": num_frames = 256 else: num_frames = 1 << 16 # paddle linspace not support uint8, int8, int16 #if dtype == "uint8": # base = paddle.linspace(0, 255, num_frames, dtype=dtype_) #dtype_np = getattr(np, dtype) #base_np = np.linspace(0, 255, num_frames, dtype_np) #base = paddle.to_tensor(base_np, dtype=dtype_) #elif dtype == "int8": # base = paddle.linspace(-128, 127, num_frames, dtype=dtype_) #dtype_np = getattr(np, dtype) #base_np = np.linspace(-128, 127, num_frames, dtype_np) #base = paddle.to_tensor(base_np, dtype=dtype_) if dtype == "float32": base = paddle.linspace(-1.0, 1.0, num_frames, dtype=dtype_) elif dtype == "float64": base = paddle.linspace(-1.0, 1.0, num_frames, dtype=dtype_) elif dtype == "int32": base = paddle.linspace( -2147483648, 2147483647, num_frames, dtype=dtype_) #elif dtype == "int16": # base = paddle.linspace(-32768, 32767, num_frames, dtype=dtype_) #dtype_np = getattr(np, dtype) #base_np = np.linspace(-32768, 32767, num_frames, dtype_np) #base = paddle.to_tensor(base_np, dtype=dtype_) else: raise NotImplementedError(f"Unsupported dtype {dtype}") data = base.tile([num_channels, 1]) if not channels_first: data = data.transpose([1, 0]) if normalize: data = normalize_wav(data) return data def load_wav(path: str, normalize=True, channels_first=True) -> paddle.Tensor: """Load wav file without paddleaudio""" sample_rate, data = scipy.io.wavfile.read(path) data = paddle.to_tensor(data.copy()) if data.ndim == 1: data = data.unsqueeze(1) if normalize: data = normalize_wav(data) if channels_first: data = data.transpose([1, 0]) return data, sample_rate def save_wav(path, data, sample_rate, channels_first=True): """Save wav file without paddleaudio""" if channels_first: data = data.transpose([1, 0]) scipy.io.wavfile.write(path, sample_rate, data.numpy()) ================================================ FILE: audio/tests/features/__init__.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. ================================================ FILE: audio/tests/features/base.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import os import unittest import urllib.request import numpy as np import paddle from paddleaudio.backends import soundfile_load as load wav_url = 'https://paddlespeech.cdn.bcebos.com/PaddleAudio/zh.wav' class FeatTest(unittest.TestCase): def setUp(self): self.initParams() self.initWavInput() self.setUpDevice() def setUpDevice(self, device='cpu'): paddle.set_device(device) def initWavInput(self, url=wav_url): if not os.path.isfile(os.path.basename(url)): urllib.request.urlretrieve(url, os.path.basename(url)) self.waveform, self.sr = load(os.path.abspath(os.path.basename(url))) self.waveform = self.waveform.astype( np.float32 ) # paddlespeech.audio.transform.spectrogram only supports float32 dim = len(self.waveform.shape) assert dim in [1, 2] if dim == 1: self.waveform = np.expand_dims(self.waveform, 0) def initParams(self): raise NotImplementedError ================================================ FILE: audio/tests/features/test_istft.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import numpy as np import paddle from paddleaudio.functional.window import get_window from .base import FeatTest from paddlespeech.audio.transform.spectrogram import IStft from paddlespeech.audio.transform.spectrogram import Stft class TestIstft(FeatTest): def initParams(self): self.n_fft = 512 self.hop_length = 128 self.window_str = 'hann' def test_istft(self): ps_stft = Stft(self.n_fft, self.hop_length) ps_res = ps_stft( self.waveform.T).squeeze(1).T # (n_fft//2 + 1, n_frmaes) x = paddle.to_tensor(ps_res) ps_istft = IStft(self.hop_length) ps_res = ps_istft(ps_res.T) window = get_window( self.window_str, self.n_fft, dtype=self.waveform.dtype) pd_res = paddle.signal.istft( x, self.n_fft, self.hop_length, window=window) np.testing.assert_array_almost_equal(ps_res, pd_res, decimal=5) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_kaldi.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import numpy as np import paddle import paddleaudio import torch import torchaudio from base import FeatTest class TestKaldi(FeatTest): def initParams(self): self.window_size = 1024 self.dtype = 'float32' def test_window(self): t_hann_window = torch.hann_window( self.window_size, periodic=False, dtype=eval(f'torch.{self.dtype}')) t_hamm_window = torch.hamming_window( self.window_size, periodic=False, alpha=0.54, beta=0.46, dtype=eval(f'torch.{self.dtype}')) t_povey_window = torch.hann_window( self.window_size, periodic=False, dtype=eval(f'torch.{self.dtype}')).pow(0.85) p_hann_window = paddleaudio.functional.window.get_window( 'hann', self.window_size, fftbins=False, dtype=eval(f'paddle.{self.dtype}')) p_hamm_window = paddleaudio.functional.window.get_window( 'hamming', self.window_size, fftbins=False, dtype=eval(f'paddle.{self.dtype}')) p_povey_window = paddleaudio.functional.window.get_window( 'hann', self.window_size, fftbins=False, dtype=eval(f'paddle.{self.dtype}')).pow(0.85) np.testing.assert_array_almost_equal(t_hann_window, p_hann_window) np.testing.assert_array_almost_equal(t_hamm_window, p_hamm_window) np.testing.assert_array_almost_equal(t_povey_window, p_povey_window) def test_fbank(self): ta_features = torchaudio.compliance.kaldi.fbank( torch.from_numpy(self.waveform.astype(self.dtype))) pa_features = paddleaudio.compliance.kaldi.fbank( paddle.to_tensor(self.waveform.astype(self.dtype))) np.testing.assert_array_almost_equal( ta_features, pa_features, decimal=4) def test_mfcc(self): ta_features = torchaudio.compliance.kaldi.mfcc( torch.from_numpy(self.waveform.astype(self.dtype))) pa_features = paddleaudio.compliance.kaldi.mfcc( paddle.to_tensor(self.waveform.astype(self.dtype))) np.testing.assert_array_almost_equal( ta_features, pa_features, decimal=4) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_kaldi_feat.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. #import platform import unittest import kaldiio import numpy as np from kaldiio import ReadHelper from paddleaudio.kaldi import fbank as fbank #from paddleaudio.kaldi import pitch as pitch # the groundtruth feats computed in kaldi command below. #compute-fbank-feats --dither=0 scp:$wav_scp ark,t:fbank_feat.ark #compute-kaldi-pitch-feats --sample-frequency=16000 scp:$wav_scp ark,t:pitch_feat.ark class TestKaldiFbank(unittest.TestCase): def test_fbank(self): fbank_groundtruth = {} with ReadHelper('ark:testdata/fbank_feat.ark') as reader: for key, feat in reader: fbank_groundtruth[key] = feat wav_rate, wav = kaldiio.wavio.read_wav('testdata/test.wav') fbank_feat = fbank(wav) fbank_check = fbank_groundtruth['test_wav'] np.testing.assert_array_almost_equal(fbank_feat, fbank_check, decimal=4) #def test_pitch(self): # pitch_groundtruth = {} # if platform.system() != "Linux": # pass # with ReadHelper('ark:testdata/pitch_feat.ark') as reader: # for key, feat in reader: # pitch_groundtruth[key] = feat # wav_rate, wav = kaldiio.wavio.read_wav('testdata/test.wav') # pitch_feat = pitch(wav) # pitch_check = pitch_groundtruth['test_wav'] # np.testing.assert_array_almost_equal(pitch_feat, pitch_check, decimal=4) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_librosa.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import librosa import numpy as np import paddle import paddleaudio from base import FeatTest from paddleaudio.functional.window import get_window class TestLibrosa(FeatTest): def initParams(self): self.n_fft = 512 self.hop_length = 128 self.n_mels = 40 self.n_mfcc = 20 self.fmin = 0.0 self.window_str = 'hann' self.pad_mode = 'reflect' self.top_db = 80.0 def test_stft(self): if len(self.waveform.shape) == 2: # (C, T) self.waveform = self.waveform.squeeze( 0) # 1D input for librosa.feature.melspectrogram feature_librosa = librosa.core.stft( y=self.waveform, n_fft=self.n_fft, hop_length=self.hop_length, win_length=None, window=self.window_str, center=True, dtype=None, pad_mode=self.pad_mode, ) x = paddle.to_tensor(self.waveform).unsqueeze(0) window = get_window(self.window_str, self.n_fft, dtype=x.dtype) feature_paddle = paddle.signal.stft( x=x, n_fft=self.n_fft, hop_length=self.hop_length, win_length=None, window=window, center=True, pad_mode=self.pad_mode, normalized=False, onesided=True, ).squeeze(0) np.testing.assert_array_almost_equal( feature_librosa, feature_paddle, decimal=5) def test_istft(self): if len(self.waveform.shape) == 2: # (C, T) self.waveform = self.waveform.squeeze( 0) # 1D input for librosa.feature.melspectrogram # Get stft result from librosa. stft_matrix = librosa.core.stft( y=self.waveform, n_fft=self.n_fft, hop_length=self.hop_length, win_length=None, window=self.window_str, center=True, pad_mode=self.pad_mode, ) feature_librosa = librosa.core.istft( stft_matrix=stft_matrix, hop_length=self.hop_length, win_length=None, window=self.window_str, center=True, dtype=None, length=None, ) x = paddle.to_tensor(stft_matrix).unsqueeze(0) window = get_window( self.window_str, self.n_fft, dtype=paddle.to_tensor(self.waveform).dtype) feature_paddle = paddle.signal.istft( x=x, n_fft=self.n_fft, hop_length=self.hop_length, win_length=None, window=window, center=True, normalized=False, onesided=True, length=None, return_complex=False, ).squeeze(0) np.testing.assert_array_almost_equal( feature_librosa, feature_paddle, decimal=5) def test_mel(self): feature_librosa = librosa.filters.mel( sr=self.sr, n_fft=self.n_fft, n_mels=self.n_mels, fmin=self.fmin, fmax=None, htk=False, norm='slaney', dtype=self.waveform.dtype, ) feature_compliance = paddleaudio.compliance.librosa.compute_fbank_matrix( sr=self.sr, n_fft=self.n_fft, n_mels=self.n_mels, fmin=self.fmin, fmax=None, htk=False, norm='slaney', dtype=self.waveform.dtype, ) x = paddle.to_tensor(self.waveform) feature_functional = paddleaudio.functional.compute_fbank_matrix( sr=self.sr, n_fft=self.n_fft, n_mels=self.n_mels, f_min=self.fmin, f_max=None, htk=False, norm='slaney', dtype=x.dtype, ) np.testing.assert_array_almost_equal(feature_librosa, feature_compliance) np.testing.assert_array_almost_equal(feature_librosa, feature_functional) def test_melspect(self): if len(self.waveform.shape) == 2: # (C, T) self.waveform = self.waveform.squeeze( 0) # 1D input for librosa.feature.melspectrogram # librosa: feature_librosa = librosa.feature.melspectrogram( y=self.waveform, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin) # paddleaudio.compliance.librosa: feature_compliance = paddleaudio.compliance.librosa.melspectrogram( x=self.waveform, sr=self.sr, window_size=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin, to_db=False) # paddleaudio.features.layer x = paddle.to_tensor( self.waveform, dtype=paddle.float64).unsqueeze(0) # Add batch dim. feature_extractor = paddle.audio.features.MelSpectrogram( sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, f_min=self.fmin, dtype=x.dtype) feature_layer = feature_extractor(x).squeeze(0).numpy() np.testing.assert_array_almost_equal( feature_librosa, feature_compliance, decimal=5) np.testing.assert_array_almost_equal( feature_librosa, feature_layer, decimal=5) def test_log_melspect(self): if len(self.waveform.shape) == 2: # (C, T) self.waveform = self.waveform.squeeze( 0) # 1D input for librosa.feature.melspectrogram # librosa: feature_librosa = librosa.feature.melspectrogram( y=self.waveform, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin) feature_librosa = librosa.power_to_db(feature_librosa, top_db=None) # paddleaudio.compliance.librosa: feature_compliance = paddleaudio.compliance.librosa.melspectrogram( x=self.waveform, sr=self.sr, window_size=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin) # paddleaudio.features.layer x = paddle.to_tensor( self.waveform, dtype=paddle.float64).unsqueeze(0) # Add batch dim. feature_extractor = paddle.audio.features.LogMelSpectrogram( sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, f_min=self.fmin, dtype=x.dtype) feature_layer = feature_extractor(x).squeeze(0).numpy() np.testing.assert_array_almost_equal( feature_librosa, feature_compliance, decimal=5) np.testing.assert_array_almost_equal( feature_librosa, feature_layer, decimal=4) def test_mfcc(self): if len(self.waveform.shape) == 2: # (C, T) self.waveform = self.waveform.squeeze( 0) # 1D input for librosa.feature.melspectrogram # librosa: feature_librosa = librosa.feature.mfcc( y=self.waveform, sr=self.sr, S=None, n_mfcc=self.n_mfcc, dct_type=2, norm='ortho', lifter=0, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin) # paddleaudio.compliance.librosa: feature_compliance = paddleaudio.compliance.librosa.mfcc( x=self.waveform, sr=self.sr, n_mfcc=self.n_mfcc, dct_type=2, norm='ortho', lifter=0, window_size=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, fmin=self.fmin, top_db=self.top_db) # paddle.audio.features.layer x = paddle.to_tensor( self.waveform, dtype=paddle.float64).unsqueeze(0) # Add batch dim. feature_extractor = paddle.audio.features.MFCC( sr=self.sr, n_mfcc=self.n_mfcc, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels, f_min=self.fmin, top_db=self.top_db, dtype=x.dtype) feature_layer = feature_extractor(x).squeeze(0).numpy() np.testing.assert_array_almost_equal( feature_librosa, feature_compliance, decimal=4) np.testing.assert_array_almost_equal( feature_librosa, feature_layer, decimal=4) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_log_melspectrogram.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import numpy as np import paddle import paddleaudio from .base import FeatTest from paddlespeech.audio.transform.spectrogram import LogMelSpectrogram class TestLogMelSpectrogram(FeatTest): def initParams(self): self.n_fft = 512 self.hop_length = 128 self.n_mels = 40 def test_log_melspect(self): ps_melspect = LogMelSpectrogram(self.sr, self.n_mels, self.n_fft, self.hop_length) ps_res = ps_melspect(self.waveform.T).squeeze(1).T x = paddle.to_tensor(self.waveform) ps_melspect = paddleaudio.features.LogMelSpectrogram( self.sr, self.n_fft, self.hop_length, power=1.0, n_mels=self.n_mels, f_min=0.0) pa_res = (ps_melspect(x) / 10.0).squeeze(0).numpy() np.testing.assert_array_almost_equal(ps_res, pa_res, decimal=5) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_spectrogram.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import numpy as np import paddle import paddleaudio from .base import FeatTest from paddlespeech.audio.transform.spectrogram import Spectrogram class TestSpectrogram(FeatTest): def initParams(self): self.n_fft = 512 self.hop_length = 128 def test_spectrogram(self): ps_spect = Spectrogram(self.n_fft, self.hop_length) ps_res = ps_spect(self.waveform.T).squeeze(1).T # Magnitude x = paddle.to_tensor(self.waveform) pa_spect = paddle.audio.features.Spectrogram( self.n_fft, self.hop_length, power=1.0) pa_res = pa_spect(x).squeeze(0).numpy() np.testing.assert_array_almost_equal(ps_res, pa_res, decimal=5) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/test_stft.py ================================================ # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. # # 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. import unittest import numpy as np import paddle from paddleaudio.functional.window import get_window from .base import FeatTest from paddlespeech.audio.transform.spectrogram import Stft class TestStft(FeatTest): def initParams(self): self.n_fft = 512 self.hop_length = 128 self.window_str = 'hann' def test_stft(self): ps_stft = Stft(self.n_fft, self.hop_length) ps_res = ps_stft( self.waveform.T).squeeze(1).T # (n_fft//2 + 1, n_frames) x = paddle.to_tensor(self.waveform) window = get_window(self.window_str, self.n_fft, dtype=x.dtype) pd_res = paddle.signal.stft( x, self.n_fft, self.hop_length, window=window).squeeze(0).numpy() np.testing.assert_array_almost_equal(ps_res, pd_res, decimal=5) if __name__ == '__main__': unittest.main() ================================================ FILE: audio/tests/features/testdata/fbank_feat_txt.ark ================================================ test_wav [ 8.86961 7.025289 6.664165 7.169617 7.317829 7.188704 8.351522 8.843228 7.711394 7.231504 6.903938 7.053499 7.293597 8.331067 7.871729 9.206844 9.434045 9.768963 10.01864 10.25888 10.68228 10.55968 10.62156 8.364346 7.526375 6.915925 6.705005 7.641569 7.827819 8.253532 7.794802 7.522578 7.222802 7.388284 7.493527 8.257078 9.141049 8.994849 9.348937 9.015431 9.343955 10.42236 10.13459 10.40709 10.39534 10.22199 7.230361 6.771988 6.422344 7.535786 7.164408 6.342811 8.723886 8.481328 6.804535 7.276428 7.471786 7.581892 8.757826 8.764767 8.570841 8.741215 9.756334 9.515329 9.720121 10.26671 10.67728 10.5581 10.61378 8.872903 7.371414 6.360067 6.153208 7.333708 8.0974 8.851793 8.730195 7.622618 7.169075 7.85181 7.04872 7.978426 8.408302 8.802312 8.395834 9.217923 8.381662 9.777567 10.40261 10.37856 10.31888 10.34441 7.532231 6.751142 8.175496 7.593341 8.063697 8.369373 7.881088 8.15251 7.428252 7.103447 7.989072 7.949497 8.124873 8.496659 8.553727 8.761693 9.109408 9.4684 10.13223 10.16827 9.71019 10.59482 10.90851 6.746207 6.833902 8.067636 7.6485 7.013279 7.693223 8.147296 8.030097 7.067122 8.186153 7.784977 8.756321 8.6457 8.458344 7.769485 8.669812 9.332602 9.097817 9.444702 9.950351 10.18657 10.94016 11.36237 7.128079 7.711221 6.469111 6.649592 6.508276 7.082622 7.440871 7.623552 7.594537 7.354738 8.278585 8.652099 8.709033 8.605441 8.353497 8.4307 9.50789 9.312969 9.785786 10.18853 10.35708 10.71134 11.13716 8.201805 8.373339 7.420624 6.559644 6.318965 6.861043 7.299667 7.459548 7.392651 7.774329 7.917755 8.39668 8.304465 7.503887 8.319722 9.310571 9.144365 9.811728 9.738833 9.825593 10.65616 10.42954 10.28108 8.140867 8.803907 7.842072 6.760153 6.040633 7.099484 7.671337 7.230731 7.280159 7.825505 8.67013 7.970374 7.691161 7.603088 8.121623 8.186304 8.884687 9.764359 9.774008 10.14217 10.57618 10.70955 10.46593 9.335081 7.443659 6.302314 6.274453 6.648484 7.101899 8.31965 7.279731 7.011406 7.738722 8.111496 7.826912 9.217668 8.704701 8.520703 9.237556 9.141415 9.966189 10.13588 10.02818 10.32232 10.5961 10.39195 8.623323 6.642638 6.092153 6.010561 6.961139 7.523609 7.631736 6.81785 6.3952 7.437364 7.784822 8.421501 8.569756 8.931039 8.394889 8.730085 8.568606 9.672934 10.10908 10.22258 10.30489 10.11329 10.44942 8.340079 7.404711 6.73463 6.621991 6.641872 6.501914 7.429152 7.325783 7.075316 7.198759 7.573832 7.726879 8.173958 8.713857 8.947656 9.52945 9.495684 10.04432 9.70799 9.853218 10.34904 10.31011 10.33581 9.458065 6.449831 5.764122 6.112749 6.633307 6.588135 7.683532 7.854395 7.497962 6.587214 7.522266 8.246718 7.842532 8.194103 8.769976 9.494311 9.410578 9.623136 9.262513 9.66307 9.958323 10.58842 10.94138 9.336168 7.658177 6.552251 4.668932 5.951582 7.329723 6.881893 7.673193 8.018956 7.765876 8.092113 7.657069 8.385877 8.804426 8.99403 9.033966 9.84664 9.652982 9.678547 9.901299 10.55994 10.98264 10.42628 8.845008 7.827737 6.934293 6.809871 7.603892 7.622493 7.295815 7.316114 7.707997 8.28838 7.455571 7.749361 8.357333 8.413839 8.780228 9.111949 8.773423 9.546294 9.316511 9.7621 9.853085 10.24652 10.58686 9.845795 7.653487 6.760835 6.417203 6.483883 8.249362 8.985138 7.782502 8.038197 7.994664 7.512061 7.712332 8.276911 8.76414 8.027122 8.730929 8.986988 9.50342 9.225771 9.793655 10.35338 10.19652 10.67655 8.068243 7.419188 7.323668 6.883723 7.588089 7.267737 7.464292 8.121238 7.117096 7.165044 7.638491 7.958453 8.368897 8.497821 8.06803 8.636445 9.186031 9.296571 9.991373 10.35782 10.44223 10.60756 10.9512 8.540399 7.109134 6.417945 6.851756 7.50145 7.613665 7.395747 8.489678 7.192803 8.40198 8.48846 7.516579 8.291675 9.133558 8.94935 9.040503 9.475376 9.886353 10.04679 10.23742 10.22118 10.67988 10.29023 9.943547 6.745187 7.141617 7.058182 7.203416 8.045156 7.670315 7.748672 7.009519 7.208478 7.261959 8.346151 8.425858 8.822375 8.973361 9.907825 9.710265 9.542497 9.383007 9.832958 10.30413 10.9831 10.99566 9.077311 7.305787 7.036552 6.220779 6.492191 6.642952 8.301676 8.177285 7.706949 7.897906 7.814847 7.765959 8.228884 8.499186 8.701291 8.90225 9.000106 9.510703 9.477421 9.869934 10.31142 10.33504 10.62863 9.609183 6.470312 6.850113 7.247727 6.606174 7.178535 7.569305 7.858948 7.907071 7.322339 7.393857 8.411836 8.555615 8.416198 8.268435 8.814535 9.016805 9.221167 8.856338 9.819329 10.63624 10.67038 10.4818 8.896682 6.96038 7.062835 6.841669 6.556721 7.257597 9.19041 8.196911 7.560658 7.475944 7.570982 8.699837 8.718691 8.698103 9.604801 9.410757 9.482757 9.489608 10.0253 10.21278 10.42956 10.25078 10.40438 10.05012 7.997848 8.523865 7.810099 7.064989 7.438704 8.866325 8.385101 8.702444 7.532755 6.970853 8.658536 8.904259 8.098039 8.240754 9.383977 9.924636 9.825594 10.16586 9.929379 10.33848 10.6166 10.88825 9.945673 7.943526 8.236642 7.982066 7.059935 7.337771 8.282602 7.669298 6.812744 7.241785 7.059946 8.290605 8.874635 8.206081 9.037805 9.692253 9.771944 9.658941 9.887684 9.687504 10.12401 10.5467 10.46784 9.24334 8.005972 8.029324 7.080775 6.692482 7.339699 6.330315 7.749064 7.191765 7.614157 7.584374 8.707373 8.633794 7.661246 8.89745 8.717183 8.727042 9.601094 9.761832 9.91165 10.89605 10.7561 10.4439 9.008655 7.696863 8.051159 6.21505 6.986367 7.75211 7.125566 8.008561 8.631255 7.692895 7.423654 8.070612 7.934104 7.481667 7.878049 8.699003 9.587379 9.81943 9.638152 10.14519 10.48706 10.67093 10.95845 9.56725 7.086317 7.604103 6.621353 6.861667 6.762026 7.150949 8.061196 7.548547 6.552682 7.445788 8.408651 8.276496 7.768121 8.235985 9.36837 9.303123 9.568222 9.907539 10.04948 10.3193 10.38864 11.01985 9.435867 7.065077 8.260999 7.606821 7.11696 6.622849 7.453804 7.729028 6.969114 7.593372 8.076168 8.142076 7.987474 7.750668 8.709545 9.194512 9.28443 9.696207 10.08809 10.43397 10.95729 10.62421 10.32698 7.326074 6.968657 7.991836 8.057238 8.277269 6.64677 8.417533 8.390658 7.716748 7.254366 8.046806 8.952176 8.943592 8.626341 8.475414 8.366508 9.379741 9.649915 9.956218 10.14107 10.0686 10.3009 10.63128 8.867029 7.436584 8.325071 8.151552 7.802304 7.204567 7.817641 8.41904 8.079826 7.800119 7.738661 8.019406 8.496906 8.371117 8.895446 8.874495 9.541505 9.603241 9.702045 9.520963 10.07405 10.22188 10.69203 7.892157 7.706676 8.708323 8.090714 7.298046 7.119635 7.677824 8.568966 9.065309 7.950867 7.361037 8.006032 7.704475 8.136228 9.241001 9.342211 9.766371 9.645364 10.53355 10.35027 10.26263 10.8308 10.88063 9.17825 6.552885 7.865911 7.314655 7.429624 7.467305 7.331274 8.097523 8.513691 7.603092 8.123087 8.988563 8.24368 7.665757 8.043156 9.323641 9.559673 10.4114 10.44213 10.46176 10.31303 10.41219 10.04096 9.499084 6.913695 8.680465 8.913202 7.983476 7.54614 8.20214 8.433187 7.619872 7.079637 7.59503 7.827682 8.021211 8.954014 8.512682 8.685501 9.039448 9.882102 10.09629 9.995301 10.25326 10.52707 10.41024 8.841949 7.852749 8.220187 8.067208 6.958006 6.525739 7.606658 8.743006 8.618779 7.857424 7.85938 6.839745 8.494206 7.93556 8.554915 9.17892 9.411014 9.403722 9.75618 9.915223 10.4127 10.62058 10.75261 8.80931 7.176473 8.226482 8.048065 6.875594 7.035853 8.159007 8.788584 7.998541 7.745961 7.02769 7.343524 8.768233 8.742394 8.993815 8.919962 8.948602 9.299537 9.644719 9.328181 10.0551 10.60812 10.26714 8.416738 7.433433 8.202932 7.654713 7.487177 7.454067 7.807778 8.21654 7.973643 7.745943 7.477229 7.699207 8.724244 8.921854 9.167027 9.329788 9.198338 9.449234 9.350556 9.504007 10.01113 10.77754 10.79311 7.265522 8.85788 8.794858 6.660202 5.630237 7.668158 8.690257 8.2572 7.200497 7.342714 7.748627 8.173976 8.632828 8.53996 9.053345 9.001765 9.227647 10.09744 9.63631 10.25264 9.908823 11.11253 11.10346 8.641815 8.838676 8.314915 6.847168 5.620167 7.186635 8.486069 8.301935 7.863872 7.790708 7.733249 8.113005 8.49118 7.827488 8.389672 8.932463 9.147495 10.10519 10.22344 10.33928 10.09212 10.47646 10.13575 7.634632 6.384978 8.24638 7.503924 6.99588 7.640463 7.480204 7.821477 7.610888 7.87086 8.010333 7.981211 7.871301 8.551961 8.90114 9.304276 8.653571 9.205483 9.727321 10.48769 10.20595 10.13756 10.41514 8.518332 7.862745 8.034936 8.2016 6.675735 7.573159 8.171587 8.14386 7.991887 6.929758 7.718138 7.759238 8.233613 7.833398 9.010793 8.673923 9.241878 10.12235 10.55527 10.50808 10.58219 10.75335 10.4664 8.728762 7.574676 6.733976 7.824086 8.000705 7.302856 7.860464 8.410678 7.924881 6.743472 7.201906 7.431501 7.915576 8.187505 8.869449 8.608752 9.654437 10.20065 9.895975 10.05015 10.0937 11.01951 10.82668 7.629794 6.486794 6.295053 7.050656 7.523815 7.511558 8.234637 8.500476 8.005258 7.928689 8.219633 8.856939 8.562517 8.864034 9.246393 9.440809 9.380711 10.00752 9.569251 9.957119 10.54277 10.3938 10.80297 9.755882 6.397912 7.59745 7.644662 7.147341 7.108955 8.413054 8.151018 7.909472 7.656272 9.413692 11.06461 10.69808 10.64652 11.38675 11.21603 11.1705 10.6691 9.91959 10.95611 11.29983 11.17031 10.97226 9.474765 7.803607 8.385871 6.384162 7.948147 7.78756 8.428943 8.824086 8.393611 8.634716 8.208453 8.799019 9.028046 9.011028 9.807654 10.60488 10.43945 10.06425 10.27431 9.998198 11.03344 10.98869 10.06162 8.450254 7.49551 6.799858 6.310681 7.20258 8.050933 8.205685 8.776224 7.973586 7.784925 7.730099 8.780946 9.105856 8.773993 8.182259 8.562423 9.90097 9.80205 10.24598 10.17385 10.20839 10.46425 10.26094 8.252859 7.287729 7.475165 7.372538 6.989303 7.400277 6.899447 8.107825 7.968466 7.659332 8.521437 9.400009 9.208941 8.744918 8.120193 8.727738 9.995106 9.742892 9.950342 9.993467 10.03006 10.28127 10.45164 8.592541 7.811454 7.721195 6.033926 7.451138 7.954978 7.936564 8.032441 8.207817 7.761642 7.824575 8.806037 8.584102 9.029242 9.405202 9.570443 10.0666 9.799012 10.14801 10.00847 10.26264 10.47974 10.30221 8.263712 7.622368 7.388706 6.853238 7.028842 8.005108 7.877354 8.477866 8.796792 8.305426 8.403102 8.24081 8.906131 8.901518 9.546893 9.517485 9.934557 9.7798 10.04766 9.671112 10.1303 10.74265 10.63667 9.357657 8.026215 7.907611 7.254067 6.912889 7.510985 8.215575 8.492505 8.151805 7.310562 8.163457 8.056206 8.009975 8.118791 8.972518 9.303927 9.412671 9.438314 9.8068 9.750667 10.35458 10.35285 10.09931 8.511848 7.523149 8.195268 7.966453 7.744322 8.485562 8.004887 7.922952 8.245237 7.383193 7.844249 8.127041 8.127259 8.443523 8.102531 8.774108 8.681726 9.477551 8.882012 9.804171 10.55685 10.48077 10.37192 7.975676 7.082146 7.933741 6.951503 6.272567 7.088233 7.917744 7.379583 8.238628 7.820266 8.475443 8.424726 8.05715 8.067741 8.94787 8.867351 9.374059 9.266661 9.49703 10.01138 10.3168 10.71612 10.27346 8.813721 8.656951 7.681757 7.203363 7.488046 8.216457 8.221495 7.714307 7.938663 7.708951 8.019526 7.926672 7.864351 7.698409 8.801851 8.555806 9.788485 9.553381 9.62245 10.2158 9.915847 10.40117 10.80687 6.477304 7.734454 8.373713 6.965827 8.077723 8.442548 7.893295 8.407219 7.909376 8.080144 8.55372 7.803288 6.868239 8.449481 8.860373 8.910608 9.437862 9.165442 9.82246 10.30201 10.48472 10.77984 11.18594 9.42877 10.45913 10.29159 9.716755 9.220295 8.658374 6.794528 6.873018 7.217855 8.288869 8.809176 8.809996 8.093638 8.87556 9.207784 9.647738 9.825712 10.08347 9.918015 10.10553 10.54475 11.02415 10.92163 13.23045 15.72255 15.14105 16.25381 15.65043 12.23466 10.81911 10.62931 10.80597 11.77175 12.40585 12.68368 13.26326 11.76209 10.96095 14.30546 15.08591 12.37251 12.23275 11.97119 10.67747 10.71765 10.87486 13.65519 16.94076 16.0239 18.20588 16.9831 13.7648 12.16126 11.07043 11.80799 12.73412 12.98298 12.90398 14.25156 11.9087 10.24638 14.79149 15.7653 13.01829 12.92099 13.79269 11.3934 11.02932 11.13173 13.2973 17.06046 16.08663 18.53358 17.69795 13.95008 12.40663 11.98961 12.74475 13.79677 14.19347 14.3372 14.89816 13.25463 12.57261 16.00417 16.9676 13.95466 13.9528 14.54457 12.07387 11.57656 11.49943 11.75321 16.53652 16.49979 19.33843 18.63615 13.93179 11.64835 11.64008 12.97903 13.87796 14.90638 15.14878 15.24947 14.3757 13.73179 15.41584 15.93701 14.80291 14.12144 14.58253 12.19397 12.21274 12.09839 12.51654 17.17333 16.62761 20.22687 19.77942 13.27525 11.65 12.57212 13.83558 14.21572 15.06257 15.13174 14.75701 15.54657 14.15343 15.183 16.24345 14.94379 14.57995 14.90003 12.3515 12.90885 12.08299 12.59919 17.27024 16.59142 20.83065 20.46106 14.01313 12.53942 13.63936 14.82475 14.79233 15.39594 15.28064 15.61105 15.19362 13.62629 15.96059 17.22206 15.25036 15.57805 15.82821 13.8464 14.34314 12.32957 12.87339 17.40207 16.69853 20.75185 20.27472 14.82241 13.57454 13.89783 14.86771 15.49655 15.69082 15.79947 15.61258 16.25987 14.84013 16.51847 18.01414 15.01476 15.3407 16.01681 14.13993 14.62834 12.70863 13.17359 17.59177 16.96258 19.95944 18.9106 15.22701 13.8382 13.31798 14.14737 14.76138 15.86723 16.08653 15.98195 16.09414 14.82789 16.4943 17.65386 15.15134 15.58843 16.19427 14.51803 15.25478 14.10639 13.61701 17.7865 17.24287 20.31397 19.26783 15.3012 14.27533 14.00652 14.06157 13.97732 15.41972 16.40127 16.03523 14.89164 14.54936 15.81458 16.71577 14.59401 15.69445 17.08231 15.19946 15.35905 13.67907 14.00184 17.83053 17.10755 20.32385 19.31859 16.05173 14.2608 13.70262 13.87365 13.57939 14.82414 15.85239 16.70191 15.73202 13.95968 14.90556 15.42773 15.31231 15.90333 16.87693 15.50014 15.44649 13.9608 14.57378 17.84243 16.76657 19.45782 18.36666 15.36792 13.44019 13.72313 14.92875 14.36976 14.25026 15.64569 15.89312 14.45428 13.3161 14.53451 15.62068 14.59393 15.80624 17.03548 14.96751 15.02374 13.4909 15.21447 18.18304 16.96745 19.16579 18.69295 14.50879 13.17371 13.65467 15.22889 14.17074 13.75207 14.95903 15.48484 14.01785 11.96252 13.67882 15.37274 14.30946 15.06645 16.43822 14.03593 14.029 12.96432 15.69557 18.73573 17.84295 20.32482 19.18899 14.03427 12.50394 12.18307 15.27329 13.74666 13.09154 14.42644 14.96374 13.87214 11.83368 12.93985 14.45116 14.00281 15.06362 16.09592 13.61044 13.31885 12.74485 15.98183 18.61076 17.23318 18.58419 17.75739 14.66514 11.80884 13.04507 15.05399 13.23005 12.31126 13.64777 13.9603 12.94314 11.54242 12.23427 13.46654 13.42021 14.35025 15.38576 13.45529 13.28467 13.43179 16.36983 18.49153 17.46072 19.55406 17.8304 14.26844 11.65388 12.54786 13.89278 12.02204 11.70842 12.86929 13.92763 13.19448 11.47678 11.02568 13.00155 13.05625 13.99241 14.93269 13.36193 12.62123 11.25201 16.91053 19.31395 17.91098 18.89643 16.86432 13.72694 11.87185 13.24254 14.00205 12.05257 10.76908 12.87949 13.28356 11.94633 11.05437 11.12533 12.75738 12.05501 13.33129 14.07069 12.3796 11.7192 11.05169 17.29174 19.6846 17.73157 17.35478 16.16297 14.15115 11.11073 12.40668 13.28362 11.18836 11.07174 12.54022 13.02938 11.88706 10.44743 11.13548 12.77041 12.04656 12.83903 12.8876 11.77514 11.40439 10.56045 17.23432 19.42053 17.20756 16.95235 16.25754 13.89139 11.49117 11.78105 11.14721 10.20588 10.31909 12.48863 12.60464 11.83299 12.36004 11.31453 12.29337 12.36164 12.43958 12.93882 11.9782 12.27852 11.67843 16.53074 18.71063 16.51751 16.94945 16.05041 12.74791 10.03071 10.72647 10.99932 9.982744 10.96635 12.68731 12.83623 11.30921 11.54913 10.90253 11.23106 11.50233 12.71762 13.18253 11.76622 12.38223 11.70104 15.69217 17.89815 15.7483 14.97377 14.53612 11.96516 11.12983 9.131196 10.96767 10.9673 12.05442 12.21859 12.5895 10.55106 10.79283 10.54876 11.01498 10.7606 11.54235 11.51353 10.85205 11.89782 11.11372 13.86923 16.57632 15.26331 14.85788 14.39067 12.7171 11.17243 11.00468 11.68423 13.25407 12.60769 12.59903 12.12048 12.90249 13.94144 13.63238 13.21792 12.05534 12.87838 14.90839 15.73015 16.02667 15.69104 13.61382 16.34682 14.90382 14.8893 14.40084 13.49422 12.6097 13.05071 13.73629 15.75304 15.30508 13.85447 13.98672 15.82224 16.32998 16.46949 16.51073 13.91432 14.74784 17.0687 18.13454 18.42613 18.47258 14.55605 16.97081 15.03501 15.3369 14.16967 11.95557 10.91977 11.08843 11.75058 13.24282 12.85878 12.96099 13.28478 15.59657 14.72278 15.30267 15.28392 13.16171 14.36229 17.22016 18.41889 19.45104 19.20117 15.47327 17.72926 15.78447 15.42446 15.40768 12.5729 10.11994 10.89366 12.10496 13.59284 13.03747 13.40623 12.94038 16.30528 16.32386 14.95233 14.70298 13.22234 14.0664 16.60508 17.89858 18.17508 18.00281 16.2211 18.26995 17.28866 17.57735 15.27353 13.3695 11.53266 11.68451 11.35421 11.92297 12.33619 13.06362 12.45224 15.49412 16.06547 15.92675 15.58576 12.58488 13.5124 15.40464 16.18043 15.33247 15.62229 16.40175 18.42591 17.84651 18.44906 15.41768 13.78307 12.2946 12.64999 11.22093 11.41927 11.63084 10.93246 11.98123 14.54343 16.20716 16.31189 15.47426 12.76656 13.13507 15.26896 15.09722 14.0725 14.46431 16.6757 18.54147 17.61383 18.17967 15.46035 13.83175 11.8658 12.33601 11.13389 11.20397 11.12461 11.22868 12.22488 13.94469 15.89769 16.34622 15.46319 12.74337 14.20451 15.74678 15.10971 14.52905 14.4963 16.76283 18.5887 17.68788 18.20937 15.80549 13.99685 12.14814 12.54838 10.8432 11.06379 11.41749 11.17507 11.48255 12.85203 14.78319 16.05849 16.08326 13.06919 13.94136 15.39909 14.80749 14.61425 14.66702 16.64995 18.30085 17.58634 18.3342 16.15151 14.58886 11.89366 12.30556 11.47828 11.79887 11.09667 11.30176 11.16868 14.35984 14.87677 16.13587 16.49911 13.06481 14.12372 15.51614 15.46192 15.01677 14.90916 16.52672 18.18384 17.63734 18.262 16.74109 15.33377 12.32343 12.43404 12.25445 12.18885 12.2143 11.90199 11.90509 14.61265 15.28587 16.9969 17.03483 13.91487 14.51653 15.79068 15.46326 15.15117 14.32447 16.60033 18.01448 17.0511 17.71783 17.75788 16.23282 12.81127 12.78385 12.44913 12.3739 12.64835 12.44617 11.88231 14.26506 14.75798 16.41036 16.44767 13.79646 14.08188 15.74754 15.21961 14.5229 14.27368 16.58554 18.17001 15.6192 15.79108 17.83907 16.49691 13.58467 13.87136 13.15251 15.34053 15.64338 14.75528 12.38052 13.428 14.05307 15.71102 16.18547 13.51842 13.2032 15.82146 15.4119 15.28212 14.9756 16.81706 18.37561 15.55623 15.33322 17.88172 16.29072 14.11057 14.21804 13.08518 13.69146 14.14797 14.73615 13.03893 13.11906 14.03352 14.95837 16.48228 13.51765 14.07395 15.32152 14.80149 14.38036 14.81253 16.95721 18.65568 15.88247 14.83851 17.85907 16.19847 14.35859 14.35917 13.97949 13.80073 14.48404 15.46158 12.86709 12.57524 13.31753 13.57888 14.20235 13.62078 13.80603 14.58132 14.26628 15.57101 15.81091 16.92929 18.59748 16.18815 16.21428 17.81978 16.08954 14.27445 14.10925 13.96899 14.1386 14.35728 14.62649 12.22072 11.41585 11.79407 12.69996 13.94304 14.1476 14.00437 14.08617 14.21517 16.62167 16.08522 16.71347 18.34732 16.52386 16.70664 17.32837 15.66043 14.25163 14.13859 14.01087 14.8577 14.49389 14.02374 12.22193 12.02307 12.09513 12.59532 14.0639 13.72341 13.91703 14.04354 14.41245 16.46469 16.29546 16.4208 18.01264 16.88099 17.1442 16.57642 14.64041 13.85327 13.94551 14.64954 14.75776 14.21291 14.0806 12.50921 12.25238 11.75339 12.30866 14.22572 14.74261 14.3222 14.56139 14.66986 16.32808 16.07767 16.02585 17.41488 16.75061 17.14062 15.60216 13.43982 13.3218 13.5059 15.12315 15.74747 15.12732 14.97423 11.94713 11.64201 11.86428 12.81159 14.43116 14.51448 14.0855 13.91175 13.53605 16.79836 16.27676 15.54676 16.81251 16.59787 16.86721 13.93739 12.5265 13.02697 13.58001 14.63541 15.0335 15.03953 14.87171 11.96232 11.17344 11.23595 12.35256 13.94297 14.62026 14.15592 14.0969 13.14401 15.85678 16.06257 15.29335 16.5896 16.2428 16.40902 13.19328 11.96381 13.15584 13.4573 13.83275 14.18077 14.74952 13.4333 11.54537 11.45848 11.20981 11.44254 13.91985 14.09482 13.83819 13.72444 12.47239 15.62782 15.47463 15.03695 16.41206 15.76506 15.74993 14.99031 12.53887 14.11596 13.88085 13.56149 13.86856 14.16082 13.18733 10.81969 11.83342 11.28586 11.12295 13.29487 13.72911 13.43846 13.1814 11.87428 13.31521 14.49123 15.19216 16.60078 14.61114 14.46758 15.01078 13.24106 14.01335 13.57776 12.27156 13.13906 14.44345 13.87597 11.4695 11.93211 11.51881 11.86933 13.54847 13.27814 13.21632 13.90559 14.1398 14.70719 14.13614 14.67921 16.36944 14.31438 14.29885 14.20024 12.58013 12.82334 12.93028 12.20578 13.60437 14.77291 14.12951 12.00097 12.08059 12.8358 12.58611 13.60779 13.56823 13.54014 15.80377 16.93598 17.07594 16.38759 14.09909 15.53763 14.35333 14.36311 13.46532 12.24172 11.28518 11.79358 12.87418 12.31148 14.00558 14.61462 12.33662 12.94618 13.78474 13.02037 13.37858 14.04721 15.38267 18.08268 19.1378 18.01291 17.87174 13.13866 14.28506 13.46247 13.33514 12.55707 11.26553 10.44495 10.7674 12.86463 12.67321 13.31184 12.77522 11.95182 13.00975 13.90651 13.2495 14.2042 14.69992 15.82987 18.51886 19.10749 19.2898 19.35597 12.87447 13.63893 12.77628 12.87282 11.82412 10.49559 11.2738 11.53943 12.46402 13.76956 13.33128 13.70105 13.19503 13.69975 14.5716 14.70375 14.28935 14.60292 15.83705 18.41346 19.52948 19.5496 19.50181 12.43892 14.00917 11.94452 12.23295 13.09062 11.04633 10.81847 11.03293 12.85549 13.9011 14.34009 14.35291 13.72982 13.88251 14.83228 14.69408 14.73889 15.0092 16.64098 19.92425 20.72796 20.62129 20.78949 12.57589 14.14755 12.76697 12.63588 12.86826 10.93601 10.81407 11.39892 13.70268 15.24565 15.25113 15.90769 15.04436 13.95307 14.30912 15.37132 15.7328 15.43253 17.88644 20.36236 20.81531 21.52759 20.81256 11.55697 13.42533 11.86985 12.06834 12.89067 12.34525 12.49656 12.66325 13.77704 15.66433 16.10908 16.22246 15.24011 14.59829 15.35136 15.66786 15.75713 15.76261 17.19726 20.20177 20.41369 21.18811 20.27664 11.83781 11.78476 10.88169 12.16515 12.8652 12.27359 12.28256 13.37679 14.12796 16.37236 16.86594 16.74899 13.97586 14.41109 15.27517 15.25704 16.5749 15.36801 16.12666 18.94821 19.08416 20.14678 19.19424 11.29138 12.42908 11.55172 11.38864 12.08098 11.84389 12.93314 13.31962 14.90897 16.77657 16.34854 15.3447 13.96065 14.13565 14.2487 14.35624 16.70179 14.96482 14.82867 17.15551 17.93615 17.96055 17.92477 11.65481 13.19278 11.53873 12.37848 11.75132 12.30172 13.64941 13.70718 15.32799 15.79656 16.56388 15.52489 14.06691 13.22153 13.50002 13.39991 15.37756 14.06801 14.822 16.09739 16.44575 16.48426 16.86766 10.83643 12.90215 11.20963 11.4503 12.48443 12.65709 14.0135 14.90167 14.40853 15.14135 14.69142 14.34933 13.56003 13.23642 13.07663 13.29242 14.56171 13.91872 14.96106 16.0597 15.73718 16.22322 16.35061 11.76764 14.94607 14.002 12.59242 13.17363 12.93256 14.04444 14.95929 14.73403 14.32073 13.673 13.46165 12.49231 11.98037 12.40751 12.22861 14.2252 13.65674 14.01322 15.1333 14.95369 15.47503 16.08985 13.89615 16.76128 15.37205 14.68637 14.55084 14.06249 14.60906 15.02118 14.96586 14.17659 13.32582 13.36398 12.40657 11.75675 12.20584 11.6482 13.49479 13.45353 13.88642 14.68982 14.64923 14.41646 14.38884 14.84046 17.53472 16.00968 16.66092 14.74903 14.52959 14.44483 14.51026 14.96541 13.62469 12.74818 12.63656 11.79429 10.7945 10.28362 10.71255 12.82129 13.17442 13.48379 14.43379 14.1143 13.92664 13.57136 15.24041 17.86895 16.36832 17.24933 15.26022 14.57038 14.41827 14.01725 15.12896 14.63774 13.50198 13.16672 10.8975 10.52911 10.55219 10.53394 12.4472 12.95718 13.381 14.41105 14.18102 13.43132 13.21059 15.70714 18.11394 16.63966 17.54475 15.6258 14.62249 13.44291 14.33535 15.30156 14.73038 12.71182 11.88729 11.21848 11.80892 11.28598 11.00321 12.07642 12.61302 12.96624 13.64967 13.5497 13.66227 15.18429 16.24144 18.45406 16.74632 17.26887 16.00562 15.20356 14.67932 14.5265 15.42036 15.9411 12.72794 11.28165 11.22411 11.92239 11.05458 10.47411 11.84302 12.45643 12.32757 13.31341 13.65614 14.01642 15.6444 16.61691 18.75608 16.65908 16.05809 16.49335 15.44349 14.24317 13.74861 15.73102 16.03167 12.45979 11.43863 12.06159 11.43628 11.58031 10.96982 12.73052 13.25921 12.43133 13.44257 13.17499 13.61122 15.05092 16.80972 18.82384 16.56598 15.89633 16.39415 14.86858 13.51579 13.62421 15.78119 15.96636 12.04702 12.23535 12.08618 11.75746 11.64274 11.03938 12.40111 12.2805 12.29179 13.94364 13.40477 14.06813 15.88864 16.63538 18.58344 16.62993 16.47061 16.84248 15.18759 14.40616 13.94959 15.81456 15.56275 13.3875 12.99495 11.75405 11.29325 11.58946 10.95365 11.4328 12.09967 12.70522 13.64252 13.03335 14.81887 16.09799 16.17998 17.74599 16.20119 16.20937 17.15302 15.38168 15.02195 14.70119 15.58851 15.20672 13.59827 13.00949 12.00444 11.9139 12.20626 11.42136 12.15257 13.27923 12.24949 13.81115 13.19789 14.65822 15.93385 15.63498 16.83412 15.9795 16.01633 16.73568 14.96041 15.20592 14.9941 15.25987 15.44159 13.90219 13.12603 12.1955 12.00728 11.73402 11.36467 12.2128 13.21522 12.46231 13.59565 12.94152 14.60943 15.73831 15.64667 16.88672 16.15878 16.30288 14.82288 12.78746 14.38334 14.24222 15.33887 15.6051 14.19205 13.4702 11.48957 11.67185 11.36558 11.50844 11.67504 12.6779 12.27801 13.62284 12.4663 13.766 14.50554 16.1116 17.70094 16.61898 16.63179 14.50537 13.00403 14.49458 14.1091 14.77081 16.03117 14.69265 13.87188 11.65564 11.77306 11.69971 10.80465 11.53343 12.87404 11.97025 13.6426 11.97943 14.26168 15.0657 16.30089 17.96895 16.63384 16.78599 15.04495 13.30599 14.34233 14.00725 14.74239 15.8376 14.84421 13.98984 11.77159 11.99564 11.91329 11.26901 12.10066 14.10714 12.30086 12.97296 11.96393 13.5807 13.9249 16.11331 17.73792 16.50445 16.31737 15.14762 13.18915 13.33717 13.48801 15.0379 14.98231 14.6054 13.371 10.87303 10.89191 11.57216 11.3191 12.55595 13.71982 12.37777 13.36162 12.34734 12.24435 12.79598 15.58554 16.86545 15.76826 16.14976 14.84043 12.69869 13.17145 12.83138 13.56788 13.88323 12.82279 11.39667 10.49319 10.13156 10.41932 9.690503 11.98269 12.59705 11.74903 12.81073 11.81398 12.05253 12.92546 15.40506 16.56629 15.7819 16.15461 15.12686 13.06547 13.38418 13.28866 11.46526 12.2537 12.2489 12.08193 10.35587 10.30065 10.11564 10.48493 11.5637 11.96607 11.58659 11.82748 10.88299 11.80397 12.83247 15.64443 17.13461 15.25182 15.23267 14.96755 12.78958 12.95011 12.96703 12.13067 12.01262 11.68263 11.51331 10.19018 10.40131 10.45652 9.893003 10.72811 11.31659 10.82685 11.00283 10.72475 11.77716 12.83387 15.71785 17.45413 15.5854 15.01698 14.3412 11.71642 10.96577 11.03219 11.98035 12.71681 11.61681 10.26505 9.601998 11.02885 11.42186 10.48678 11.01715 11.48228 11.22338 11.53144 10.79359 11.5774 11.99054 15.35344 17.22778 14.87986 13.97491 13.06646 10.3242 10.27509 10.32014 10.23042 10.61678 9.737593 10.01495 9.896219 9.359041 9.507567 9.67006 10.14279 10.65076 10.4929 10.57693 10.33899 11.15093 10.91731 14.73678 16.47514 14.2816 13.68988 13.41362 11.12034 10.6353 10.23782 10.21636 10.79559 10.0661 10.10203 9.259908 9.090837 9.185848 9.923974 9.884459 10.10081 10.24038 10.84077 10.28913 10.66675 10.87501 13.34543 15.10439 13.62741 13.43057 13.13955 11.26525 10.73161 10.48361 8.931073 10.65594 10.13154 10.01275 7.661518 8.794694 8.97205 9.528334 9.832764 10.47726 10.19211 10.24871 10.08061 10.30916 10.30075 10.66386 12.08491 13.25964 13.39106 12.19863 10.12935 11.24597 11.23391 9.032432 10.34383 9.701096 9.622985 8.836775 8.976686 8.384194 8.839561 9.518727 10.43447 10.18111 9.936262 10.31167 10.56191 10.62938 9.864835 11.36032 12.31589 12.7327 11.80678 10.03503 10.97492 10.7874 9.752045 8.775429 8.095765 8.616365 8.481807 8.58884 9.057997 9.505718 10.19115 10.05057 10.04556 10.14044 10.41077 10.46338 10.77466 8.924618 11.12906 12.26638 12.40822 11.61309 9.230251 10.80107 10.44947 9.52743 9.636349 8.786553 9.209707 8.387288 8.182937 8.243385 9.326593 9.774284 10.1685 10.02218 10.17269 10.70011 10.49688 10.61065 10.46031 12.47213 11.88194 11.74302 11.8674 10.72511 11.42089 11.52294 12.66962 13.42245 12.90012 11.16923 10.26218 10.81529 10.76803 10.16122 9.826 9.915348 9.86139 10.30795 11.00059 11.42232 11.84945 12.26625 14.16075 12.72903 14.60278 14.37007 13.44235 12.87462 13.86045 15.57594 16.44231 16.44123 15.36868 13.77279 15.25738 15.21306 14.52211 13.27622 12.97607 12.30169 14.6017 16.36056 17.2046 17.79084 12.88817 14.4487 12.22028 13.27812 13.9757 13.02691 12.24403 13.3259 14.29199 15.57484 15.93701 16.14005 13.74489 14.87244 15.91617 16.46932 15.27049 13.81515 13.83679 16.70215 18.24577 19.36378 19.67374 12.00124 15.37659 15.7605 14.22926 13.0174 13.10144 11.59302 12.30477 13.87144 16.48501 16.24954 14.65436 13.44942 13.95702 15.1756 15.80813 15.05493 13.84618 12.97811 14.7254 15.89062 17.37466 17.80906 11.40193 16.41908 17.10656 18.07596 18.44994 14.86982 11.46446 13.08391 15.70103 16.6888 15.61081 14.1348 12.79728 13.32965 13.90944 13.99649 13.78145 12.89573 11.9253 13.4449 14.24946 14.72222 15.25539 11.44434 16.72986 17.13328 18.86685 20.06189 16.01924 13.17847 12.7762 17.20245 16.84163 15.03655 13.80424 11.7222 13.07261 13.83397 13.96507 13.21282 12.76647 11.96956 12.39547 12.90304 13.23651 13.36372 10.10038 17.35346 17.76299 18.8912 20.46964 16.98438 14.85764 12.72846 16.86143 16.67736 14.81743 13.0213 12.2606 12.59028 13.18198 14.63323 13.8833 13.29084 11.56619 12.33959 12.88427 13.18531 13.93617 11.39528 17.46929 17.92314 19.14353 20.62991 16.99307 15.65434 13.20797 15.76896 15.81176 13.97282 12.77619 11.2707 11.88343 12.92847 13.32276 13.7076 13.56002 11.07274 11.85992 12.23533 13.28798 15.04418 11.27983 17.707 18.24305 19.08735 20.56552 17.11422 16.33149 13.43726 14.52213 14.48029 13.66881 12.0331 11.1849 10.85902 12.006 12.63326 13.76072 13.75976 11.0928 11.39149 11.49694 13.85464 15.78272 10.4093 17.90809 18.4453 18.32235 20.13852 17.31362 17.00359 13.08082 13.30086 13.77682 13.61921 11.83928 11.08163 10.67048 11.6871 11.93983 13.32355 13.21966 11.60241 12.79556 10.68321 13.65361 15.63675 11.84527 18.06657 18.71371 18.15455 20.01794 17.42912 17.4063 13.26461 13.40163 13.82001 13.56594 12.01353 11.27739 11.76238 11.80556 12.06823 13.41709 13.49274 11.33103 12.29501 11.13933 13.40397 15.07014 11.17124 18.38477 19.04682 18.43799 20.28102 17.52682 17.30856 12.02493 13.38366 14.0256 12.96288 11.21294 11.00717 11.76898 11.5427 11.69634 12.18315 13.27228 12.24852 12.80867 11.54512 13.54795 14.91226 11.79911 18.40328 19.16708 18.38249 20.19378 17.33193 16.52722 12.74763 13.76983 14.43673 13.70339 10.60393 10.94744 11.23283 11.7214 10.93908 12.70267 13.61965 12.34297 12.93185 11.72894 13.06544 14.49717 11.53892 18.40511 19.1988 17.54394 19.24091 16.508 15.51558 11.58755 12.57494 12.96985 12.25272 10.15904 10.6575 10.79901 10.68679 10.70864 12.52 13.14616 11.88523 13.06559 11.90712 13.5841 14.07163 11.24507 18.51727 19.28405 15.55707 16.47013 15.3894 15.69263 12.4398 12.47237 12.42525 11.96187 10.67544 11.41625 11.04646 10.61635 10.52443 12.70697 13.38649 11.35408 12.26194 11.28505 13.45126 13.82557 11.66839 18.54571 19.34097 15.28023 16.99143 15.16772 15.61421 11.90284 12.48574 13.0267 11.92334 10.24209 11.53736 11.04919 10.13369 10.87534 12.32853 13.07113 11.1777 12.35379 11.42702 13.24903 13.47682 11.33042 18.52498 19.28227 15.3864 16.97915 14.79772 15.07273 11.31091 12.86657 13.35474 11.33974 9.940867 11.48389 10.81812 9.995729 10.97024 12.09934 12.44435 10.87501 12.38766 11.07067 13.29669 13.62211 11.3056 18.38368 19.13547 14.39207 16.36372 14.8709 14.99244 11.87787 12.69045 13.26806 11.46194 8.540175 10.51303 10.84584 10.27139 10.64636 11.47711 11.95679 10.57964 11.26044 10.76696 12.47983 12.5918 11.55642 18.09599 18.73145 15.37899 17.526 15.3725 15.14406 11.61225 12.45738 12.59422 10.7795 8.732772 9.834822 10.28893 9.671982 10.17871 10.94767 11.20057 10.26523 10.61838 10.52447 10.65674 11.38504 10.35312 17.61216 18.04445 15.89868 17.93677 15.43736 14.92465 10.95503 10.74119 11.10365 10.10367 8.769894 9.549344 9.448477 10.16095 9.991289 10.12919 10.67581 10.30081 10.2757 10.61878 11.08467 11.66054 10.57029 16.80257 17.43232 15.33712 17.40169 14.69754 13.7979 10.32226 10.54766 10.62139 9.538151 8.558439 8.763721 9.43328 9.823753 9.941569 10.20876 10.29988 9.839418 10.4947 10.67628 10.63656 11.36743 10.88069 16.40481 16.94452 14.63999 16.55998 13.75831 12.04815 10.07983 9.779847 9.41483 9.367539 8.638872 7.551649 8.591156 9.22356 9.253392 9.312204 10.12255 9.771526 10.66726 10.28885 10.70903 10.99041 10.68995 15.9614 16.66981 12.87561 15.32809 13.38852 13.34967 10.08965 9.267484 8.510974 8.937634 8.066225 7.492024 8.559677 9.379137 8.934621 9.395594 9.947574 9.762503 10.16802 10.52471 10.62313 10.52163 10.10682 15.73363 16.55744 12.98704 15.02876 13.22308 13.64594 9.306398 8.513678 8.840482 8.639846 8.813548 8.690471 9.372956 9.21609 9.271674 10.22423 10.17199 9.91317 10.44354 10.81481 10.71306 10.58567 10.53498 15.85452 16.48894 13.69206 15.73015 14.98417 13.35866 12.12415 12.66079 12.8636 12.57128 11.65822 10.42173 9.932479 10.30401 10.88577 10.69672 11.60742 10.67614 10.5448 11.20179 12.58635 13.41792 10.96499 15.49205 16.39072 14.58421 16.09194 14.12068 12.85947 10.9668 11.6846 11.61401 11.32033 10.1519 9.595464 9.126978 9.282423 9.871722 10.47498 11.93141 10.77083 10.79808 10.82797 12.26179 13.4949 10.02513 14.95054 15.62905 12.19269 13.6047 13.04639 12.49895 9.641859 10.20514 10.12763 9.829097 9.059594 8.440591 8.796917 9.133607 9.019018 10.19306 11.17522 10.55359 10.32446 10.81375 11.08818 12.5863 9.422004 14.69329 15.27407 12.65151 13.94985 12.99975 11.70039 9.886936 9.611949 10.09684 9.314202 9.766679 9.321723 8.8813 8.354034 8.528647 9.770875 10.59045 9.79849 10.28119 10.74567 10.74199 12.01325 11.32263 15.05788 15.25787 15.88041 15.08022 14.13194 12.75217 11.34698 9.656963 9.717936 9.331264 8.585823 9.124638 8.87212 8.442982 8.890512 9.943332 10.48704 10.23122 10.30991 10.68609 11.49976 11.52623 13.40004 15.62923 17.28662 19.34645 17.7522 14.88166 15.30356 13.29276 11.17599 10.1756 8.496209 8.687905 8.767036 7.138587 7.905816 9.155358 9.870092 11.34072 10.64145 10.56284 10.93426 11.27267 11.83103 14.40832 16.92628 18.28235 19.92572 17.42484 16.51931 17.17439 13.85876 11.32172 10.88191 9.843261 8.557543 8.702249 8.43864 8.905317 9.214272 10.79284 11.19663 10.4797 10.33966 11.11496 11.59549 12.62567 15.07293 17.23655 18.7453 20.03891 18.20394 17.32358 16.8287 15.43667 13.0998 12.50691 10.92344 10.46035 9.055417 9.849059 9.764614 11.06528 13.47688 13.99895 12.79779 12.12013 14.56175 14.29823 14.93593 15.40606 17.37957 18.26671 19.24368 19.16639 17.99058 16.59817 14.71303 12.86606 12.04343 11.7385 9.705905 9.335643 9.112566 9.626029 10.41576 13.39695 13.71364 12.28225 11.58019 13.76471 13.65422 14.2695 15.64262 17.64327 17.19793 17.43849 19.78349 18.46711 16.14888 16.3467 13.90007 12.84516 12.72527 10.46768 9.428706 9.794108 10.62751 11.56921 13.06464 12.97483 12.06074 12.42412 15.20449 15.17994 15.41442 15.52258 17.33565 17.81485 18.67915 20.30933 18.47157 16.206 16.37829 16.18498 14.41841 13.32267 11.18768 9.268024 10.2243 10.31914 12.25662 14.13956 13.31647 12.61077 13.04033 15.24885 15.47131 15.91226 14.72044 16.24851 17.39948 18.02982 19.91796 18.15676 16.86558 16.89674 18.34361 15.89882 13.7806 11.83443 10.31598 9.947871 10.88693 13.04681 14.78731 14.09249 13.07614 13.30486 14.96555 15.89365 16.21339 12.94438 14.262 17.79223 17.94734 18.41548 17.99884 16.59502 17.46818 19.89834 17.3267 14.68132 12.74071 10.74997 11.11081 11.97623 14.37372 15.06054 13.62777 12.74747 14.17785 13.22865 15.07573 15.67369 11.9413 14.24815 17.19899 17.78853 19.11386 17.95886 17.36403 17.78174 19.56396 18.41936 15.83994 13.5232 11.30285 11.13494 12.42168 14.83165 15.21284 13.93472 14.22501 15.48852 14.69647 14.61711 15.37134 13.80032 15.34109 17.01766 17.4297 17.96654 17.89771 17.45484 16.8976 18.80153 19.64696 17.77114 13.78843 12.49898 11.85447 13.19477 15.72658 16.27253 14.45719 14.41123 16.36125 15.85711 15.05885 15.80895 14.42734 15.95719 16.8165 17.40023 17.72437 18.32386 18.0716 16.22936 18.2776 19.88119 18.43486 14.89068 13.09634 12.62326 14.15393 16.27906 16.78207 14.59756 14.30995 16.8557 16.74701 13.89337 15.01136 13.1981 15.42621 17.47243 17.46376 16.60345 17.87163 18.14639 15.80742 17.8999 18.86058 18.78569 15.2696 12.82393 12.26846 14.426 16.64136 16.84205 14.60646 14.58007 16.73913 16.8489 13.78548 15.02061 14.53758 16.3012 17.77195 17.30224 18.26668 17.24618 16.88194 15.98161 16.4734 18.86712 18.13484 16.05925 12.78708 12.62607 14.48131 16.29807 16.06342 14.38513 14.33487 16.47281 16.5306 13.28973 14.15116 13.29329 15.40082 17.00095 16.67248 17.51397 17.87264 17.22511 15.87745 16.17892 17.66627 18.2972 16.80437 14.20589 12.99962 14.83743 16.62644 15.83631 14.91555 14.99209 17.03086 17.57478 15.26948 15.94518 12.60118 14.90419 15.67589 16.70849 16.94395 16.61985 16.03358 15.05487 15.99355 17.37237 17.7354 17.29265 14.00175 12.25772 14.06873 15.4484 15.89154 14.37778 13.64605 15.54983 15.959 14.05933 14.62753 13.46687 15.90945 16.95177 16.9344 16.38556 16.47206 16.12689 15.33399 16.03906 17.06773 16.99802 17.40662 13.44633 12.45146 13.97935 15.02217 15.57034 14.04656 14.18954 15.08655 15.59686 13.81427 14.97765 13.90775 15.34541 16.23319 17.18387 17.43214 17.35052 16.137 15.33103 15.5793 15.9622 16.35075 16.71717 13.52683 12.29098 13.29745 15.11607 15.76651 13.92764 14.35643 15.45294 15.56918 14.29957 14.75815 12.64945 15.05234 16.66335 17.67402 17.42719 17.03349 15.29472 13.20675 14.79218 16.15494 16.06722 15.88496 14.37258 12.09099 13.10366 14.55416 15.20259 14.15096 14.36049 15.3579 14.84148 14.77236 15.21402 13.63886 15.13448 17.12833 17.25077 17.57319 16.51949 14.79358 14.33071 15.40003 15.31295 14.707 15.51841 15.19862 12.16728 12.38076 13.97288 15.01122 13.84911 14.36896 15.99493 15.19653 15.71203 15.79622 14.08951 15.27791 16.67466 17.38719 17.48137 15.49804 14.64399 13.99431 14.06412 14.96719 14.45313 15.07616 15.22869 11.85608 11.80214 13.4829 14.47193 13.28767 13.82474 15.54498 14.68076 15.78218 15.55037 13.55869 15.54187 15.30116 16.07854 15.19114 14.89549 14.28598 13.40435 12.58551 12.71723 13.51417 14.44852 13.74717 11.34321 11.73631 12.8637 13.46484 12.86962 13.4271 14.9927 16.06477 17.438 17.00769 14.03767 15.96629 15.7353 15.65322 14.90481 14.81491 13.83562 13.2442 12.39499 12.31491 12.90394 14.30139 13.67956 10.38161 11.00745 11.82061 12.68529 12.26423 13.03794 13.27276 13.62125 14.79159 14.69412 14.69835 16.23426 15.85394 14.956 15.55784 15.1201 13.12001 11.77338 12.35275 13.03831 12.70205 13.89809 13.49535 10.74578 10.39047 11.01446 12.48515 11.93507 12.14398 12.33028 12.54093 12.23906 11.828 13.74119 15.01042 14.63525 14.21064 15.04048 14.53166 13.30235 11.51442 11.54563 12.75932 12.87387 12.97661 12.22388 9.737226 8.855085 10.95898 12.41875 11.5811 11.65182 12.16752 11.78344 11.6825 11.58462 13.79247 14.65056 14.39971 14.56042 14.50872 14.48325 12.4725 11.32357 11.69767 11.76651 11.72759 11.75854 11.63687 9.03346 8.632442 10.05544 11.80099 11.283 11.6399 11.7433 11.51521 11.30795 11.44739 12.4817 13.96644 14.94901 14.22443 14.7217 14.6918 12.00653 11.63244 11.49402 12.39865 11.62017 11.95335 10.76735 9.714913 9.972126 10.44865 11.5843 10.77267 11.39896 11.29488 11.80279 12.45774 12.97729 10.99601 12.48925 13.91558 13.39563 12.76022 12.97499 10.67527 11.2872 11.05415 11.66541 11.35227 12.07333 10.91728 8.470509 9.390297 9.98071 10.65596 10.24184 11.05679 11.06191 11.15756 11.02771 10.34172 11.55889 13.16734 13.01277 13.71551 11.48029 11.84606 12.16008 11.11222 11.96976 12.21278 12.98672 12.49252 11.65213 12.38936 13.03628 13.42355 12.62503 11.73549 11.11625 12.92801 14.35214 14.86793 15.02906 10.42775 12.77446 12.08269 12.53821 11.88333 11.98844 12.13725 11.12525 12.48612 13.17795 13.38511 12.48855 11.81891 12.69561 13.0315 13.13174 12.79269 11.96432 12.52114 14.89753 16.66616 17.80948 17.48282 11.87147 13.35178 12.29651 13.07613 13.38078 12.15471 11.58152 10.57638 11.48294 11.66988 10.83331 10.95618 10.80718 12.60706 13.70898 13.6584 13.12783 12.36247 13.81388 16.36983 18.19867 19.32249 19.17922 11.74805 13.03258 11.83647 10.99839 11.53884 11.58733 9.78068 10.00441 11.77152 12.2512 12.23087 13.11207 12.52222 13.45929 14.83094 14.73086 14.22945 13.92837 15.33029 17.7077 19.34477 20.7841 21.06674 12.91207 13.92127 12.60293 11.2707 11.34953 11.66406 10.61612 10.41087 11.90737 12.03745 12.62049 12.73641 12.31181 15.63897 15.29306 15.0111 14.84808 15.03202 16.69465 18.62388 20.75715 22.16574 21.82943 11.44404 13.17524 11.91981 11.4003 11.81657 10.4973 11.08138 10.91362 11.54249 11.68209 11.96895 12.71395 12.69716 15.29071 16.25213 15.87629 15.68893 14.98099 17.12889 18.67869 20.67893 22.07556 22.39026 12.4943 14.38828 15.40293 14.53412 12.63508 10.61958 11.04276 10.82849 11.58219 11.86627 13.09368 11.76773 11.85476 15.56555 15.54773 14.94056 15.46294 14.71608 16.38725 18.32511 19.88208 20.835 20.72138 12.06502 16.88607 18.26798 18.51961 18.70255 16.0556 11.92916 12.43737 13.55841 13.30871 12.92406 12.8846 12.13316 15.64249 15.85884 15.73912 15.52897 14.45106 15.96146 17.69323 18.59188 19.02813 19.20515 11.12339 17.63247 18.67913 18.09006 20.21992 17.90995 12.6137 12.48078 12.48313 12.308 12.5629 13.46077 13.18955 15.1113 15.49067 16.01841 16.40285 15.20319 16.30907 17.38044 16.9833 16.74973 17.5288 11.91933 17.71219 18.231 18.7819 20.81494 18.03944 12.80576 12.62215 13.70358 14.11044 12.98072 13.73609 12.88998 16.17216 15.98503 15.40534 16.2627 14.74855 14.94189 16.8815 16.57269 16.14612 17.22886 10.80071 17.88858 18.37441 19.57571 20.85023 16.92813 14.54551 14.11315 14.60858 14.76622 14.24647 13.50114 13.44903 15.14018 15.77174 16.55495 16.70045 14.63158 14.95225 16.897 16.51554 16.39054 16.95824 10.11735 17.24759 17.42141 19.76315 20.66429 16.31513 15.35933 15.46266 14.2526 14.75529 14.8134 13.60172 13.60854 15.0717 15.27205 15.8339 16.31969 14.84996 15.4993 17.3387 16.82842 15.77378 16.33088 11.58894 15.94406 15.80265 19.82332 19.81112 16.33015 15.83328 16.12075 14.11878 13.67492 14.12749 13.19047 13.91129 14.98374 14.91681 15.74825 16.61319 15.2014 15.57807 17.29531 16.63654 15.11069 16.41315 12.11817 16.37547 16.11933 19.74942 19.52616 15.253 15.60251 15.62886 13.73787 12.94972 14.53512 13.22932 13.03554 14.42677 14.02384 14.75253 15.97637 14.65869 15.00835 17.03261 16.1345 14.50001 16.3125 12.40414 17.09673 16.56095 19.30345 18.83337 15.53385 15.46334 15.14222 13.0195 13.65549 14.05797 13.27337 13.1787 13.58766 13.74914 13.84215 14.70384 13.81669 14.36711 16.36557 16.29565 15.23389 17.42854 13.11347 16.62823 16.08442 18.65703 19.09037 15.8935 15.2197 14.41059 14.00731 14.22315 14.2603 13.98392 12.74996 12.83496 12.62025 12.43474 14.70534 14.04083 13.31598 15.78194 16.0346 15.06308 16.98965 13.64474 17.90531 17.46792 19.65909 19.84337 16.36866 15.0947 14.08054 14.56519 14.61388 14.04171 13.45949 11.97165 12.38503 12.46181 12.36982 13.73913 13.27664 12.86066 14.10406 13.75239 13.30816 15.46512 14.14659 17.85538 16.63506 17.69785 17.37612 14.4621 14.21311 14.33 14.55272 14.0266 13.34313 12.6474 11.67851 12.07374 11.39458 12.00585 13.00983 13.07051 12.53945 13.83851 13.02929 13.78781 15.03182 14.42228 17.95903 16.79436 17.2867 17.37424 14.4423 12.56357 13.39425 14.97358 14.38745 12.16811 12.31725 11.24478 11.62687 11.66598 11.82592 13.17022 13.03793 12.44336 12.93122 12.50479 13.24247 14.70499 14.74926 17.10213 16.10866 18.41386 17.76688 14.66671 12.0519 12.36404 14.64657 13.54079 11.52991 11.67943 10.9411 11.91207 12.82024 12.68861 12.79371 12.74705 12.14265 12.87091 12.87852 13.3739 14.64138 14.77377 17.52547 16.45933 18.03106 17.99345 14.37569 12.28482 12.38711 13.49167 12.96972 12.2464 11.9446 12.06746 13.32547 13.42399 12.804 13.77554 13.8069 12.38337 13.585 13.03204 13.04344 13.17559 14.33936 16.05802 15.20399 17.29784 16.82894 14.67938 13.40503 14.50885 16.62795 16.48669 15.85748 14.00688 13.75563 13.0535 13.17885 13.77508 14.15859 14.48487 13.08349 14.30881 13.77487 13.4736 14.49444 14.44479 16.99548 15.77001 17.10963 16.52903 14.38944 13.44239 14.06731 16.73449 17.81567 16.47066 14.45036 13.36218 11.99206 12.16488 12.52671 13.19155 13.33347 12.81071 14.34716 14.2478 14.17321 15.78081 14.02579 17.08305 15.59479 15.89314 16.72221 14.24861 13.47705 14.10365 17.43085 18.94127 17.04 14.55132 12.30284 11.67238 12.13895 11.74947 12.48997 12.62799 12.61127 14.23425 14.47474 14.48953 16.6846 12.98601 16.43487 15.30097 15.82755 15.67639 13.93307 12.06077 14.01533 17.31017 17.03305 16.06872 14.63635 13.17454 12.51504 12.19607 11.30268 12.40507 12.31048 13.08197 14.41822 14.24439 14.75511 16.61187 12.36717 14.63769 12.81204 14.45165 13.75739 14.0802 13.48325 14.81929 17.03195 17.97369 16.36871 14.08131 13.45929 13.48154 13.22458 13.06752 12.79095 12.71402 13.04852 14.30993 14.63789 14.94942 16.90777 11.93372 14.51598 12.94251 14.97276 14.5037 13.14109 12.6004 15.28386 17.44633 17.41194 15.19083 13.97468 12.30335 11.49983 12.01657 12.22904 12.7571 12.17981 13.11903 15.56299 14.76678 16.0535 16.8217 12.47566 14.19673 11.79418 12.79603 13.27397 13.03157 14.51644 15.58098 16.45773 16.79338 14.77104 13.59812 12.80408 11.51495 12.39793 12.11381 12.55917 12.43729 13.31075 15.56109 14.98054 15.78551 17.06624 12.2613 15.1282 13.99666 13.71514 14.27644 13.59662 14.62273 14.96381 16.1037 15.93762 14.79321 13.20536 12.09543 11.00414 11.58279 11.8383 12.9191 12.51326 13.47569 16.26331 15.60605 16.11314 16.97496 12.43962 14.93872 12.93799 13.37484 14.13616 13.94297 13.31241 15.01747 17.49583 16.37276 14.13916 12.80372 11.91654 10.96919 11.34828 11.55524 13.11632 12.65655 13.44765 15.82003 15.211 15.98718 16.41879 12.20704 14.56072 12.76487 14.66424 14.36893 13.81488 12.67005 14.58511 15.8139 15.15328 13.72443 12.0736 11.75713 10.39046 10.3162 11.07518 13.42291 12.18517 12.6754 14.56121 13.61762 14.73406 15.99769 12.26719 14.83184 13.45157 13.9031 13.37387 13.42337 13.16261 14.01834 13.45282 14.0881 12.42882 10.71366 10.67623 9.888527 9.556181 10.42893 12.93971 12.08191 12.30767 14.6603 13.51334 14.00465 15.0682 13.72396 15.37463 14.90107 14.14883 14.71334 14.23447 14.62967 15.41844 13.9625 13.62733 12.02162 10.61794 9.693156 9.38163 9.607562 10.24143 12.10383 11.62002 11.61677 13.37127 12.76904 12.98495 13.14606 12.20455 15.08801 16.28204 15.02526 14.91302 14.54155 16.05799 15.24317 13.17851 13.23946 11.95253 10.98236 9.365788 9.214337 9.505456 10.4926 10.92743 11.19956 12.08282 12.89608 12.90349 12.21022 12.78775 13.37813 14.82368 16.03482 15.19005 16.00402 15.02282 15.84676 15.76265 13.34728 12.43027 11.99226 11.34601 9.200621 9.239662 9.540243 11.00728 12.16874 11.82533 11.95636 13.50077 12.4501 12.26641 12.92042 12.66223 14.38916 15.40475 14.94944 16.37963 15.2842 15.38037 15.8695 13.61753 13.21642 11.7801 11.01452 9.542067 9.19785 9.696535 10.70263 12.5226 12.46992 12.17822 13.79243 13.24585 13.34737 13.80106 11.79797 13.75565 14.85456 15.8272 16.72862 15.18555 15.07867 15.58954 14.36672 13.03338 12.42223 11.01965 9.557907 9.226222 9.848079 10.37486 11.38179 11.42391 12.02948 13.78323 12.73048 13.11424 13.94043 12.11479 14.20692 15.95607 15.77075 15.94264 15.04848 14.68504 15.58499 16.73163 14.876 13.04782 11.34189 9.554831 9.312258 9.405445 10.54039 12.08341 11.93015 12.28186 14.35123 13.82728 13.614 15.07887 11.63898 13.24526 15.91903 15.04351 15.44301 14.33202 14.69388 15.04394 16.66434 15.8622 13.70809 11.39564 9.984374 9.255429 9.771338 10.38831 12.17067 12.11052 12.20296 14.49279 14.43369 13.75218 14.74203 12.24345 14.6031 16.65611 14.82507 16.38684 15.87055 14.16241 14.53406 16.72972 16.78175 14.29714 11.9692 10.40499 9.319419 10.12237 10.74756 13.3062 12.89304 12.51923 15.03736 15.23477 14.65409 15.5749 12.77314 15.07554 16.98285 15.57631 16.88236 15.60186 13.31313 14.22181 15.56985 16.22102 14.96699 12.77368 10.60659 9.910019 11.08181 11.14588 13.15701 12.80074 12.45314 14.14474 14.5937 14.61545 14.75511 11.81499 14.35236 15.86184 15.37682 15.91093 14.51173 12.01213 12.23065 14.53028 15.26377 14.16712 12.59848 10.46429 9.104154 9.218637 9.824287 12.90368 12.61128 11.938 13.29911 13.48286 12.61785 12.90715 13.13115 13.74104 13.82935 14.62105 13.24596 12.30486 11.74188 12.57558 13.35646 14.14618 12.51182 9.92897 9.892784 8.203323 8.843456 9.73543 11.10688 11.40638 11.2225 11.48934 11.82256 11.33256 11.55696 13.5014 14.46064 13.74532 13.76357 14.51184 13.47387 12.36466 13.09748 12.37077 13.78026 12.56234 10.40441 9.652602 9.258573 9.640882 10.48315 11.37579 11.28799 11.69723 12.14306 11.93345 12.913 12.47232 12.11707 14.41063 14.2667 13.93633 13.81357 11.92622 11.39311 12.56514 11.91435 12.2172 11.83334 10.78043 8.693699 9.34746 10.5232 10.74675 11.27402 11.17691 11.69285 11.59679 11.87287 12.48645 13.45397 12.73287 14.28872 14.12864 14.03616 13.14685 12.7475 12.18416 12.10903 11.98855 12.79712 14.14206 13.79637 12.14143 12.49956 13.05192 13.06696 12.86376 11.90433 12.45795 13.79512 14.72743 15.6082 16.03671 13.99284 14.59781 15.86497 15.46929 15.35721 14.4506 13.86872 13.70982 12.77764 13.87713 16.70483 16.12365 13.74394 14.14882 14.72046 14.79044 14.55702 13.26187 13.4715 15.52675 16.2828 17.03688 16.70895 13.34487 14.76827 16.66223 16.6201 16.95358 16.41091 14.59964 14.13615 14.98613 15.52808 16.94203 16.33436 13.65864 12.67898 12.89719 13.15985 13.87055 13.7345 13.81801 15.46476 15.5521 15.17291 16.18393 11.05816 13.38546 16.02215 16.0239 16.26703 16.0995 16.00097 15.06918 15.39436 16.33123 17.5566 17.69474 14.73381 12.76004 13.46956 13.62351 14.9516 14.46614 13.86967 15.92621 15.77614 15.14017 16.05052 13.44674 14.49088 16.24643 15.87667 15.80228 16.08157 16.27578 16.11953 15.71647 16.77408 17.38955 17.5013 14.82175 12.91548 12.99751 13.53425 14.71743 14.50213 14.5002 15.80028 15.50727 14.7684 16.64701 14.21669 14.68321 15.45795 15.69659 15.90129 16.00284 16.18194 16.61241 15.75285 16.67905 17.6036 17.33829 14.63122 13.52661 13.50696 13.30114 14.47372 14.06641 14.2557 16.1715 16.02145 14.45178 16.56786 13.89403 13.90886 13.8904 15.63989 16.239 16.28278 16.61728 16.93481 16.17262 16.97161 18.37757 18.09198 15.23442 13.31642 13.7317 13.67162 14.61277 14.06051 14.15388 16.12131 16.52321 14.41898 16.15249 13.62738 14.29071 14.26743 15.39755 16.17412 15.93856 16.81614 17.35265 17.03794 17.52091 19.20687 18.71931 15.41284 13.25959 14.02276 14.49864 15.36796 14.59919 14.92057 16.34993 16.91476 14.57673 16.4135 13.91304 14.38333 15.62968 15.92608 15.88913 15.46424 17.23949 17.6737 17.75764 18.32361 19.38836 18.81548 14.75313 13.59059 14.47715 15.14762 15.94664 14.38755 14.47487 16.32241 16.61687 13.88076 16.03177 13.85443 14.63751 16.63829 16.22158 16.00957 14.22576 17.54068 17.94837 17.70362 18.35151 19.07424 18.78005 15.38741 13.65261 14.89409 15.66142 16.46598 15.04117 14.94388 16.69312 17.13902 14.49912 16.41131 14.16736 15.20732 17.17613 15.65355 14.81104 14.93489 17.35307 17.69239 17.67073 17.9412 18.96013 18.70328 15.56409 14.20707 14.99696 15.9745 17.04941 15.52152 15.42804 16.55275 17.19493 14.82115 16.61891 14.55787 15.56332 17.40187 15.79714 15.16877 15.23872 17.43352 17.88713 17.42919 17.76297 19.16017 18.89678 16.21667 14.49569 15.32538 16.22569 17.27599 15.67997 14.60294 16.08368 16.37376 14.28088 16.07994 14.28819 15.29579 16.9726 15.32225 14.96721 14.86766 17.3646 17.55653 16.88566 16.39165 17.97582 17.84254 15.61118 13.325 13.99773 15.29101 16.41687 14.61869 14.14026 15.54824 15.78234 13.5513 15.05351 12.89534 14.19264 16.16715 15.45553 14.97155 14.18898 16.54575 16.86909 17.18435 16.91364 17.95696 17.44936 14.9484 14.08921 14.70956 16.02505 16.75773 14.69309 14.29639 15.83831 15.93069 13.20353 15.10151 11.07287 14.01731 15.98684 15.85503 15.7026 14.17124 15.66209 16.81634 16.69689 17.06315 17.20102 16.85413 14.60714 13.95707 14.35706 15.67642 16.10085 14.48048 13.75637 15.7046 15.97279 12.9786 14.57301 13.20215 14.88027 16.1391 15.30331 14.56342 14.65112 16.31849 16.70032 16.30379 16.66877 17.15785 17.35987 14.50481 13.62881 13.80476 16.18898 16.30147 13.83495 13.66053 14.89267 14.77247 12.55925 14.45503 13.06126 13.95905 14.72861 15.52299 15.57437 14.80034 15.9755 16.06871 15.0617 16.14234 17.04153 17.21765 14.65441 13.15693 13.40964 15.61284 16.12287 13.8438 13.76604 15.52066 15.88898 13.41924 15.27078 12.30977 13.65725 15.62276 15.12077 15.0009 14.32717 15.56222 15.53802 15.59415 16.0091 15.70288 16.7213 14.29013 13.25526 13.82748 14.57323 15.08817 13.3787 13.22771 15.28969 15.54399 12.92044 15.89454 13.2355 12.87303 14.13755 14.8824 14.98317 14.09578 15.47559 14.69907 14.95037 15.00035 15.11841 15.08056 14.14125 13.50607 13.85954 13.90839 15.27832 13.46804 13.2138 15.63453 15.70406 13.72386 16.19327 14.09465 13.80971 14.12421 15.16251 15.51726 14.75089 15.25305 14.35832 14.27529 14.6144 14.28123 15.06938 13.85847 13.27495 13.16495 13.6391 14.85534 13.8216 13.19121 14.84105 14.6136 13.33247 14.90938 14.17169 14.05926 14.38466 15.14356 15.18883 14.75758 14.63411 13.4688 13.57265 14.68271 14.24092 14.8144 14.59175 13.15273 12.52619 13.557 14.39644 13.34105 12.86075 15.03354 14.76084 13.2114 14.36096 12.94696 14.0161 14.38512 14.93382 15.28973 13.96826 13.00536 14.16216 12.7634 13.37025 13.69937 14.27973 14.28271 12.20191 11.58065 13.0691 13.86918 12.99897 12.07017 12.88836 13.36119 13.8559 13.72427 14.00163 14.74522 13.96561 13.84176 13.14617 12.28493 13.21515 13.64575 12.21422 12.96211 13.65326 13.52429 13.38388 11.56683 10.93623 12.6721 12.94885 11.75394 11.93754 12.60298 12.66667 13.39652 13.23497 14.01837 14.65643 14.34931 12.89079 12.44645 12.47288 12.34212 12.92817 12.88704 12.13856 13.52651 14.26985 13.20721 11.13747 10.50563 12.04486 13.04915 12.82268 12.21847 14.11812 14.85144 15.37979 15.23997 13.68709 14.73938 13.74758 13.45861 13.16367 13.00546 12.78111 12.54126 11.39514 11.72749 12.81818 13.32782 12.47606 10.72879 11.57598 13.16603 12.89361 13.47785 12.73763 14.78968 15.50553 18.04643 17.43831 12.58177 13.59478 14.05649 13.31381 13.11898 12.32821 13.0021 12.62218 11.5436 12.16554 12.48717 11.81394 10.50265 8.973746 10.09016 12.06378 12.39155 12.9348 12.42843 14.2313 14.86099 18.31309 17.32769 12.75411 12.6887 12.49659 12.86026 12.59906 11.34449 12.41792 12.40671 10.25577 10.55363 11.62938 11.7192 11.39313 9.014958 9.833184 11.20295 11.54293 12.10884 12.57974 14.2528 15.04182 16.35394 17.43106 13.07687 12.93932 12.05013 11.10465 10.92198 10.16203 11.9019 12.00359 11.20652 11.09058 11.98129 10.94307 10.32444 9.561 10.09412 11.1652 11.89071 12.46157 13.37886 14.81377 15.79583 16.46983 16.3099 12.44068 12.16542 12.749 11.51701 11.75818 10.98072 11.45177 11.79877 11.41194 10.86352 11.39708 11.80494 10.21916 10.17022 10.94074 12.73651 13.22818 13.90771 14.318 16.45604 17.52512 18.12885 17.99037 12.84129 12.74346 11.62644 11.11886 11.60124 9.904121 10.04816 10.7376 10.31966 11.05361 11.45463 12.15746 11.15053 10.69711 11.84554 13.98456 14.60289 15.31413 15.49967 16.84238 18.05069 19.01266 18.84834 12.53398 11.96433 9.244778 8.572387 10.26614 9.39289 10.5042 10.72253 10.65647 12.75043 13.54582 13.20332 12.30947 11.8775 13.39289 15.73803 16.03198 17.65893 17.08116 18.5041 19.5771 20.24899 20.35165 12.00563 12.20351 10.276 9.838881 10.18145 9.774684 9.775256 10.85217 11.57201 12.9943 13.72266 13.57533 12.36394 12.41757 14.64912 16.40559 16.40833 17.94178 17.0117 19.56192 20.42689 21.10626 20.54123 11.91491 12.22656 10.11695 11.68905 13.45684 12.16579 11.17595 11.02882 13.19395 13.89767 15.23678 15.18915 13.55568 14.68092 15.77575 16.75733 17.13061 17.34155 17.21397 19.74595 20.57611 22.05666 21.36359 11.47355 11.28028 10.45217 11.66897 13.02617 12.40421 12.3838 12.38136 13.96514 15.68431 16.50488 16.14618 15.39929 15.91039 16.42896 17.51905 18.45585 18.59583 17.75705 19.62965 20.81224 22.27122 21.80147 12.52662 11.94858 10.55505 12.42413 13.77102 13.32065 12.9342 13.66854 14.39565 16.63391 17.94618 17.4248 17.46566 16.57822 16.48766 17.86062 18.27674 18.54208 17.23242 19.31924 20.2264 21.92178 21.3364 12.02873 11.26655 9.571183 11.58556 13.19479 12.65055 12.59585 14.40476 14.95008 16.4713 18.34317 18.11756 17.86362 16.10263 16.13897 16.93494 18.05787 17.58092 17.09885 18.80086 19.4799 20.65734 19.97151 10.86476 9.108546 9.552567 11.91356 12.38227 12.85921 11.95166 14.44887 16.19041 17.26532 17.9296 17.84677 17.18984 16.35882 15.73214 17.40462 17.33592 16.97078 16.5151 16.88156 17.47563 18.54997 17.5454 12.60442 11.37389 10.2908 11.55008 13.28062 14.39302 13.83146 14.80365 16.86215 17.7065 17.82295 16.90414 16.20468 15.93856 16.19014 16.84039 17.83888 16.61141 15.98524 16.43695 16.56059 17.5152 17.1277 12.41213 11.59318 10.9033 11.81183 13.5534 12.9817 12.88539 14.86807 16.76102 18.08833 17.84195 17.58156 15.95464 15.7454 16.94265 17.86619 18.44193 16.60484 16.43938 17.78119 16.30627 18.12034 18.17815 13.1731 10.92382 11.44889 11.58021 12.51424 12.61171 11.91807 14.35635 16.45222 18.2344 18.02634 18.44849 16.43503 15.31518 16.52777 16.50167 17.21136 16.07273 16.42845 17.90891 16.48678 18.03056 17.71963 12.32748 11.78882 9.929072 11.31927 12.64543 11.5685 10.86378 14.32529 17.28631 17.74572 17.08748 16.90873 15.3218 14.87652 15.57612 15.72205 15.87119 15.72217 15.76832 16.80227 16.46172 17.64037 17.64002 12.19527 11.26126 10.91108 11.51357 11.88646 12.82152 12.50746 15.10742 17.22483 18.49776 18.38831 17.32627 15.58188 14.17714 15.13854 16.44323 16.22381 16.09768 16.18013 17.33267 16.986 16.6601 17.38706 12.38316 10.9315 10.43465 10.56535 12.23314 11.90101 12.91362 14.65029 16.51646 18.22181 17.65647 16.37604 14.34329 13.71848 14.16311 15.41569 16.0204 15.15731 15.41514 16.67949 17.00598 15.89455 16.97392 11.30577 10.28441 9.945932 11.39331 12.30649 11.96362 11.83533 14.81513 17.35564 18.33072 18.05184 15.06798 14.07956 13.20424 13.25025 14.4972 15.11539 14.80095 14.70875 16.30007 16.03745 14.93294 16.70602 11.03609 11.63719 10.21918 10.6167 10.88359 11.86974 11.941 14.54243 18.29357 19.38234 16.87861 14.88691 13.15115 12.30057 13.38792 13.84875 14.85546 14.83342 14.70834 15.97845 15.37833 14.04472 16.18783 13.34986 14.78248 13.79236 13.17295 12.78349 12.70567 12.45625 14.42082 17.43404 18.18635 15.59477 14.50266 12.80653 12.16918 12.35644 12.73297 13.97416 14.38635 13.72448 14.86592 14.04201 13.30526 16.08755 13.90898 15.20264 15.9369 14.62706 13.72583 13.84371 14.70597 16.07141 18.13611 18.26731 15.36589 14.14722 12.81018 11.74895 11.73215 12.83022 13.8598 14.30199 14.02788 15.60954 14.73503 13.21847 15.28059 12.65622 13.64794 16.40841 15.1159 12.92702 14.19901 14.66136 16.53231 18.85972 18.87691 15.47901 14.02315 13.04305 11.90804 12.02419 12.18788 13.65167 14.87863 14.52754 15.9854 15.23429 13.42042 14.61205 13.16586 14.09224 15.83176 14.90314 13.58085 14.20237 14.74656 16.52872 18.05439 17.30598 14.93832 14.26765 12.49032 11.86487 11.99516 12.17831 14.06437 14.65313 14.55127 15.61084 14.85131 13.26807 13.69388 13.4008 14.57262 15.16415 15.02138 13.99929 13.74122 14.89686 16.43497 18.12129 17.57994 14.38773 13.34021 11.77359 11.37652 10.77275 11.62928 13.2342 14.23693 14.04607 15.04497 14.55735 12.52344 13.15258 12.58941 13.8753 16.66035 16.01036 13.94624 12.86215 14.91205 15.55473 17.18862 16.32199 14.95177 13.18178 11.81485 11.68483 12.10907 10.99695 12.64363 13.92735 13.98247 14.74136 14.57911 14.06635 14.69018 12.09153 13.84327 16.73779 16.22157 14.56728 12.37056 15.10593 15.10421 16.23268 15.88102 14.39125 12.42256 11.36509 10.85059 10.98364 10.62551 11.97378 13.79792 13.98639 13.31582 13.83742 14.01882 14.74063 14.35417 15.46001 15.97281 15.97872 15.05301 13.271 14.85252 14.8182 15.14593 14.99852 13.87889 12.85231 11.08199 10.78992 11.17402 10.49343 12.2052 13.27493 13.57413 13.50568 12.8814 12.89545 14.14766 15.11954 16.42943 16.03817 15.8695 14.94205 13.81331 14.11605 13.90077 13.72665 14.46259 13.50304 12.15606 10.48165 10.17465 10.4161 9.912415 11.29775 13.10989 13.52075 12.40094 12.22526 13.01442 14.24785 15.51706 16.90478 15.31721 15.63563 14.91287 12.8936 13.76248 14.32526 14.25805 14.36927 12.66967 12.0761 10.97497 9.48582 10.20874 10.5375 11.10218 12.73337 12.90427 12.4544 12.51494 12.39871 13.89166 15.83766 17.44094 15.59742 15.76098 14.73724 13.33175 13.09907 14.17982 13.79805 13.84968 12.17967 12.07957 11.02122 10.35668 10.95256 10.26702 11.17187 12.12873 12.05996 12.1097 11.7091 12.38269 13.66632 16.28121 17.97894 15.37001 15.30069 15.23669 13.93175 13.33285 13.58994 12.95194 12.94088 12.26932 12.17642 10.4537 10.94146 11.22272 10.16105 10.75595 11.85875 11.60317 11.8685 11.6532 12.81746 14.03694 16.65678 18.48001 16.02887 15.72611 14.88948 13.75212 13.00821 13.84919 13.9075 12.9391 12.38781 11.60378 10.67275 10.77736 11.13959 10.14937 11.14159 12.06991 11.99633 12.57936 11.69493 12.77214 13.83402 16.88027 18.81418 16.32965 15.89062 14.08585 12.9283 13.01355 14.09655 14.04627 13.70805 12.55457 12.14791 10.23291 10.64731 10.54774 10.34701 11.31384 11.85837 11.31565 12.61369 11.56602 12.69893 13.17958 16.86315 18.90851 16.74496 16.61073 13.71159 11.98781 12.37382 13.89134 13.772 14.01257 12.72022 12.62209 10.90394 10.19925 10.34741 10.43047 10.72284 11.89819 11.36431 12.45117 11.00326 12.7707 13.43279 16.55088 18.7428 16.48301 16.17187 14.55713 13.0492 13.09207 14.58359 13.44237 13.92513 13.25501 12.62462 10.7068 10.42912 10.70771 10.98847 11.20761 12.1386 10.86133 11.76409 10.89257 12.65522 13.48968 16.31133 18.53433 16.33694 15.77417 14.38188 12.95522 13.08407 14.4475 12.69577 13.27632 12.01401 11.38529 10.35604 10.744 10.78147 10.85441 10.54302 12.20752 11.1479 11.46902 11.70803 13.0295 13.62829 16.08484 18.22621 16.04434 15.1363 12.58238 11.89639 12.57116 13.53181 14.12426 14.20648 11.83826 11.15889 9.9625 10.32529 9.984441 10.63607 11.00616 12.5833 11.28041 11.6917 11.89614 12.90713 13.29698 15.68179 17.81505 16.00374 14.72812 14.84708 11.26076 12.04008 13.00523 14.13205 13.28368 11.21361 10.097 9.955743 10.26499 9.792438 9.863858 11.07145 12.3472 10.51815 10.99274 11.61275 13.19388 13.72785 14.55198 16.86638 15.5845 14.5592 14.73209 12.26241 10.81983 11.97698 13.21972 12.68782 10.91807 10.4126 9.59472 10.19615 9.584566 9.555467 10.64191 12.16234 10.07995 11.50145 12.38194 12.66189 12.71277 13.01004 15.59743 15.64693 14.08796 13.8486 11.90227 10.5667 10.79841 12.75414 11.89225 9.598926 9.206168 9.479238 8.989665 8.048623 9.163903 10.12297 11.2002 10.10107 10.59673 10.9262 11.29577 11.6629 13.91573 16.00849 15.0316 13.62253 12.95412 9.966305 10.1017 9.991467 9.596074 9.605503 9.343888 9.190509 8.865524 8.973734 8.919617 9.209815 10.08192 10.85753 10.00404 9.867455 10.36516 11.38496 11.67881 14.8278 16.76171 14.70668 13.6729 13.04084 9.941384 9.693533 10.51062 10.44051 10.19218 9.282916 9.032 8.986729 8.863693 9.409104 9.42415 9.590022 10.41179 9.549519 9.795614 10.16903 11.44894 11.5452 14.85072 16.98533 15.18039 13.29803 13.33594 9.623359 9.158119 10.2534 10.32673 9.353215 9.035355 9.315903 9.19397 9.060982 9.5213 9.576943 9.395948 9.738444 9.638402 9.812303 10.30602 10.88667 10.86766 14.6904 17.03413 15.28008 14.86307 14.88218 11.42855 9.846802 11.10628 10.92814 10.19661 10.62403 11.59551 10.50513 9.933274 11.18404 11.79196 12.68107 11.0639 9.99734 11.25623 10.75933 12.35911 12.92669 14.66271 16.80819 14.93047 15.11656 14.37493 12.24518 9.898335 10.41227 10.94259 9.562234 9.82956 10.52575 10.91687 11.3688 12.16531 13.12481 13.59379 11.50523 10.77534 12.16117 11.03448 13.25059 13.33833 14.15415 16.37178 13.99285 14.13001 14.35129 12.60274 10.18616 9.21813 9.342664 9.430008 10.54196 10.54733 10.69073 12.74719 13.28319 14.68884 15.19119 12.57943 11.37738 12.86609 11.79551 14.11093 13.75384 13.90892 16.035 14.79413 14.31352 13.37496 11.89549 10.30609 9.863048 9.564677 9.050714 9.766609 9.916749 9.736766 12.76469 13.29292 14.07608 15.34341 12.62214 11.65098 12.8247 11.93356 14.02104 13.58228 13.60849 15.51042 14.56466 14.77384 14.10931 12.00589 9.922771 10.00272 9.233529 8.90524 9.197906 9.287741 9.224826 11.10517 11.75283 12.47408 14.07385 11.81659 10.66715 11.48033 10.96836 11.95531 11.53177 12.63871 14.4074 14.43942 15.18537 14.02158 12.20864 10.17488 10.41652 8.884479 8.93423 10.05001 9.872001 10.05358 11.18607 11.13514 11.16448 12.71593 10.94455 10.9008 11.7045 11.48672 11.77495 11.38987 9.470507 13.9183 15.38312 15.29352 14.31409 12.62442 10.19246 9.844234 9.015466 8.645416 9.272799 8.95722 9.29404 9.842471 10.79908 11.95937 12.56295 10.62304 10.97254 11.55685 10.80731 10.67443 10.93567 9.689436 12.1227 15.04778 14.65507 12.59609 11.3594 10.29826 9.403631 8.485927 8.846539 8.928617 8.97279 8.096455 9.521686 11.13479 12.4645 12.32434 10.56936 10.17078 10.82339 10.85006 11.1649 11.38804 10.98928 14.05137 14.64129 16.00715 14.09278 11.13883 9.941337 9.854771 8.722589 9.290672 8.857082 8.991954 8.21919 9.559203 12.24082 13.63578 12.84687 11.02113 10.59677 11.14553 10.55739 11.74764 11.36405 12.63155 15.67096 14.68544 16.10676 14.76892 11.35606 9.204973 8.561191 8.504937 9.011736 8.932889 8.941728 8.647584 9.663374 12.39362 13.74842 12.88115 11.69389 10.94999 12.21108 11.19174 12.30093 11.63438 12.10139 15.86091 14.87627 15.61644 14.75041 11.31224 8.924519 8.241544 8.472549 8.927956 8.740888 9.051448 8.190333 9.251281 12.88241 13.90231 12.65679 11.89317 11.16821 12.41968 11.02865 12.32125 11.54047 11.38513 15.89259 15.55978 16.49071 15.93176 11.26818 9.120329 8.472344 9.292308 9.625569 9.129047 9.180802 8.588961 11.19132 14.33207 15.09559 13.56647 11.99036 11.61518 12.64687 10.69325 12.63932 11.8825 11.33489 16.01806 16.14634 17.10612 17.0976 11.94706 10.30982 9.953162 10.28553 10.87142 10.28722 9.505128 9.044598 12.70718 15.12737 15.38648 14.23596 12.67216 11.409 11.88481 10.85025 11.92107 11.80873 11.93121 16.69381 17.38387 17.6749 17.98742 13.28621 11.70719 10.43649 10.91934 11.77147 11.88422 11.13052 11.38345 13.80934 14.99402 15.98011 14.9559 12.99995 11.91326 12.93166 10.28887 13.55714 13.66834 11.91258 16.81928 16.99542 18.31518 19.14895 14.40946 11.01381 11.08671 11.39375 13.21682 13.19212 12.36498 12.30863 14.04659 13.71266 15.38462 14.6618 12.61307 12.04058 12.94022 10.91476 13.20159 13.73922 11.46789 17.38041 17.82477 18.2752 19.65061 15.74574 11.42097 11.61401 12.88716 14.96064 15.02348 12.79885 12.33007 13.6574 13.31771 14.41018 14.14105 12.70052 11.94269 13.00976 10.96539 14.06782 14.93854 10.82074 17.51527 17.82471 18.72139 20.24971 16.65067 13.19277 11.47689 13.75297 16.15981 15.89948 12.82615 11.78095 12.68962 13.03443 13.99312 14.44622 12.8687 12.09715 12.6253 11.04033 14.82887 15.41104 9.789128 17.60623 17.95166 19.12147 20.36291 16.45957 14.5175 11.95895 14.00584 15.58451 15.58284 13.09798 11.42349 12.38721 12.11636 14.10925 15.14098 13.66024 12.47174 12.31593 11.41416 15.35977 16.09952 10.03751 16.87819 17.14559 18.82435 19.69844 15.54911 14.925 13.47285 13.4415 14.02402 13.91976 12.55425 11.28404 11.29449 11.12666 12.90026 14.52994 14.08993 12.81467 12.58953 11.19166 14.11535 15.23785 10.93798 15.34559 15.48075 18.89332 19.13994 15.17251 14.3534 14.04348 13.22518 13.32802 12.83179 11.63252 10.8536 11.23855 11.16474 11.8378 13.7653 13.51799 12.46745 12.35123 10.79845 14.09694 15.23058 11.39907 15.94585 15.80858 18.99041 19.07972 14.78049 14.1376 14.13164 12.62071 13.95744 12.93874 11.53029 10.4269 11.58948 11.19517 11.35314 12.57921 12.77587 11.52973 10.72114 11.27394 14.35466 15.65102 12.50065 16.98081 16.2958 18.53826 18.03814 14.84136 14.63556 13.97874 13.23756 13.85454 13.35822 12.12458 10.75648 11.73495 10.99577 10.73339 12.26947 13.05336 11.80032 11.86604 11.52577 14.2759 16.10515 14.11917 17.50495 16.44348 18.44194 18.71619 15.23897 15.50647 14.00227 12.22151 13.66027 13.43431 11.87765 10.321 11.40836 10.86816 10.51086 12.05384 13.00603 11.8335 11.91356 11.91522 14.54532 16.75152 14.99379 17.92895 16.8975 18.70519 18.95995 15.73521 15.49823 12.87329 13.83215 13.62185 13.06669 12.05937 10.42773 10.73961 11.01464 10.88707 11.64818 12.58473 11.62818 11.58135 11.51648 14.55052 16.08885 15.54145 17.85107 16.98327 18.49837 17.73919 15.18074 14.75038 12.77507 14.06172 13.54413 12.30926 11.52931 10.36564 11.26507 11.33629 10.336 12.06124 12.62648 11.26266 11.69004 11.93004 14.61818 15.63297 16.0619 17.99921 16.89255 18.13565 17.83411 15.88005 14.93022 13.40796 14.59884 14.0794 12.40723 11.15436 10.18998 10.83631 11.137 10.82108 12.08101 13.16273 11.88929 11.08195 13.06093 14.60555 15.1582 16.41592 18.74591 17.24427 17.45222 17.14775 15.69397 14.63761 13.72616 14.99289 14.96222 12.8571 11.36845 10.90592 10.93947 10.72949 10.99991 12.06396 12.11599 11.73193 12.9482 13.76328 14.24961 14.51857 16.59169 18.33644 16.6729 17.92939 17.99472 15.11923 13.68678 12.95239 14.18037 14.98073 13.72894 12.48612 11.10576 11.19653 10.8321 11.57918 12.45367 12.50688 11.21697 13.96683 14.07828 13.39284 13.05171 16.37931 18.53983 17.11295 17.0422 17.68007 15.11545 13.4979 12.7253 12.83473 13.30683 14.44711 13.53261 11.2399 11.29604 10.66569 11.51261 12.52057 12.61519 11.1287 14.42613 14.21188 12.91073 13.62521 15.77711 16.81826 15.82284 16.26417 14.77699 13.92578 12.86666 12.48366 12.62949 12.08785 13.24057 12.46911 10.74334 10.64687 10.51021 10.52875 12.20348 12.29009 10.30058 13.55652 13.26817 13.30325 14.35986 15.82015 17.46225 15.50791 15.47983 15.53145 14.01977 13.48505 11.83372 11.23159 11.60364 11.24516 11.02851 9.994411 10.127 9.874244 9.952956 11.45186 11.57752 10.71201 11.31057 11.925 12.24183 13.13455 15.76488 17.33266 15.47503 15.67266 14.76409 13.55282 13.16781 10.86405 10.00527 10.30678 10.84636 10.38855 9.692888 10.62687 10.82284 10.76016 11.56705 11.6752 10.60772 11.25967 11.79259 12.14699 12.2975 15.79346 17.73031 15.68137 14.88974 13.31264 11.70068 10.75016 9.699461 11.59397 11.09019 10.58869 9.898376 8.929638 9.302467 9.637378 10.49889 11.22649 10.7973 10.0415 11.52228 10.99211 11.29036 11.60892 15.62056 17.43279 15.06023 14.50031 13.94001 11.11427 10.53508 10.24727 10.84226 10.2417 9.97341 9.786078 8.522814 8.529009 8.403295 8.864924 9.860689 10.12548 10.1109 10.64103 10.51032 10.91088 10.99742 14.92246 17.0135 15.04857 14.46992 14.52418 12.18941 11.24207 11.29555 12.0192 13.37018 13.99349 13.40953 12.65679 13.28639 14.09664 14.8326 14.6762 13.23665 11.35561 12.54946 14.12629 15.38962 14.67778 14.08548 16.16105 14.25179 13.72728 14.2951 12.56719 11.60147 10.79406 11.7847 13.46562 14.78914 15.1487 13.70664 13.32854 14.55988 16.36461 17.04605 15.91949 14.81793 16.99095 18.20212 19.37614 18.60077 13.56568 15.41561 13.65116 13.80278 12.35432 10.98944 10.19834 9.714845 10.88012 12.79503 15.31259 16.04332 15.07261 13.3139 16.37029 18.55497 19.72721 18.21986 16.88817 18.66231 19.42877 21.17449 21.34429 12.81052 14.82067 12.89596 12.89064 12.7278 9.884626 10.07492 10.31998 11.56146 13.61393 16.51963 16.62613 15.85953 13.70052 15.65685 20.09129 21.61243 19.28339 18.15581 19.5183 20.06223 21.13614 22.15731 12.4148 13.93226 11.91046 12.1541 12.28745 11.01894 10.5866 10.27591 12.31247 14.79986 17.28344 17.50844 16.46629 14.32873 15.63348 20.89158 21.659 18.84053 18.39215 19.79963 20.31273 21.56329 22.12888 12.91297 14.79987 12.71113 13.29154 13.44041 11.56215 10.49496 10.6033 12.03684 15.29325 17.49444 18.31451 16.88695 15.08641 17.40228 20.39707 21.17206 19.49123 17.8341 19.26415 20.69028 21.98025 21.82807 13.12175 14.64588 12.15094 11.35538 12.11017 10.95849 11.28366 11.61484 12.85101 16.09893 18.0477 18.62724 16.99242 15.1852 17.51782 19.87419 20.87705 19.48903 17.96088 19.17698 20.07501 21.74238 22.1084 13.00411 14.90964 12.85213 12.4642 12.19896 10.9285 11.4324 11.96293 13.98125 16.61734 18.89468 19.34385 16.26028 15.6907 16.13703 19.2197 20.6384 19.75793 18.03179 18.44206 20.21319 21.34424 21.91418 12.53915 14.56936 12.39721 13.01271 12.77172 11.97516 11.71099 11.24299 14.61106 16.86008 19.35301 19.43951 16.80698 15.8419 16.63168 19.33833 20.47225 19.18408 17.29919 18.15383 19.49329 20.5814 20.88459 12.15284 13.47757 10.60758 12.20281 13.0343 11.11187 10.97446 10.88111 14.17981 17.2116 19.27656 19.46944 16.21806 14.89002 15.36739 17.92939 19.41214 17.94695 16.58801 16.62714 18.35245 19.04712 19.02948 11.57865 13.99112 12.93595 11.18491 10.64367 10.56507 10.97282 12.65517 14.05695 15.92091 18.14322 18.23843 15.92175 14.87526 15.68978 16.53125 18.24236 17.28429 16.56872 15.94291 16.28687 17.53417 17.20242 11.28529 12.6209 11.65753 11.60241 11.58626 10.83581 10.27027 12.12041 14.267 15.48161 18.20242 17.39253 15.21907 14.75703 15.08057 16.2598 17.26633 17.07322 16.03636 15.15166 15.24807 16.5594 16.19338 10.91567 13.44223 11.93005 10.71006 11.31781 11.7807 10.22369 12.09495 13.98265 15.85598 16.988 16.82117 15.11764 13.72713 14.96652 15.93681 17.34565 16.43155 15.34467 14.63535 14.80754 16.85585 15.56012 11.37683 12.73687 10.39089 9.336987 9.831561 11.17227 10.51462 11.394 13.52753 17.06892 18.22289 16.58073 14.50473 13.4536 14.32212 15.69642 17.59365 16.24478 14.84533 14.05617 14.99095 16.48585 15.65335 11.15164 13.128 10.98207 9.10566 10.39393 10.70634 10.84463 11.06166 13.15317 16.16613 17.48376 16.13078 14.46833 12.60861 13.22436 15.39284 16.83496 15.80455 14.54673 13.42426 14.11045 16.32096 15.15128 11.15148 13.08558 11.24186 10.75418 11.27332 10.83193 10.16917 10.71663 12.71503 15.8612 16.86666 15.34324 13.83714 12.93292 12.91148 14.20864 16.26399 15.44005 14.26241 13.12186 13.5547 15.73553 15.21248 10.32435 11.80502 10.71903 10.12998 9.243139 10.32276 10.51204 9.885305 13.37798 15.24079 15.56827 14.59323 13.25549 12.08573 12.08292 13.83259 15.49082 14.31401 13.56349 12.58398 12.93209 15.15023 14.39397 9.55196 13.14198 12.09491 11.57915 11.7868 10.55393 9.688849 10.1536 12.66342 15.51936 15.60778 14.23114 13.59677 11.5554 12.35998 13.28365 14.88144 13.88197 13.16487 12.75849 12.51151 14.26958 14.14925 11.14226 15.27234 14.74488 14.24864 14.20611 12.25802 11.94632 12.10342 13.43625 15.97755 15.82204 14.68259 12.32215 10.68163 11.67134 13.07826 14.39713 13.78414 12.79398 12.32595 12.68034 13.86888 14.63672 11.82192 16.13304 15.37651 16.57404 16.01068 12.65684 12.84768 13.69928 14.84385 16.28752 15.21064 13.4215 11.93544 10.11553 10.96781 12.73654 13.93202 13.7597 12.7366 13.53805 13.78219 14.34586 15.65966 11.16597 15.60295 14.91919 17.65105 17.25035 13.94595 13.03636 13.82953 15.81298 16.99026 16.38386 13.44202 10.67358 10.54342 11.52007 12.54199 15.2073 14.85921 13.04932 13.6851 13.8579 15.4532 16.68387 10.51662 15.43471 14.99521 18.16862 17.72067 15.69889 14.12805 14.29307 16.52756 17.99657 16.64942 14.49547 11.61017 10.99339 11.64379 12.93506 15.5309 15.33103 13.2612 14.26317 14.55778 16.36224 17.4065 11.90673 16.09601 15.16525 18.22427 17.79523 16.65013 14.95471 14.57647 17.00873 18.48756 16.99238 14.55247 11.84007 11.13602 12.00641 12.06635 14.78719 14.60945 13.60264 14.37275 14.25254 15.76529 16.61269 11.77753 15.94984 15.05677 17.97174 17.373 17.41905 15.6169 14.73355 17.46013 18.81142 17.14954 15.49692 12.20508 11.44368 12.23865 12.73304 15.18181 14.84058 13.51544 14.6217 13.58304 15.94587 16.794 10.41407 15.72303 15.14866 17.70807 17.07916 17.71496 15.88798 14.64032 17.55777 18.87132 17.8488 15.62309 12.12702 11.63624 12.23076 13.35091 14.845 14.49619 13.87168 14.96588 14.34432 16.30333 17.20194 11.354 16.18204 15.44579 17.66172 16.96994 17.44448 15.66464 14.72198 17.39568 18.71137 18.22394 15.33202 11.91729 11.85658 12.49095 13.32615 14.09961 14.23158 14.58506 15.50219 16.31929 16.47316 17.44572 11.67818 16.44463 15.64772 17.72272 16.90357 16.48343 15.1468 14.66261 17.37626 18.67665 18.43763 16.17672 12.68573 12.12047 12.56644 13.53683 15.69811 15.11192 15.10006 15.99792 16.72847 15.30137 16.12518 11.81452 16.51302 15.8351 18.05065 17.12857 14.78708 14.79863 14.54577 17.14968 18.40389 18.33661 16.81234 12.45416 12.26822 13.33935 13.42922 16.02875 15.44887 14.45614 16.00752 17.02212 15.07159 15.84839 11.66775 16.09326 15.45326 18.56066 17.73905 16.56577 15.80819 14.98165 16.93577 18.54793 18.7565 16.84025 13.44262 11.95572 12.87634 13.43538 15.80291 15.6723 14.43189 16.38626 16.87126 15.30465 16.12741 11.18154 15.3121 14.98711 18.80246 18.00036 17.79539 16.50552 15.6597 16.54539 18.6693 18.88139 16.73647 13.84423 12.21505 12.68858 12.8891 14.96932 14.98377 14.47017 15.99248 16.69073 16.01393 17.04851 11.39253 14.84143 14.70809 18.75023 17.97756 18.1698 16.63218 15.90916 15.77523 18.6932 18.87343 16.30272 14.07881 12.17943 12.72991 13.99461 15.09284 14.90023 14.86968 15.68508 16.95284 15.82605 17.11721 11.86377 15.31133 14.59444 18.38207 17.6422 17.60731 16.2254 15.42659 15.86426 17.45585 17.54583 14.96311 13.32989 12.32241 12.82136 13.80614 16.04843 15.70225 14.60214 15.79691 16.55345 14.48477 16.21475 11.73533 15.70459 14.84644 17.80892 16.99964 15.85337 15.77551 15.02913 15.56236 17.03756 17.23155 14.80542 13.2883 11.4158 12.61335 13.34564 15.46394 15.25104 14.61511 15.47291 15.86379 15.43297 16.33346 10.81638 15.52154 14.9054 17.31289 16.38354 15.1073 15.92739 15.73638 16.55172 18.13293 18.54304 15.54773 13.22721 12.31508 13.16266 14.46879 16.11985 15.48509 14.86392 14.97309 15.37611 15.07204 15.87638 10.26267 15.25113 14.67625 17.21563 16.31719 14.77018 14.92522 15.68053 17.32211 18.43587 17.91074 15.57454 13.49049 12.60371 13.12548 14.11297 15.84021 15.45053 14.63433 14.96083 15.49248 13.76896 15.98103 10.69819 14.90186 14.28961 17.07143 16.24204 13.46402 14.20674 15.63925 17.09035 18.04039 17.88895 15.37756 12.4007 12.11112 12.55157 12.96375 15.69617 15.59222 14.15425 15.03544 15.54571 13.44852 15.65409 9.915021 13.82648 13.51551 16.30905 15.34114 15.36788 15.25857 15.57581 16.88137 17.62993 16.70799 14.8589 12.48502 11.65991 12.48844 12.89608 15.70182 15.3114 14.08729 15.36026 15.73317 12.51652 15.22122 8.68051 12.45413 12.77622 15.34519 14.32071 14.90527 13.81296 14.36697 15.78108 17.00771 16.51527 13.94231 11.84495 11.75392 12.35656 13.10109 14.77411 14.72279 13.45488 14.19114 14.58668 12.4133 15.44579 10.05589 13.40399 13.02372 15.95843 15.3619 14.07744 14.53119 14.84178 15.96589 16.57776 15.83888 13.69824 11.78194 11.49591 11.9167 13.30375 14.69968 14.48295 12.85517 14.20968 14.40717 12.00698 13.85596 11.27062 14.20996 13.00546 15.81915 15.0768 14.00317 14.15812 14.63979 15.93456 16.13581 15.80585 14.0422 10.93639 11.04755 11.28759 13.27676 14.53805 14.24715 12.69541 13.41502 13.21583 11.7954 14.09292 11.82292 14.00475 12.70146 14.15521 13.96183 13.86355 13.82776 14.55097 15.977 16.62114 15.52749 14.43003 11.57255 11.82603 11.46633 12.81295 13.52481 13.20844 12.48258 12.9837 12.70388 12.01538 14.10332 11.81733 14.02889 12.67105 14.56858 13.83397 13.15577 12.52465 13.75595 15.65288 15.53403 15.14229 13.78594 11.95139 10.92552 12.43795 12.72144 13.77396 13.37051 12.03247 13.05484 13.05454 12.07504 13.45452 11.53573 14.69543 13.47587 14.54975 14.09588 12.23716 11.75021 12.82979 16.3925 16.57847 15.83274 15.41968 12.53094 12.0738 12.46284 13.14491 13.65205 13.70883 12.48045 13.69684 14.24071 12.90326 13.78031 10.46279 13.28604 12.97831 14.62308 13.95662 12.26015 12.11266 13.03825 15.73407 15.80908 16.49609 15.14229 11.56523 11.61488 11.99993 13.00464 14.1577 13.95174 12.51486 14.32073 14.42474 13.37241 14.48748 10.48366 14.08517 13.39815 12.98214 12.39788 11.79398 12.84884 13.57857 15.40684 15.60652 15.99256 14.35739 12.09316 12.1796 13.10014 13.46264 14.51066 14.02861 12.81611 14.63739 14.12812 13.86828 14.78857 10.19182 14.69601 13.93462 12.37111 11.73293 10.65019 12.18164 13.14647 14.66128 15.14137 15.29343 13.7568 11.9698 12.07825 12.39925 13.19032 14.63404 14.42319 13.39776 15.18882 14.68679 13.48536 15.13381 10.34476 14.25978 13.3268 12.39499 12.02569 10.45536 10.55758 11.70175 15.12028 16.20647 14.50963 12.94513 11.49872 11.71179 12.57724 12.75515 13.61092 13.75198 13.41445 15.13885 14.47829 14.33477 15.76451 10.20487 12.92972 12.66008 12.42735 11.86889 10.36294 10.88357 12.17473 14.84048 16.0851 14.19029 12.64169 11.7309 11.68961 12.55493 12.70489 13.73792 13.65674 13.2528 14.73102 13.98869 14.62711 16.16679 9.423117 12.70624 12.09342 10.86123 10.24333 9.513165 11.43117 11.95184 14.92405 16.06582 14.44456 13.55055 11.02903 11.31061 12.30381 12.54599 13.94664 13.53971 13.29417 14.64221 13.89266 14.74018 16.82738 9.589171 12.47112 11.4502 9.131975 10.2197 10.17758 11.90142 12.39148 15.51737 16.71535 15.28426 13.4031 11.43478 11.36541 12.49403 13.41569 14.58072 13.76381 13.98231 14.93766 14.71383 14.92337 16.24941 9.503296 10.60735 9.271545 9.716817 9.667707 10.52781 11.40006 11.39293 14.60591 15.02798 15.03264 13.64719 11.30165 10.74731 12.65038 13.62129 14.64687 13.53882 15.08017 15.38536 14.1648 14.99333 16.10574 9.115908 11.43826 10.47298 10.14771 9.880108 9.726262 10.82772 12.05128 14.10969 15.54203 15.91383 13.69349 11.85291 11.131 13.34072 14.18404 15.38566 14.57817 14.72091 15.19623 14.41386 14.31567 15.83257 9.310917 10.28504 9.811528 10.01983 10.05451 9.4747 10.45637 11.62435 13.92147 16.01029 15.57332 13.24274 11.89735 11.36156 13.09891 14.07911 15.26106 14.44157 15.20087 15.08729 14.25182 14.66974 15.79354 9.030734 10.77806 10.31404 10.89988 11.18181 10.48961 10.15753 11.69851 14.42295 15.29466 14.48458 12.67693 11.36603 10.84135 11.80535 13.1063 15.03863 14.38514 14.50504 14.37171 13.37179 14.37903 15.7146 7.50856 11.28577 10.72007 10.24735 10.17675 10.65663 10.4188 11.49671 14.89423 16.14469 14.11847 12.56653 11.28391 10.65832 11.76379 12.46559 14.1188 13.54819 13.30948 13.31488 13.49415 14.57029 15.60327 8.540401 11.55971 10.55634 10.50483 10.84564 11.33433 10.85704 11.34962 13.89402 15.64289 14.49759 12.96604 10.80758 9.884405 10.34586 11.19268 13.79956 13.10055 13.12975 13.08347 12.67242 13.66006 14.28579 11.08979 14.00895 13.28101 13.3758 13.54885 12.20103 11.48327 11.56215 13.08175 15.66193 14.28371 12.17407 9.616703 9.735795 10.51737 10.66526 12.92028 12.44681 12.94642 12.86102 11.83186 12.5984 13.619 13.14398 15.67154 15.34065 16.24163 15.0646 12.54676 11.68441 12.30696 13.41859 15.11965 13.7802 11.35566 9.2933 9.63155 9.780502 10.87477 12.77262 12.19879 12.55715 12.45354 11.55077 12.7023 13.38533 14.07658 16.64854 16.01492 17.56435 15.44176 13.57488 11.04171 12.65898 13.55481 14.86006 13.82938 10.95063 9.030316 9.329757 10.07974 11.01514 14.26132 13.92831 12.94692 12.58781 11.56843 13.6175 14.11914 14.75746 16.99999 16.77552 18.02952 15.90656 14.6823 12.81055 14.08961 14.8099 15.94903 14.67507 12.65691 10.4475 10.15641 10.20949 12.54788 15.05997 14.94959 15.0851 14.83846 12.45193 15.8906 16.3022 15.11706 17.16695 16.8549 17.89547 16.15163 14.86321 13.19364 14.13913 14.60327 15.88921 14.64402 11.80295 9.991564 9.918747 10.29794 12.53781 15.5761 15.41474 14.87424 14.64059 12.25671 15.93182 16.2683 15.40835 17.45925 16.58469 16.7639 16.27665 14.75572 13.4018 13.85402 13.12921 15.10079 14.71053 11.99744 9.913205 9.705381 10.4648 12.13035 15.2068 15.025 13.92012 13.05841 12.5278 16.01011 16.19179 15.45827 17.28377 16.69241 16.92484 16.34339 14.48242 13.334 13.81861 13.36756 14.88102 14.33365 11.80426 9.697133 9.240011 10.16598 11.92516 14.61208 14.43869 14.29321 13.34631 12.60551 16.59318 16.53483 15.13229 16.73378 16.89245 17.1393 17.00265 14.96519 13.72409 14.02927 13.25723 15.83806 14.40103 12.19008 10.30029 9.71996 9.842927 12.35917 14.15221 13.89012 14.0526 13.6017 11.93211 16.53617 16.72011 14.57705 15.6379 16.80176 16.86314 16.66628 14.47865 13.58029 14.06467 13.77963 16.02653 14.70159 12.60434 10.41194 10.06278 10.46712 12.41631 14.66149 14.67236 13.84786 12.99362 12.37743 16.0895 16.24062 14.77465 16.17302 17.21569 17.31233 15.77169 13.20695 14.42118 14.81845 14.40012 16.4256 15.06712 12.46396 10.4278 10.54279 11.23261 13.11649 15.14829 15.03464 14.55053 13.6049 12.95183 16.86971 16.66895 15.05606 16.52065 17.57998 17.69038 16.2915 14.25601 14.84489 15.36414 15.11178 16.8064 15.81776 13.49685 11.06283 10.37466 11.31837 13.62332 15.70944 15.07266 14.53792 14.15806 14.11397 17.4218 17.03832 14.91461 16.54216 17.72679 17.76228 16.31701 14.88375 14.68025 15.63748 16.55472 17.25992 17.16825 15.38784 12.14931 11.18112 11.89017 14.01893 16.31654 15.77574 15.18395 14.93204 14.24931 17.65414 17.32909 14.06235 15.76193 17.18796 17.04869 16.16309 15.03378 14.50389 15.27548 16.01657 17.05204 16.83701 15.13547 11.94728 10.58079 11.4934 13.36317 15.81689 15.14827 14.4666 14.55218 13.48098 17.22405 16.73607 12.20449 13.63824 16.85458 16.60645 16.1426 16.12964 15.33291 15.36466 16.87278 18.04861 17.6068 15.85586 12.63215 11.99263 12.60324 14.04203 16.81243 16.22995 15.30362 15.6595 14.4412 17.11238 17.13072 10.72764 13.3548 16.83893 16.19029 15.82427 16.1692 15.66567 15.07302 15.77989 16.54188 16.30075 15.60935 12.34325 10.73788 11.86701 13.85012 16.31892 15.11082 14.34861 14.96774 14.47254 14.20635 15.01912 11.60129 14.09942 16.75742 16.20039 15.56324 15.11675 15.08574 14.86573 15.50838 17.15246 16.86691 15.52252 12.93029 10.73168 11.6597 14.13603 16.52929 15.7967 14.49399 14.30547 13.43089 14.71824 14.45458 14.02859 15.28391 15.8077 15.34497 15.03183 15.79032 16.02132 15.8215 15.79886 17.51942 17.64467 15.42086 12.91273 10.42257 12.27133 14.28747 16.08209 15.12793 13.71037 14.9558 14.61221 14.93433 14.82792 14.18848 15.49555 16.91608 15.82519 14.52658 13.71498 16.10671 15.94508 15.64377 17.88175 17.91087 15.55968 12.45656 10.9743 12.02333 13.80416 15.67876 14.38375 13.71993 15.67794 15.32651 14.47271 14.63666 12.46225 13.96751 15.86773 14.64494 14.40544 14.4847 15.3736 16.16685 15.92646 17.85421 18.09699 16.27834 12.37715 10.08867 11.90742 13.48527 15.4419 14.10502 13.62834 14.96597 14.83753 15.32119 15.06888 13.05211 14.65883 16.07732 15.72431 14.58461 14.83052 15.30428 15.05263 15.02916 16.23183 15.43935 14.29991 11.75905 11.07148 12.31495 13.43882 14.98901 13.66362 12.9674 14.51913 14.48279 14.95528 14.8023 12.55515 14.89801 14.75364 14.68671 14.14907 14.13834 14.59004 13.6544 13.79198 16.03756 16.11797 13.08031 11.24561 10.83997 11.88435 12.2136 13.93883 13.77705 12.87251 14.5708 14.71351 14.24566 14.39286 13.83093 15.56555 14.57585 14.22723 13.8579 13.36604 14.29341 13.54445 13.8807 14.93316 14.51684 12.76485 10.79458 10.58632 11.6082 12.35924 13.70661 13.07612 12.48223 12.69072 12.71655 12.41708 13.33185 14.18465 15.79808 14.80991 14.02056 12.90899 12.66223 13.70633 13.82998 14.50648 14.96112 15.03471 13.67727 10.52017 10.59638 11.55017 11.89342 12.99354 12.42688 11.95904 12.05783 11.865 12.08287 12.86125 13.25803 14.87615 13.40272 12.26935 12.22413 11.50442 12.41747 13.64918 15.23524 15.79496 15.65018 14.92247 10.86561 10.38056 10.77693 10.56645 12.19267 12.05079 11.84969 12.24822 11.36017 11.14598 12.25312 12.45111 13.44244 13.22482 12.22398 12.6735 12.62569 12.88445 12.80736 13.84655 14.60308 14.62763 13.62638 10.40659 11.13378 10.61906 9.895057 11.55708 10.91639 10.84196 11.58675 11.38106 11.41171 12.38584 11.51846 12.357 13.54436 12.86645 11.85491 11.5113 12.90373 11.86775 12.45533 13.17408 13.00485 11.74634 9.947218 9.551273 9.567058 9.890096 11.33025 11.05918 10.6337 10.56511 10.17946 10.49385 10.70985 10.98355 12.91067 13.64736 13.10762 10.84069 10.44838 11.49005 13.12592 12.14138 12.09276 13.07966 12.63638 9.730008 9.848679 9.347866 9.414342 10.63352 10.80758 10.35773 10.48653 10.42719 11.00619 10.87458 11.5681 13.21478 13.99549 13.15111 9.779534 10.84289 11.58694 12.34813 12.21469 12.28861 12.12051 10.8032 10.08394 10.18741 9.829264 9.272332 10.70571 10.90198 10.80318 10.46099 11.22602 10.77159 11.26807 10.92434 12.3015 13.37657 11.97633 9.846909 10.4243 11.08952 11.22303 10.78325 12.41337 12.66613 11.84448 9.250697 9.51819 9.804947 9.046823 10.62793 10.31114 10.24323 10.33592 10.83164 10.2066 10.32049 10.66577 12.14629 11.68034 9.369942 10.3728 9.903213 10.77546 11.68394 11.14858 12.63394 12.94571 11.37593 10.00287 9.558322 9.845166 10.15729 10.41532 9.908718 9.831599 10.41129 10.63024 10.63221 10.3509 11.6184 13.30724 11.55282 10.44678 10.41798 10.1706 10.90822 10.41916 10.55029 11.9752 13.67633 11.79162 10.79402 9.887626 10.8025 10.48727 10.37634 10.34983 10.57088 10.24781 10.26391 11.38719 11.21457 12.47586 13.6613 11.17755 10.26591 9.585545 8.900165 11.20114 11.92466 11.11244 11.51987 12.53722 10.63915 9.778065 10.18182 10.7475 10.43095 11.06562 10.47551 9.800613 9.590487 10.01961 10.74588 10.42597 10.77701 12.82747 11.43204 10.35398 8.763439 9.405526 10.82308 10.63848 11.23412 12.39658 12.69621 11.6574 9.802265 10.72791 10.38412 9.456212 10.21749 10.77777 10.52131 10.53893 10.67069 11.10977 11.42564 11.11245 11.89655 11.72092 11.20401 9.289854 9.801051 10.75733 10.49686 11.86391 12.7017 13.00109 11.37016 10.12052 10.20385 9.899943 10.12168 10.17335 10.37608 10.25884 10.2047 10.5204 11.22245 11.59654 10.07293 9.634727 11.54807 11.43805 9.092267 9.683016 10.62169 11.24899 11.31559 11.98399 12.95545 12.45842 10.71746 10.80228 11.2789 9.754478 10.40236 10.25889 10.37339 9.958531 10.25048 11.00226 11.04672 10.42046 11.45978 11.63636 10.63461 9.173406 8.947865 9.959992 9.868871 11.08009 11.51371 12.75934 12.10706 11.59692 10.57697 11.32946 10.17161 10.1469 10.40671 10.2813 10.1093 10.52484 11.39623 11.14704 10.24291 11.15639 10.16661 9.884758 9.216879 9.206462 10.319 10.26303 10.83201 12.79486 13.33239 11.75389 10.45811 9.76089 10.24667 9.601921 10.60552 10.51551 10.36004 10.27134 10.3252 11.17595 10.70015 9.422491 10.00307 9.304786 9.541505 9.374505 9.497077 9.545082 9.764844 10.62842 12.44954 12.87034 11.195 9.428076 10.17063 10.55802 9.774949 10.74514 10.18642 10.23282 10.14036 10.41611 10.48228 10.65022 9.431662 9.925019 10.80831 9.614099 8.896067 8.509177 8.498697 8.813649 10.72018 11.46818 11.79037 10.94821 10.24577 10.29312 10.4467 10.298 11.07519 10.74677 10.3395 10.43149 10.75678 12.64705 11.43539 9.448807 10.96071 9.576197 7.308518 8.883255 8.301652 8.766844 8.846759 10.22622 11.76619 12.58748 11.67644 10.72528 9.9915 10.21584 10.17676 11.38863 11.19318 9.839796 10.4516 11.10404 13.23044 11.87121 10.62994 11.5706 10.67056 9.265289 10.66641 8.995152 7.84528 9.58221 9.973509 10.98804 12.24823 11.57158 10.72447 10.14804 9.541183 9.675903 11.06965 10.92531 10.45405 11.09323 10.41595 11.13436 11.58708 10.39545 11.44841 10.55975 9.705544 10.74701 9.747647 8.344221 10.04484 10.6118 11.2215 12.51557 12.40113 10.53294 10.54167 10.73098 10.17531 11.36208 11.10819 10.5466 10.93015 10.72956 11.21366 11.42109 9.808684 10.54995 8.585596 8.609066 9.104267 8.886292 8.315665 9.341417 10.22613 11.00258 12.79302 12.32948 11.03078 10.42751 10.86653 10.40495 11.54998 10.99841 10.25156 10.56426 10.5004 11.59432 11.25886 9.783687 9.554473 9.224267 8.305874 9.829804 8.624431 9.106644 9.878937 9.975676 11.34404 12.81888 12.35782 11.02464 10.09095 10.79956 10.69735 11.30436 10.86825 10.91094 10.57113 10.4626 11.75406 11.67169 9.964293 8.91133 9.597994 8.38109 10.30375 10.12096 9.371438 9.138732 10.23402 11.95144 12.71362 11.4016 10.57952 10.13566 10.54746 10.2636 10.74369 10.67116 10.78272 10.88782 11.01974 11.17345 11.2694 7.987907 8.382757 9.251793 8.551911 8.960312 9.169497 9.091488 10.20918 11.97596 10.86922 12.52002 12.28877 10.51484 10.44818 10.56632 10.83528 10.84797 10.92687 10.48957 10.72594 10.87492 11.48538 11.44997 9.208866 8.503493 9.972482 9.071673 9.462955 8.664878 7.662143 9.897245 10.64185 10.91716 11.13872 12.12932 11.36929 11.34245 11.2402 10.83909 11.03287 10.97415 10.68303 10.55697 10.5056 11.69601 11.68266 9.830456 7.644547 9.789823 9.708093 10.68528 10.30543 9.51989 9.725322 10.94882 11.60964 13.0219 12.9686 12.24573 11.09353 11.58634 11.25884 10.88388 10.70734 11.0613 10.88753 10.72593 12.06754 11.55765 10.1434 9.600281 9.03609 9.28277 9.389798 9.782507 9.522714 9.155346 10.51925 11.83723 12.88527 13.05917 12.5973 11.04044 12.4058 11.76693 11.41435 11.29793 11.33523 11.57119 11.21824 12.67894 11.60467 9.044415 9.35461 8.125829 8.155436 10.21073 9.420408 8.485256 9.519516 10.80159 11.03508 12.98993 12.86469 12.11976 11.60614 11.22908 11.30737 11.26812 11.07872 11.49184 12.23885 12.01657 12.81706 11.95831 9.557627 10.25238 8.452591 8.784152 10.9992 9.823544 9.510536 10.38744 11.27521 11.65287 13.02484 12.76013 11.33446 11.90731 11.69084 11.35221 11.25088 11.1325 11.48025 11.96735 11.96839 12.37707 11.87469 10.23095 9.161502 8.99103 8.923839 9.805343 9.837078 10.10092 9.621623 10.84666 11.88772 13.02984 13.09626 11.90776 11.65839 11.98773 11.63274 11.56222 10.86827 11.27272 11.77922 11.91178 12.68476 12.05236 8.874165 7.809851 8.695865 8.223797 8.763299 9.566321 8.770155 9.008782 11.19149 11.83618 13.52786 13.19089 11.91928 11.96163 12.16576 11.49836 11.79749 10.94192 10.88142 11.00608 11.66361 12.51995 11.84705 8.437733 8.480018 7.988172 8.590461 9.420288 9.875575 9.504238 9.388609 10.90206 11.65753 13.35867 13.6816 12.48646 11.95356 12.16133 11.43572 11.42155 11.1403 10.60003 11.26259 11.62654 12.52154 11.82845 9.964341 8.923758 9.201259 9.687395 9.499485 9.23505 8.127786 8.023572 10.40248 11.75716 12.92915 12.92148 11.44932 11.59385 12.10262 10.90831 11.27934 11.05236 10.57544 10.54616 11.69068 12.66987 12.08684 7.982019 9.21278 8.003357 9.466326 10.96768 9.979166 8.679527 8.800684 10.64961 10.21235 12.66046 12.89555 12.06681 11.04834 11.27791 11.41866 11.11113 10.78568 10.56767 10.6112 11.04461 12.21314 11.62118 8.391383 9.194236 9.299546 9.597569 11.07862 9.571204 8.833894 8.325615 10.67207 11.36724 11.90812 12.3979 11.69843 11.26144 10.98187 10.62434 10.55542 10.79755 10.96708 11.02939 11.2887 11.80884 11.33321 8.614913 7.849565 7.212549 9.800451 10.48496 9.617368 9.147942 9.296861 10.13177 11.20514 12.3896 11.95667 11.57815 10.64794 11.444 10.93266 11.42423 10.72211 10.74878 10.75023 10.98787 11.26347 11.04169 7.535953 8.379319 8.465982 9.019888 8.474906 8.644684 9.380523 9.011086 9.468113 10.66582 11.96134 11.67335 10.88397 10.53693 10.82633 10.25402 10.21263 10.32749 10.5247 10.19471 11.01541 11.35801 10.77586 8.953902 8.443554 8.80369 8.623836 9.60961 8.834076 8.999572 8.835788 10.4686 10.42089 11.60229 11.5832 11.33114 10.05566 11.09636 10.20237 10.258 10.62062 10.48857 10.14489 11.40099 11.07088 10.64445 8.500578 8.544858 7.815175 8.512371 8.136365 8.380095 9.461661 9.8258 9.200838 10.49927 11.48638 11.7742 10.49608 9.742468 9.315075 9.044184 9.661458 9.323888 9.979736 10.51669 10.50003 10.75289 10.55279 8.140522 7.9291 8.467335 7.948473 7.84909 8.878713 9.228608 9.341762 9.541382 9.544453 9.793461 9.858119 10.06971 9.451279 8.51177 8.683918 9.586095 9.493937 10.0905 10.45376 10.50862 10.45298 10.89592 9.174277 7.910554 8.41324 7.574174 8.196404 8.136746 8.121965 7.858237 8.164356 9.198856 10.01476 9.891054 9.341989 8.451241 8.975142 8.96706 9.390165 9.745036 9.87119 9.820464 10.01453 10.3652 10.31961 9.053761 8.623909 7.898996 7.378081 7.484929 8.12253 7.869719 8.111196 7.660993 7.883986 8.894523 9.96628 9.412325 8.602212 8.978284 9.126224 9.584894 9.770082 10.27369 10.15531 10.25294 10.89211 10.43277 8.431073 9.066086 7.605909 6.630337 6.98281 6.810944 7.623994 7.17003 7.13573 8.053357 9.209491 9.415495 8.662474 9.053435 9.397181 9.446578 9.86334 10.01845 10.17869 10.7758 10.44624 10.38814 10.5821 8.942445 8.941487 8.016459 8.513492 8.322972 7.758252 7.450797 7.878129 7.665907 7.39168 7.762891 8.652268 8.399451 8.6668 9.206373 9.121785 10.34451 9.926603 10.24554 10.46929 10.76244 10.86812 10.72856 8.17054 7.23271 7.703678 7.791962 8.005906 6.999223 7.472554 7.710637 7.925411 7.891777 8.577125 8.739526 8.736339 9.344995 9.341995 9.167021 10.40602 9.640493 9.765063 10.79863 10.77817 10.97881 10.41767 8.539558 8.259498 8.565295 7.196165 6.610144 8.112316 7.271636 6.927933 7.946772 8.102273 7.875247 8.079875 9.375752 11.33052 10.81717 10.21815 10.39465 10.33572 9.731151 10.2445 10.49189 11.12053 10.76395 8.240433 8.050691 8.147851 7.085478 6.498564 7.444286 7.85869 7.59498 7.437051 8.215886 8.160721 8.345738 8.091083 9.35317 9.591409 9.448403 10.31442 11.06631 10.24245 10.9984 10.90544 11.08032 10.89513 8.550308 7.967917 8.127562 7.298366 7.333465 6.49415 7.352107 7.673339 7.976416 7.147206 8.484519 8.401263 8.720249 9.223616 9.384628 9.444779 9.571202 10.1814 10.25545 10.58296 10.57897 10.69769 10.3299 8.480454 8.143271 8.400046 8.316236 8.42107 7.541131 8.236753 8.256838 7.837097 7.3845 8.376999 8.782026 8.372799 9.166592 9.061806 8.605547 9.607065 10.09919 10.09029 10.41691 10.74461 10.34597 10.42431 8.515889 7.59104 8.670294 8.427706 8.82935 8.922324 7.844193 8.359896 10.19205 11.45637 11.92006 11.58537 10.71724 11.57984 12.44317 12.37348 11.76033 10.8328 10.71005 12.17016 13.12123 13.49667 12.32615 9.425822 7.528139 8.268925 8.60403 9.334135 8.938853 8.31205 8.903502 10.90029 12.15107 12.53318 12.27021 11.24565 12.047 13.05301 12.96288 12.37509 11.36883 10.95156 12.79793 14.03581 15.59215 14.59917 9.623832 8.175732 8.02983 8.535868 7.534457 7.092595 7.973546 8.616755 9.133872 9.538013 9.353437 10.20192 10.09133 10.06388 10.93718 11.69838 11.60221 10.81748 11.46689 14.67081 16.11157 18.09854 18.4955 9.071504 7.593831 8.569519 7.444993 7.027435 7.670381 7.727194 8.79417 8.78412 10.26749 10.49481 10.5346 10.10987 10.96909 11.81418 12.57517 12.30537 11.48952 13.16938 15.3521 18.07163 19.78831 20.41618 9.247075 8.342739 8.020856 8.513025 8.168929 8.344195 8.860204 9.17792 10.17791 11.50909 11.07768 11.59347 11.83874 13.10125 13.83476 13.61449 13.87037 13.02653 13.97317 17.72324 19.60029 21.56919 21.07852 9.474851 6.999008 7.357038 8.650279 9.284972 10.27271 10.72347 10.36143 11.41015 11.70805 12.40401 12.9837 12.64802 14.57075 15.13742 14.90884 14.86531 14.43093 15.03153 18.73455 20.89188 22.41504 21.75938 8.43823 7.602589 7.820417 9.932999 10.68121 10.14239 10.38401 10.35759 12.41399 12.78729 13.28866 13.30149 12.69712 15.16579 15.84278 16.40749 16.29351 14.39652 16.20181 19.23029 21.44838 22.89708 22.22457 8.946985 7.907045 8.086035 9.623978 11.20953 10.96355 11.34051 11.00923 13.56718 13.85 13.94107 14.30479 14.27669 15.13896 16.49326 16.82891 16.4699 15.615 17.10016 20.28425 22.26842 23.02636 22.56798 8.171475 8.090663 8.552567 10.50998 10.79045 10.79585 11.77593 11.28996 13.5619 14.10327 14.95813 15.71215 14.54693 15.72432 17.80629 18.37472 18.3487 16.05388 17.43175 20.30505 22.645 23.84378 23.11084 8.994973 8.401255 10.09553 11.87671 11.69541 11.35841 11.40016 11.24762 13.69226 14.48686 14.93769 14.94588 14.56451 15.99824 18.65324 18.06892 17.89767 16.18208 18.38502 20.50726 22.87932 22.78703 22.46937 9.782323 8.487134 9.374578 10.02132 10.83674 10.82025 10.9053 12.09562 13.35448 14.63213 14.8919 14.47755 14.00885 15.77607 18.01674 17.6033 18.13421 16.40895 17.83689 19.94169 22.52357 22.9064 22.88938 9.201106 9.515572 10.08597 10.27731 11.7706 10.57605 11.69659 11.87735 13.37034 14.23273 14.85306 14.77176 14.40004 15.35916 18.42156 17.62954 17.38562 16.92805 18.14824 19.61706 22.00475 23.03317 22.16275 8.748121 9.011187 9.970596 11.7954 12.21095 11.81142 11.55084 12.17591 13.77476 14.28944 14.6072 13.23592 13.31399 15.84934 19.25628 18.41424 18.67715 16.80241 18.52868 20.36193 21.57055 22.12268 21.53455 8.204464 8.748878 10.92591 11.5593 13.19048 12.10626 12.02502 12.05263 13.87249 14.59625 14.2399 13.71816 14.30343 15.58732 18.69723 18.77998 18.86568 17.82364 18.05045 20.36054 21.73694 21.81034 20.88315 9.566998 9.260836 10.80363 11.55462 12.66976 12.26979 12.27326 11.70452 12.91361 13.86102 14.35423 14.02273 14.13222 14.11232 18.20366 18.85984 18.12046 16.65557 17.61575 19.08671 20.27447 20.7323 19.79643 9.615409 8.908094 10.52764 12.07648 12.35761 11.91719 11.31676 10.78619 11.90151 13.13435 13.57572 13.40028 13.16485 14.1586 17.97005 18.6574 17.49142 16.61602 16.97221 18.26481 19.8641 19.66534 19.13474 9.518407 13.66414 14.68301 12.44051 12.49297 11.79643 11.65911 11.69031 11.55598 11.38682 13.41629 12.76745 13.40397 14.54726 16.66532 17.59948 16.87245 15.5036 16.39759 17.45155 18.24678 18.04825 17.68169 9.886844 16.85537 18.44436 16.27383 15.36497 13.84907 13.35042 12.87622 12.51681 12.60914 13.06418 12.81159 12.38205 13.68456 16.01586 16.22343 16.41093 15.50471 16.12335 16.51148 17.60962 16.92897 15.91486 9.932881 17.91137 19.72267 16.92243 17.54066 16.3813 13.78773 13.66247 14.68949 11.97803 13.91343 13.337 12.36077 13.84169 16.9629 16.03707 15.96878 15.15771 15.55823 16.98711 16.99094 16.69534 16.27666 9.659884 18.09613 19.96937 17.05172 18.13224 17.0855 14.13896 14.20781 15.18947 12.32284 14.15654 13.44278 11.52995 14.65633 17.3638 16.08185 14.93075 14.58424 15.63039 16.85744 16.92874 16.18911 15.86921 9.225732 17.84486 19.66064 16.73664 18.33948 17.20544 14.32049 13.99798 14.7793 14.12439 13.80436 13.0112 10.64079 14.43213 16.94347 15.76767 14.88731 14.56431 14.75913 16.57955 16.82982 14.99926 14.78576 9.978578 17.50287 18.95299 15.45618 18.21201 17.02547 14.4027 13.69167 14.05373 14.97102 13.77975 12.47722 10.86374 13.84392 16.04429 14.79358 15.0554 14.68087 14.3245 15.75972 15.80098 14.99877 15.23887 10.18868 17.52852 18.87184 15.18826 17.86486 16.54828 14.55269 13.6402 14.14156 15.5371 13.91196 12.7452 11.54375 13.17193 15.15623 14.38001 14.19828 14.53728 13.81415 15.57458 15.68111 14.43799 15.17661 9.751181 17.77567 19.34327 16.0554 17.61001 16.27066 14.56316 13.73765 14.17065 15.73401 13.81508 12.20863 11.4907 13.34967 15.23476 13.96594 13.74054 13.87504 13.52333 15.54135 15.94359 14.1128 15.21993 10.12562 17.83921 19.52574 16.31928 17.54741 16.23771 14.63482 13.75617 14.15524 15.65129 13.92926 12.40173 12.0656 13.88922 14.18397 13.18738 13.58043 13.53881 13.6731 15.04371 15.07353 14.68031 15.49483 9.599173 17.72381 19.33587 16.07591 17.93183 16.65643 14.42071 13.79618 14.27678 15.20349 13.67884 12.52839 12.27971 14.40655 13.7573 12.9882 12.78122 13.05482 13.01771 15.88482 15.94137 15.41255 15.99297 9.698954 17.42312 18.87054 15.56586 18.05615 16.68462 13.77028 13.44723 13.88304 14.32237 13.28011 12.27115 12.59856 13.77862 13.29578 12.70767 12.83421 13.53693 13.18715 15.76992 15.76956 15.14107 15.93729 10.26758 17.18085 18.16345 14.96107 18.03324 16.52345 12.76308 12.70064 12.66801 12.16031 13.20089 12.79833 12.22538 12.70561 13.22355 12.84058 12.97821 13.38026 12.87051 16.21716 16.48619 14.9863 15.6656 10.44387 17.23746 17.66788 14.44783 17.53398 15.96145 11.02331 12.6539 12.60111 13.22309 12.45506 12.53511 12.75447 13.26548 13.35413 13.15652 13.2005 13.69604 12.86835 15.36887 16.235 16.85772 16.54977 10.23759 17.50456 18.4933 14.91491 16.87596 15.31868 10.46777 12.26849 12.64224 12.68833 12.15624 12.53137 13.16832 14.12793 14.15696 13.49824 13.72296 13.93223 13.8926 16.50182 18.04177 18.58524 18.28993 10.35166 17.05918 18.34675 14.85144 15.89987 14.52373 9.76105 11.89735 12.64335 14.01029 13.73979 13.24587 13.72216 15.26234 15.57124 15.82822 14.74431 15.00797 14.97392 17.71632 19.5425 20.54453 20.59761 9.555297 15.74934 17.18219 13.77729 15.08703 13.69022 10.26886 10.90417 12.99767 13.61335 14.09484 13.58124 14.1276 15.82747 16.31124 16.64211 16.18265 15.21884 15.42664 17.76999 19.3903 20.87875 20.63521 8.862854 14.02321 15.96503 13.04325 13.75009 12.35207 10.97646 11.18398 12.65906 13.14713 13.12646 13.15454 14.30518 15.27275 15.80141 16.52305 15.9915 14.97509 15.27901 17.70121 19.40024 21.01748 20.90414 9.332595 14.84705 16.37164 13.3482 13.17087 10.29789 10.88544 11.37841 12.42703 13.47049 13.44906 13.32345 14.28644 15.11956 16.00913 15.9466 15.03316 14.63348 14.81898 18.33994 19.95979 22.53777 21.45701 9.877868 15.61059 16.83839 13.17729 12.35922 10.87731 12.04013 11.68683 13.13918 13.59089 14.2367 13.87884 13.71417 14.67861 15.89329 16.04236 15.43196 14.25506 15.13684 17.87797 19.84326 21.79107 21.3449 9.140958 14.76068 16.10624 13.06766 13.47845 11.71019 11.03197 11.56545 12.67004 13.27332 13.428 13.15621 14.76991 15.18839 16.24062 16.5626 15.80795 14.79566 15.80218 18.18081 20.55774 22.59585 22.16014 9.849629 12.1764 13.81905 12.20043 12.96303 11.37443 10.69466 11.47991 12.80477 12.91667 12.75835 13.21933 15.38656 15.95259 16.823 16.35283 16.43909 15.31986 16.49224 18.66559 20.4817 22.71685 21.85016 9.36202 14.08019 15.09082 12.18999 12.97359 12.29903 11.47363 11.54493 12.6398 12.84276 13.85428 13.64815 15.08565 15.69742 16.96827 16.94289 16.80222 15.64644 16.48269 19.1488 21.81447 23.17466 22.23106 9.57612 15.02501 16.06492 12.43449 13.88631 12.50848 11.44948 10.40349 11.57291 13.3126 14.31746 13.71188 14.76625 16.03081 16.07044 15.89003 16.94098 15.98808 16.14021 18.78211 21.02096 21.56885 20.88732 11.78685 15.01811 15.52112 13.93588 14.43564 12.86158 11.35952 11.50686 11.3272 13.30817 13.81913 13.40519 15.05978 15.84919 15.35929 13.89001 15.52159 15.23993 15.40555 17.11906 18.97794 19.44685 18.4641 13.22307 17.17885 17.15026 17.71776 17.11022 14.76405 13.44761 13.67636 13.50036 13.58129 13.95018 13.70605 14.88567 15.03857 14.84337 14.45563 14.86374 14.4649 14.85144 16.43289 16.89828 16.35405 16.94752 13.76669 17.1444 16.05253 18.63818 17.65204 16.25583 13.92566 13.3862 14.08959 14.32102 14.93346 14.31664 14.22204 15.10196 14.79939 14.6737 15.79121 14.93165 14.95335 16.65422 16.83254 16.26995 16.42411 14.16293 17.56638 16.68997 18.26259 16.92739 16.86658 14.25883 13.70589 14.65646 14.7077 15.98879 14.10393 13.49225 14.60994 14.55858 14.16977 16.02258 15.63895 14.65991 16.49418 17.11003 16.32096 16.05037 15.02538 17.72275 16.8508 18.08271 16.43288 16.42471 14.93453 14.1509 15.1513 14.99477 16.14239 14.24235 14.14056 14.526 13.32078 13.45539 15.79795 15.33149 14.69157 15.69744 16.36747 15.60381 15.84035 15.73365 18.03275 17.27561 18.75753 16.95327 15.80555 14.91612 15.18357 15.67709 14.97079 15.72672 15.15915 14.04085 14.47075 13.372 12.99742 14.7936 14.90177 14.24704 15.20238 16.2678 14.74167 16.11823 16.26338 18.46109 17.27797 17.99683 16.66476 16.05012 15.40509 15.53155 15.96098 15.33267 16.30002 15.72512 14.53671 14.58817 13.3534 12.64955 14.37179 14.83991 14.59077 15.26721 16.07784 14.28749 15.199 16.74382 18.91121 17.16111 18.04957 17.40871 16.48565 15.41961 15.17963 15.49974 15.08093 16.65548 15.9269 13.91849 13.88327 12.97235 12.65223 14.07203 14.75737 14.22784 14.64774 15.34663 14.63228 16.0888 16.98529 19.11541 16.87011 16.74349 16.9392 15.88544 15.29093 14.62053 14.88953 15.09566 16.51639 15.45968 13.03472 13.23992 12.823 11.87619 13.33451 14.86192 14.20521 15.69702 15.84917 14.75232 16.39235 17.02896 19.19595 17.16109 16.8834 16.3556 15.42284 14.74861 14.76104 14.92473 14.9596 16.6881 15.93081 13.33428 12.97397 11.86678 11.63746 13.04319 14.28844 13.94617 15.04595 15.0869 13.90257 15.89565 16.85907 18.78141 16.70892 17.00507 15.92624 15.45061 14.55362 14.95892 14.77704 14.90913 16.98108 16.19264 12.85906 12.48413 11.65127 11.22398 12.58972 13.57485 13.65335 14.72739 15.04537 13.98265 15.01211 16.64772 18.64282 16.71573 17.18554 14.0683 13.95587 14.57919 14.46328 14.58978 14.59518 17.19131 16.57361 11.92534 12.44241 11.72602 10.9928 12.40186 12.90819 13.48149 13.89237 14.56885 13.63314 15.65915 16.43158 18.50433 16.55654 16.99913 14.52069 14.72103 15.24015 14.21969 14.87307 14.52989 16.81562 16.34734 11.70553 12.3317 12.12857 10.71785 11.98174 13.78292 13.32322 13.64274 14.45671 12.9734 15.85995 16.15336 18.23414 16.24944 17.09164 15.74857 15.23684 15.1064 14.90766 14.93522 14.25292 15.3692 15.24385 11.05891 11.63416 11.56629 10.73565 11.83266 13.19534 12.7056 12.56191 13.70245 13.0052 15.80045 15.78317 18.05012 16.20395 16.93727 15.87394 15.19709 14.3524 15.32856 14.63064 14.19885 14.98944 14.75296 10.62751 12.19092 12.06983 10.93399 11.87565 13.48435 13.07779 12.09982 12.47317 12.27248 14.84082 15.39456 17.87456 16.5168 17.58305 15.61139 14.72246 13.21522 14.96642 14.20902 13.41669 14.09352 13.92773 10.64034 11.88319 11.45076 10.29098 11.03321 12.29812 12.70397 11.7358 12.26939 12.86226 14.78897 15.02351 17.78964 16.85471 18.13364 15.47449 12.54772 11.64264 14.01794 14.02666 13.12667 13.50438 13.3572 10.43241 11.16833 10.74877 10.2707 11.00853 12.42801 11.92629 11.09674 11.43357 12.86431 14.27416 15.09622 17.92495 16.85561 18.0988 15.42922 13.02023 12.68088 13.53072 14.48343 13.28728 12.15022 11.93546 9.953141 10.79692 10.91492 10.17909 10.60862 11.80252 11.56975 11.04416 11.2531 12.42208 13.60621 15.60607 18.24389 16.80309 17.81159 15.3917 13.49877 12.40576 13.14706 13.09449 12.85986 11.56458 11.51797 9.652337 9.949935 10.32372 9.620278 10.69048 12.02814 11.59302 11.66032 11.30074 12.12424 13.24895 15.90996 18.41689 16.64116 16.99631 14.64567 13.13194 12.07542 12.5822 11.69349 12.01927 12.62355 12.76301 9.990061 10.90189 10.44079 10.43505 10.66998 11.15739 10.76031 11.42792 10.89405 11.56491 12.52887 16.00483 18.30446 16.08208 15.86133 13.48314 11.61676 10.97823 11.11799 11.98649 11.92625 11.69026 11.50517 9.732758 11.60136 12.52013 10.93729 10.51151 10.81287 10.82617 11.56538 11.44386 11.92824 12.41918 15.85966 18.15599 15.9375 14.95248 13.4534 12.87702 10.83218 10.35821 11.16184 9.718279 11.04042 10.5775 9.815519 11.36835 11.88853 10.33835 10.50751 11.11677 11.1463 10.79816 10.42655 11.12749 11.29204 15.60883 17.95237 15.71562 14.06708 12.83226 12.50489 11.20979 11.6847 10.72093 10.36459 9.917531 9.80342 9.078652 10.03732 10.6124 10.40085 10.80684 10.88086 10.69822 11.10227 10.46698 10.97048 11.10912 15.2283 17.69786 15.57806 13.4353 12.19316 11.6246 11.0224 10.72823 9.161061 9.050728 9.18773 8.855824 9.341613 10.0488 10.13517 9.546819 9.585426 10.50744 10.39803 10.67031 10.51961 11.0685 11.14912 14.64353 17.16451 15.15834 12.35796 12.72608 12.63046 11.68167 12.3668 14.25992 15.93695 17.47775 17.61803 15.56757 12.9737 13.57319 14.56981 13.7044 12.71877 12.86225 13.4201 14.1629 15.60515 15.65097 14.06131 16.47077 14.28449 12.84858 13.9689 13.82744 13.50231 13.78073 15.74885 17.04282 18.63243 18.85933 16.36653 13.78124 14.21553 15.24145 14.55391 13.56051 13.44235 13.90322 15.24372 16.40675 16.67416 13.27166 15.83467 13.93871 14.37551 15.34901 13.98736 12.92254 13.76627 16.36158 17.10549 18.30305 19.29653 16.39378 14.40754 14.97054 15.40539 15.09013 14.31383 14.41104 14.81105 16.28816 17.46544 17.82826 12.96865 15.35536 13.58534 12.4107 13.17324 13.02235 12.97369 12.78875 14.50413 17.08331 17.24843 18.6091 16.95518 13.8684 14.65208 15.11388 14.85909 14.55639 14.21002 14.85613 16.15392 16.62638 16.38885 12.74014 14.99901 13.14317 12.02542 13.41206 14.03033 13.80731 13.07016 15.74668 17.29949 18.08332 19.69819 16.80057 14.75249 15.27074 15.78106 15.3902 15.52286 15.18476 16.46467 17.64916 18.49447 18.44848 12.97496 15.42951 13.52378 12.25876 12.9795 12.56979 12.22692 13.57497 16.76153 17.23584 17.87868 19.12806 16.46191 14.3858 15.09691 16.4803 16.39127 15.58957 15.17072 17.00169 18.0875 17.41795 17.79514 12.85048 15.10298 13.23063 12.87181 13.15208 14.49708 13.07669 14.13431 17.66776 18.05823 18.7889 19.8481 17.92514 14.92354 15.70432 16.74818 16.99346 15.81199 15.74879 17.21499 17.70545 17.515 17.36108 12.53143 14.44646 12.04487 12.66221 12.77981 14.32154 14.07838 15.03848 17.27874 19.03686 20.9606 21.08079 18.90958 15.76664 16.3242 16.48548 17.68536 17.00244 15.70976 17.18387 17.96568 17.45182 17.34422 12.27433 14.13071 11.95814 11.10963 12.29782 13.32947 14.22352 14.91252 17.05256 19.26613 20.56975 21.0718 19.55671 16.45315 16.53867 17.16694 17.57012 16.58561 15.94327 18.1118 18.44273 17.04756 17.29078 11.13274 13.31547 11.17836 10.36571 11.99675 13.38614 12.98195 13.65712 17.52398 18.83635 20.82496 21.25018 19.02944 15.45844 17.22033 16.9855 17.61625 16.53855 16.01951 17.28067 17.80919 16.29823 16.60528 11.49348 12.72149 11.09698 10.74121 11.50064 13.47943 13.28319 14.12894 16.37674 18.3519 20.4639 21.47652 19.33566 15.77035 17.06349 16.64114 18.07568 16.64302 15.36201 16.04336 16.91956 15.94561 15.99434 9.608139 11.75429 10.06571 11.10138 12.11786 11.58483 13.1205 14.21301 17.56386 19.13147 20.32322 20.12503 18.29022 15.28772 16.86212 17.37056 17.82328 16.0193 14.99997 15.78904 16.12305 14.55896 16.01875 10.37425 13.20676 13.2479 12.19929 12.48866 11.74895 13.30715 14.54824 16.49951 18.31167 18.70988 19.54097 18.35619 15.11479 16.51697 15.98994 17.09819 15.56539 14.59282 15.14828 15.75255 14.43601 15.72609 12.24577 13.50046 14.6557 13.99299 13.82843 14.16929 14.48501 15.5354 17.66883 19.51937 19.39577 20.05754 18.37926 15.92839 17.23025 16.90665 17.33165 15.74956 14.90289 15.95183 16.37263 14.70161 16.83718 11.82463 14.14506 14.91792 15.10521 13.43633 14.76357 14.50471 16.30964 18.37582 20.10591 19.70662 20.12249 18.50193 16.44523 17.84676 17.22989 18.06538 15.9933 14.78116 15.97121 16.63473 14.1447 16.62147 11.49515 12.57675 14.99955 15.12591 14.04319 14.90118 15.1428 16.90608 19.3396 19.58758 19.89336 20.47232 19.38027 16.83281 17.80051 16.78543 17.68006 16.1482 15.12499 16.29321 17.28958 14.39812 16.74356 12.83119 13.36858 15.33085 15.8993 14.98862 15.06884 16.27656 17.09787 19.89 19.45495 19.66687 20.41065 20.05285 16.93578 17.84101 17.22516 16.6539 15.47889 14.51853 15.41234 16.16337 13.92638 16.21105 12.24501 13.81182 15.54418 15.71802 14.7434 15.25031 16.42093 16.59528 18.99483 18.75741 18.65719 19.56692 19.45428 16.5445 17.94703 16.85806 17.52571 15.87006 14.62513 16.25237 16.75192 14.53815 16.44307 12.43977 14.4055 15.44666 14.61817 14.49417 15.49514 16.47301 15.8417 18.29481 18.40584 18.14786 18.99505 18.48756 16.02132 17.57674 16.21739 17.56367 15.96092 14.12129 15.69186 16.08254 13.29479 15.69123 13.40359 14.56592 14.56405 14.75467 14.80557 15.61075 16.30825 16.00495 17.7576 17.7054 18.44081 18.78086 17.91715 15.75736 16.79029 16.09669 16.95103 15.45958 14.6285 16.45296 17.08261 14.81537 16.62719 13.40314 14.79066 14.44038 14.9208 15.28192 15.93543 16.12896 15.63424 17.53443 16.71537 17.66586 18.26663 18.14948 15.38054 15.57821 15.0981 16.37489 14.9254 14.11771 16.22453 16.63408 13.88445 16.03982 13.27263 15.37152 14.98211 15.65071 16.10147 16.25443 16.39878 15.22288 16.07312 15.48051 16.95177 17.88365 17.64783 15.38212 14.85438 14.25418 15.50375 13.87315 13.85102 15.71543 15.58055 13.48126 13.54171 12.79769 14.03458 15.15382 15.77783 16.13641 15.98903 15.71088 14.83081 15.42676 14.42686 16.35059 17.19747 15.89601 14.84456 14.84353 13.56014 14.43848 14.02768 13.56937 15.50516 15.01935 13.35548 13.45835 12.93903 13.22154 14.53004 14.98958 15.29645 14.57587 14.04077 13.26272 15.32759 15.32236 15.08416 15.42689 14.78734 13.71587 13.79163 12.75518 14.19596 13.34965 13.19663 14.03743 14.96614 16.49541 15.33635 12.45864 14.61374 13.87632 13.62215 13.72294 14.31611 14.38086 14.30659 15.43989 15.61096 14.15577 14.35514 14.81355 13.64131 13.45614 12.72456 14.13968 12.8555 13.59385 14.17748 16.39845 18.38371 17.80732 12.33578 14.00891 13.07828 13.71424 14.10664 14.0687 13.13889 13.63885 14.8914 14.61784 13.90929 15.45194 14.73162 13.03892 13.2657 13.5637 13.76148 13.25706 15.10444 16.29706 16.97831 19.44946 19.79165 11.96159 13.51957 13.01035 13.54761 13.69153 14.00353 13.68937 12.58661 13.48017 14.13214 13.91707 15.31068 14.23771 12.71703 12.92456 13.6957 14.43063 13.71029 15.22686 17.15446 18.45062 20.47192 20.89673 12.05161 13.9109 13.16452 12.97099 13.18609 13.13105 12.99765 11.58859 13.5218 14.01596 14.89017 16.47881 15.28746 13.67678 14.92654 14.96245 15.16147 15.0592 16.54627 18.17285 20.02958 21.51884 20.96085 11.84209 13.52904 12.77278 13.65398 13.20718 12.63755 11.65749 11.51693 13.74348 13.71783 15.14928 15.87488 15.38048 14.01578 15.41916 16.25989 16.82 15.85239 17.44685 18.49073 20.68714 23.03419 22.3119 10.61903 12.43421 12.6958 13.1518 12.79633 12.09934 11.18174 12.15249 13.5683 12.78554 14.49859 16.1356 16.38138 15.60392 15.1943 16.6934 17.43444 17.15856 17.69735 18.73776 20.3603 23.0533 22.83157 11.10656 11.3087 12.01439 12.55888 12.73079 12.43724 11.43508 11.91604 11.70938 13.99057 15.63961 17.28322 16.47677 15.20305 15.66617 17.61813 17.6751 17.60305 17.77451 19.25667 19.94949 21.90983 21.98059 10.16949 12.0564 11.52991 9.989189 11.37004 11.68872 11.52673 12.63663 12.73647 14.62583 15.9687 17.945 17.5506 15.1612 15.45209 17.22151 17.94404 18.35554 18.20267 19.54291 20.5292 21.7872 21.39606 10.79198 11.45736 9.874234 11.29701 11.26837 11.21837 10.89179 11.62866 12.76508 14.6835 16.18573 17.36658 16.85448 15.94918 15.41981 17.08667 18.88033 18.45577 17.89176 18.7529 19.93383 20.91602 20.71407 10.99965 11.83611 10.76372 12.36669 12.88359 12.50686 12.02554 11.77562 12.96449 14.7419 17.49727 19.05647 17.76691 16.14889 15.8502 16.94702 18.54008 18.61212 17.60375 18.40122 18.75871 20.56727 20.2013 10.71721 12.24653 11.40098 12.01936 13.33127 11.90686 10.65947 11.82579 13.32248 15.28793 17.01124 18.64284 17.72797 16.53176 16.11108 16.70494 17.7008 16.87293 16.90321 17.01193 17.9865 19.62047 18.54438 10.84808 11.77401 10.30343 12.64884 13.14566 11.23923 10.88098 13.11721 13.34063 16.31784 16.83382 18.21345 17.3839 15.27081 15.50685 15.6567 16.72981 16.33526 16.45064 16.3113 16.49539 17.15864 16.46489 9.56905 11.07326 11.29717 12.00945 12.56924 11.74636 11.67797 12.27109 12.33903 15.01359 17.29026 17.98109 16.23312 14.9431 14.57544 15.20214 16.10517 16.19224 15.99478 15.25868 15.40402 16.06674 15.44316 10.508 10.89142 10.47173 10.95241 11.76593 10.98585 10.76927 12.52917 13.36483 14.31004 15.60877 16.93384 15.8426 14.30149 13.70551 14.91785 15.92855 15.53096 15.40199 15.04334 15.08857 15.01525 14.25574 10.63981 10.66823 10.20522 11.10935 11.52312 11.02348 10.33216 11.91914 13.66731 13.93949 16.71332 17.01327 15.03499 14.47763 14.38019 14.41362 15.83647 15.67047 14.47045 14.31423 14.19904 14.82268 14.1559 8.488654 10.10538 10.92675 10.09366 10.85918 11.26827 12.20304 11.80998 13.27558 13.73623 16.86435 16.49012 14.37312 13.21352 13.43559 13.28338 14.71591 15.0856 14.91768 13.89271 13.95088 14.00356 13.01124 10.81898 13.143 12.69162 12.18221 12.55161 11.64523 12.4468 13.02303 11.64384 13.77602 16.63419 16.27282 14.54465 12.69009 12.62936 13.17467 13.86224 14.07909 14.24895 13.57493 13.15678 13.56058 14.07112 11.59634 16.15282 16.04291 14.96902 14.3159 12.56915 13.37283 13.76863 13.54054 15.07096 17.31351 15.84202 14.1527 12.01037 12.44869 12.54331 13.90306 14.87695 13.81047 14.15678 13.85537 13.21027 14.43797 11.50468 16.01534 15.65023 16.86644 16.7308 13.15539 13.75249 14.19167 14.84136 15.6804 16.669 15.56741 13.27599 12.18581 12.46388 13.30746 14.70786 14.89385 13.59378 14.1329 13.90083 13.44039 14.82801 10.83374 15.32171 15.06138 17.48699 17.51079 13.80905 13.93069 14.59176 15.34084 16.82994 18.43996 15.90578 13.45436 11.4224 12.79343 13.04898 15.73146 15.33158 13.21905 14.24352 13.77445 13.27233 15.71018 10.87577 15.47127 14.70888 17.73984 17.70155 15.23704 14.3281 14.20854 15.22783 16.9904 18.81393 15.66493 12.64094 11.61629 12.53687 12.72079 15.53799 15.56939 13.56948 13.97123 13.99972 13.84164 15.74528 9.678106 15.093 14.73196 18.04266 17.9735 15.98976 14.84349 14.29395 15.38192 17.14681 18.48132 15.55414 11.81447 11.31875 12.51214 13.46786 15.07734 14.72639 12.89217 14.18221 13.942 14.46083 16.30935 9.27702 15.11397 14.6864 18.26455 18.06617 16.64905 15.23202 14.50276 15.79894 17.31784 17.91948 15.71456 11.84832 11.10479 12.36307 13.02193 14.84241 13.94248 12.61262 14.14687 13.61714 14.61513 16.65529 10.31116 15.20001 14.41779 18.20655 17.87181 17.37104 15.80053 14.73345 16.33781 17.26945 17.61073 15.76432 12.14948 11.87968 12.84734 13.35572 15.99964 15.05299 12.98151 13.59093 13.31608 14.26525 16.48788 11.03995 15.58457 14.74849 18.04535 17.62146 17.83399 16.13437 15.02326 16.80089 17.59974 17.02293 15.01341 11.93478 12.57936 13.6127 14.46719 15.84169 14.35661 12.21926 13.44742 13.43839 15.56678 17.01775 10.68538 15.81025 15.13098 18.21277 17.8306 18.10699 16.28154 15.16807 17.16661 18.57889 16.92452 14.87336 11.62055 12.73409 14.09998 15.07829 15.77258 14.38338 12.46635 13.38107 13.42031 15.66041 16.70012 10.80705 16.10119 15.46497 18.4098 18.0212 17.97135 16.10877 15.19762 17.24214 18.58634 16.91249 15.42679 11.88585 13.91432 14.45943 15.74949 15.78372 14.54293 11.42183 13.62915 13.34823 14.55129 16.14689 11.94579 16.89884 16.24403 18.55092 17.98724 17.20735 15.26665 14.65565 17.00868 18.47542 17.43419 16.03572 12.83943 14.0368 13.85004 14.82996 15.17481 14.47794 11.56922 13.58228 13.62983 13.59302 13.86895 12.38524 17.37505 16.7696 18.47446 17.26857 15.96833 14.24874 13.03042 16.26422 17.79273 17.16697 15.42565 13.5957 14.48988 15.57542 16.0727 14.58922 13.24106 11.54757 13.28529 14.40883 13.49071 12.73336 13.03429 17.5047 16.87468 18.99148 17.70904 16.97621 14.13228 12.62222 14.45247 16.32981 16.61537 14.76507 12.27121 13.29012 13.69145 14.77818 13.90872 12.32405 11.65774 13.06149 13.20633 12.79723 14.08691 13.543 17.20046 16.71364 19.24344 17.89848 16.23823 13.61446 12.58731 13.79848 15.94572 15.83083 13.94334 12.33336 12.76893 13.26038 13.66663 13.53549 12.52763 10.97694 12.18569 12.12396 12.52927 14.61442 13.93316 16.19917 16.60253 18.37887 16.34868 15.3344 13.60281 12.46623 14.00873 15.9596 15.67228 13.47866 13.02688 12.05685 12.97747 13.6599 13.39636 12.42592 11.40474 12.42729 12.39029 12.35651 14.67778 14.61915 17.17112 17.5472 19.37409 17.49985 15.90717 13.63423 11.95899 12.93315 15.14544 15.01936 13.25283 12.0639 11.61034 12.99201 13.5629 12.46684 11.77172 11.48846 12.21882 12.39871 12.28264 13.6378 15.01957 17.45677 17.19109 18.36874 17.45291 15.49117 13.40853 11.98515 13.43848 14.47075 13.50971 13.02251 11.71136 11.68848 13.16979 13.33672 12.58453 12.35258 10.77152 11.58895 12.66962 12.02104 13.51065 14.3445 16.08383 16.46618 18.37986 17.49754 15.51561 12.724 11.01192 12.56261 14.75061 13.70792 13.23755 11.97928 11.47003 12.88496 13.19709 12.51916 12.02072 11.23445 11.98222 12.57755 12.58092 13.76349 14.65777 17.34103 16.21595 17.87756 17.01974 14.35497 12.22902 10.17611 12.75461 14.43687 13.74576 11.96353 11.00994 10.55103 11.22951 12.06966 11.58648 11.32696 10.70369 11.09274 11.97977 11.15652 12.0545 13.84403 16.75669 15.79734 15.90669 15.87204 12.81713 11.09628 9.869988 11.99412 13.88495 12.05193 12.04093 9.865374 9.98888 10.54978 11.08329 11.51721 11.287 10.19415 10.19129 11.11317 10.82287 11.26695 12.03434 15.45859 15.11167 15.11641 15.16317 14.43024 11.65586 9.923259 11.36602 12.3641 11.81006 10.42863 9.54241 9.423545 10.06809 10.60886 9.986245 10.09022 9.895988 9.939384 10.39964 10.69043 10.78549 11.62159 13.6024 13.63344 15.00115 13.6637 13.22205 10.87602 8.768591 9.799749 12.06331 11.48621 10.03431 9.139547 9.069712 9.670283 10.33705 9.896729 9.732963 9.743416 9.657762 10.36899 10.26934 10.40027 11.81183 14.29564 13.63866 13.6298 13.18893 11.65243 10.08644 8.713807 10.15905 11.12224 10.93487 10.20999 9.452074 8.578758 9.197603 9.436418 9.835726 10.35768 10.15316 9.921681 10.65349 10.78003 10.5952 12.90228 14.67107 13.85628 14.29541 14.35086 11.63753 8.860591 8.425612 9.22795 10.41009 10.2974 10.03016 9.485574 8.96593 9.532566 10.04701 10.0559 10.14437 9.809213 10.09447 10.73098 10.48613 10.97839 12.14247 14.62703 13.12694 13.76217 13.40734 11.91112 10.03432 10.69592 11.79923 14.96772 14.89136 11.78498 11.03141 11.00658 12.59778 13.80232 13.4921 12.70364 11.11213 11.89696 12.66712 11.61696 12.02989 12.4993 14.9535 13.76636 14.01113 13.60918 11.75265 9.318426 8.455474 10.17039 14.04918 14.17533 10.41443 9.469222 8.986806 10.21098 11.43141 11.99639 11.92311 10.10373 10.33753 11.20988 10.83258 10.75896 12.68394 14.34959 12.56896 14.07434 13.22602 10.90166 8.476089 7.972132 8.819757 12.4768 12.05638 10.18155 9.379935 9.701678 9.932637 10.54168 10.334 10.5734 9.954249 10.09657 10.31382 10.49024 10.26939 11.75025 13.98052 12.16752 14.10251 13.03628 9.846658 8.836266 7.344621 8.59577 10.93273 10.1303 9.196149 9.388488 9.020345 10.06814 10.79366 10.47544 10.58243 10.03372 10.03065 10.42077 10.64656 10.34247 11.83129 14.04893 12.96955 13.20662 12.82525 9.696637 7.323474 8.177329 8.925125 10.40487 10.10953 8.585592 8.994603 8.708897 9.25738 9.843696 9.578411 9.801521 10.00724 10.09079 10.59092 10.64287 10.58762 9.790665 12.15129 12.64895 13.58438 12.95563 9.711924 8.575097 9.001645 8.701345 10.52208 10.09897 8.517282 8.199652 8.714253 9.041263 10.04511 10.11496 10.00863 9.805107 10.16271 11.0758 11.04546 10.75644 9.414765 12.83946 11.98675 12.726 12.46979 9.267152 9.039246 8.176429 8.053612 10.21454 10.41292 8.622193 7.66354 8.369621 8.642668 9.53128 9.865145 9.638438 9.991666 10.25773 10.73875 10.72115 10.65728 8.779566 11.93363 11.50436 10.50424 9.622196 9.267383 8.582248 8.53771 7.890744 10.04505 10.20443 8.095118 8.612964 8.879345 8.707826 9.227075 9.176577 8.984758 10.03803 10.03335 10.5386 10.95927 10.46486 10.31262 11.88174 11.99282 11.90945 9.594206 8.671169 8.318475 8.181697 8.13483 10.15049 10.25244 7.071458 7.442567 8.785149 9.691864 9.679538 9.605824 9.961757 10.42259 10.17275 10.75009 11.18037 10.72504 9.364248 11.96104 11.57661 12.01562 10.75383 6.945975 7.367255 7.736284 7.312432 8.969963 9.153383 7.523694 7.927206 8.369026 8.890183 8.625024 9.480546 9.502405 9.561119 10.14811 10.62848 10.7046 10.59589 8.967705 11.99061 11.26416 11.1752 9.580898 7.045003 7.880908 7.853495 8.063289 8.442639 8.374674 7.542927 8.712921 9.363231 8.787829 8.940651 8.762001 9.656484 9.560316 9.75022 9.998157 10.96855 10.83991 10.79417 10.95528 10.71563 9.979272 8.763993 8.042848 7.088778 6.67021 7.448594 8.206177 8.038567 8.22692 8.547086 7.783141 9.548368 9.043281 9.180702 10.15911 10.00978 9.834736 10.7707 10.82731 10.66534 9.814768 12.13082 11.35585 9.269568 8.184406 7.729397 6.804678 6.910729 7.282489 8.309008 8.415974 8.394214 7.598199 8.050271 7.802004 8.228464 9.248132 9.948934 9.981988 9.834879 10.65781 10.51871 10.32499 9.652328 11.7325 10.80005 9.37675 9.013214 7.384077 7.177258 6.372046 7.152434 7.877509 7.752526 8.609852 8.207765 8.032439 8.76918 8.827532 10.00151 9.213638 9.988755 9.774078 9.915665 9.921049 10.41844 9.466437 10.99616 10.88723 9.492371 8.961466 7.342728 7.358507 7.339148 7.301462 8.448383 7.55255 8.734881 8.417077 8.13668 8.47903 9.036981 9.332474 9.148084 9.903509 9.827729 9.972055 10.26808 10.0221 9.64337 12.05854 10.97252 10.21088 9.235108 7.101156 7.432653 8.052295 7.081014 6.580639 7.278504 8.679576 8.280871 7.73062 8.75071 8.532309 9.329696 9.757581 9.649004 9.204338 10.25986 10.47111 10.64369 8.506092 11.0128 10.68274 8.38584 7.542353 7.152045 7.326688 7.308694 7.642912 8.45325 8.044881 7.742783 7.756063 7.661537 8.275199 9.033102 9.546831 10.0107 9.767799 9.575422 10.45731 10.67947 10.68756 9.190603 9.530713 10.03561 9.930932 8.509491 7.016098 7.502091 7.892929 8.24372 8.307619 7.979042 8.022539 7.607509 8.970244 9.02056 9.152427 9.395686 9.654662 10.00138 9.774302 10.25611 10.34001 10.50237 8.055989 10.48079 9.946203 8.668516 8.405702 6.663228 7.840029 7.953751 7.417573 8.407804 8.318707 8.09545 8.268252 8.237886 8.408285 9.147687 9.502143 9.359609 9.642401 10.35548 10.85097 10.35253 10.09162 8.523983 10.58812 10.45586 9.346948 8.423094 6.955203 7.860735 7.061844 7.640428 8.098751 8.684567 8.348521 8.667695 8.787177 8.56147 9.256539 9.863892 9.601056 9.600217 10.26275 10.53992 10.67695 10.53019 8.54944 10.105 9.919378 8.700562 8.344156 7.651311 7.920049 8.247942 7.364244 7.392271 7.95518 8.640728 8.450232 9.633104 9.684301 9.891527 10.32047 10.18789 10.04646 9.441429 9.973019 10.92726 11.09868 8.736779 10.67164 10.37507 8.660881 7.410948 6.964188 8.062383 8.657798 8.175787 8.124825 8.552548 8.639585 9.223927 9.4434 9.095827 9.018662 9.108647 9.592525 9.690062 9.847681 10.15555 10.88235 11.25451 9.102138 10.24407 9.305552 7.972584 7.585355 7.130199 8.330059 8.346169 7.620663 7.047201 7.893063 7.923952 8.201685 8.679209 8.079769 8.701505 9.398625 9.830337 10.10372 10.45054 10.39745 10.80141 11.24109 8.334327 8.800347 7.70179 9.206788 7.814823 6.755373 8.229139 8.560562 8.269526 8.002664 8.831103 8.463894 8.141541 9.049789 8.658106 9.396982 9.033927 9.765074 9.622846 9.758422 10.27184 10.49305 10.98647 8.128156 10.12106 8.910188 8.762326 7.666012 6.949401 7.950629 8.1798 7.218674 8.2833 9.230454 8.431417 8.010346 8.432215 9.385073 9.408096 9.264348 9.842328 9.402944 10.16326 10.44512 10.27258 10.61046 9.777776 10.17425 9.162596 8.756527 9.402295 7.245045 6.706331 7.813528 7.5786 6.985806 8.648697 8.302122 8.295655 9.284019 9.676419 9.26071 9.179568 9.636398 10.1599 10.62567 10.66345 10.83598 11.00543 9.4869 9.121305 8.684687 8.700015 9.641527 9.05888 7.269274 8.791707 8.11694 7.627497 7.894124 8.112581 8.470985 9.387035 9.151163 9.710186 10.16911 10.16346 9.604074 9.987885 10.31005 10.77668 10.24039 7.866471 9.883156 9.715327 8.677911 9.516367 8.34246 6.843951 7.838072 7.583541 7.852625 8.79549 7.970304 7.762091 8.846987 8.563057 9.384929 9.697865 10.01375 9.721039 9.735113 10.16057 10.63224 10.43368 9.080318 8.246053 9.041588 9.417509 9.518696 7.989542 8.403717 7.463982 7.206106 7.981693 8.578013 8.107899 8.514518 7.873508 8.147607 8.765822 9.033931 9.63969 10.04347 10.20652 10.35496 10.39911 10.52451 9.13128 9.074238 9.046019 9.162777 9.203651 7.817907 8.81809 9.218652 8.689803 8.523691 8.246085 7.754849 8.768758 8.798193 9.144502 9.340219 8.860093 9.865606 10.48086 10.25486 10.56614 10.47177 10.82067 7.529797 9.080559 9.025809 9.092778 9.069881 7.946015 8.707859 8.578739 7.658888 7.688912 8.116105 8.22648 8.638034 8.394612 8.661798 9.266599 9.497275 10.0152 10.51752 10.32173 10.39726 10.61129 10.75329 8.053345 7.806293 9.592606 9.250229 10.12409 9.191865 7.827196 8.112508 8.535282 8.097424 9.000211 8.186003 8.92979 8.464402 8.670289 9.216187 8.820874 9.527074 9.87499 10.41622 10.59681 10.51637 10.55027 8.95764 9.454929 9.582647 10.45938 9.56032 9.433331 8.428452 8.183547 8.032114 8.346304 9.071006 7.965348 8.02034 8.698916 8.684159 9.147419 9.093694 9.894665 9.954333 9.885933 10.35833 10.71119 10.45288 8.644167 9.48673 9.193418 10.94477 10.83592 10.44026 9.28124 8.387064 8.084641 8.072067 8.342614 7.222877 7.512965 8.233858 8.808452 9.225642 9.137754 9.547808 9.455416 9.747941 9.971579 10.64146 10.5402 9.362679 9.369581 9.729918 10.51496 11.36854 10.06961 9.509526 8.469991 7.580379 7.402191 8.035908 8.038517 7.526035 8.179871 9.229591 9.114322 9.371479 8.994488 10.0342 9.992566 10.37911 10.48729 10.1093 9.234426 10.02822 10.1721 10.36807 11.38841 10.48724 9.894856 8.55321 7.932958 7.556772 6.919079 7.997473 8.420939 8.136166 8.576433 8.605513 9.379736 9.246395 9.551528 10.12443 10.13093 10.29004 10.01479 7.140229 7.340988 9.690434 11.22617 10.54758 9.907132 10.23349 7.846205 7.38694 7.756484 8.138117 7.949685 8.286037 7.875541 8.682808 9.680047 8.736238 9.250605 9.806664 9.929686 10.29157 10.88262 10.53922 7.609503 8.446361 7.927704 10.19232 9.981958 9.750368 10.16796 8.132822 7.723164 7.520811 7.855199 7.349501 7.666749 8.55197 8.498571 9.580915 9.49983 9.968874 9.624427 10.19383 9.79729 10.48853 10.77697 8.643137 8.622834 9.379179 10.04107 10.14056 9.3327 9.441696 7.66965 6.918215 7.325087 8.433827 7.403569 7.932473 9.355262 8.961336 9.433534 8.987287 9.442863 9.373944 9.75194 9.910201 10.3459 10.44656 8.102217 8.064889 10.64028 12.49552 11.73663 10.07672 9.110008 8.321954 7.095238 7.711002 7.663853 7.130478 7.74688 9.022202 9.092591 9.239534 9.148391 9.078291 9.648328 9.942706 10.50384 10.56971 10.62924 9.490426 8.373809 10.40654 12.21494 12.46647 10.44266 9.246642 8.188566 7.077143 7.664156 7.372887 8.266142 8.489851 8.568101 8.872865 9.148156 8.987501 9.957211 10.15845 9.909985 10.00002 10.26888 11.01089 8.798372 9.025386 11.31425 11.42679 10.40138 9.216152 9.422606 8.502447 7.214077 7.507916 7.581383 7.426453 7.74972 8.678537 8.401515 9.35175 9.522068 9.689368 10.34969 10.18144 10.10829 10.22423 10.66045 8.333779 8.557695 11.21921 11.96504 10.46627 9.176018 9.10099 8.930181 6.847103 7.599282 7.893191 7.544654 8.840031 8.585423 8.405005 8.922948 9.007273 9.288807 9.946635 10.77755 10.62705 10.41732 10.66157 7.559142 9.412998 10.48524 11.38948 11.17182 9.945296 9.195613 7.687301 7.509073 7.597322 8.275542 8.369865 7.823867 8.430854 8.52591 8.722355 9.220226 9.689714 9.526666 9.805052 10.34926 10.81544 10.53098 11.4918 14.00084 16.17197 16.42617 15.349 12.41796 11.39773 11.66957 13.16477 16.12451 15.81399 11.20098 8.846268 9.76712 11.6804 12.1915 12.09149 11.27532 10.66243 11.10545 11.89396 11.18614 11.62189 12.7754 14.8082 17.40473 16.74525 14.93741 12.71457 10.89088 11.37673 13.37231 16.26893 15.81663 11.01917 8.918041 9.566416 11.83768 12.05284 12.66729 11.85449 10.60257 11.00357 11.39586 10.96889 11.1296 13.36541 15.34315 17.2086 17.66689 14.65784 13.48884 12.4741 12.45936 13.42722 15.72825 15.79719 14.43064 12.889 10.51247 12.3019 12.30175 12.62188 12.04293 10.42985 10.74694 10.95862 12.90817 13.67789 14.24038 16.24807 17.4501 18.67464 18.25082 16.41788 13.84389 13.58693 15.07749 17.34456 17.16127 16.20167 15.06416 11.77578 12.49449 13.45164 13.06607 12.11281 10.48501 10.73691 11.01208 15.49132 16.34476 15.46261 17.19522 17.5746 18.0107 18.14651 16.75021 13.80587 13.41014 14.9592 17.26956 16.178 14.19134 11.93522 11.6239 12.82757 14.12765 13.70803 12.50571 10.75355 11.29876 11.34688 16.21528 16.64844 15.85424 17.58728 17.14469 17.19608 18.15673 16.2019 13.98389 14.04934 14.00954 16.88185 15.97725 14.16334 13.0995 11.42474 11.70505 13.47377 14.31889 12.8265 11.54771 11.79184 11.55733 14.441 14.84616 16.01069 17.67813 17.21562 17.56873 18.24154 16.43555 14.16117 14.16953 13.69155 17.32711 16.4162 13.46104 12.36254 11.61799 11.27409 13.07141 14.62038 12.76868 11.54521 12.79095 12.39311 14.58929 14.84247 16.09941 17.7363 16.53284 17.27621 18.18447 16.58593 14.33624 14.35762 14.19332 17.44104 17.00833 13.70702 12.45344 12.21988 13.11712 14.56761 16.01712 13.74598 12.13099 13.26468 13.10818 15.27417 15.56255 16.42318 17.98415 16.44273 16.57448 17.62833 16.28909 14.36828 14.6948 13.78254 16.22694 15.95521 14.12572 12.26701 11.85083 12.46605 14.29742 16.13456 13.84185 12.26186 12.63923 12.99921 15.56506 15.71164 16.66626 18.41392 16.23549 16.69583 17.69269 16.16858 13.91554 14.21553 13.17823 15.73793 16.4865 15.50647 12.3832 11.67269 11.71129 12.98511 15.19916 14.09333 12.14127 13.53028 13.66361 16.01434 15.8486 16.93131 18.80218 16.81364 17.33029 16.89452 15.53996 14.12277 13.81145 13.03909 15.09264 16.55081 16.00311 12.3552 12.25566 11.77334 12.40888 14.75922 13.7299 12.90318 13.40209 14.23598 16.61812 16.00201 17.09422 18.93463 16.77671 17.12045 16.87137 15.12399 13.50143 13.57805 12.80646 15.09097 16.1608 15.57011 12.32053 11.78571 11.45637 11.75474 14.11037 13.6446 12.81923 13.51655 14.85688 16.60715 15.62787 17.18843 19.15834 16.90851 16.13819 16.45988 14.99436 12.40748 12.04965 12.14001 13.26226 14.0558 13.51968 12.57948 11.99215 11.86336 12.04673 13.09016 13.15625 12.4888 12.85295 14.979 16.59832 15.41977 17.2978 19.31523 17.34639 17.72629 15.35329 13.78927 12.61048 11.38221 11.57769 13.06238 13.21393 12.3947 11.35336 11.29097 10.76642 10.99077 12.29214 12.08838 12.20228 12.01544 11.86961 12.86051 13.13075 17.29455 19.39194 17.52913 18.08251 14.94142 11.73378 12.26912 13.0758 11.84843 11.48248 13.48376 13.39672 11.70031 11.98227 11.31891 10.61537 11.5765 11.5006 12.25064 12.40025 11.37915 12.90368 12.65543 17.11082 19.30302 17.25127 17.65386 14.90019 12.53856 11.45692 13.26181 11.62685 11.53579 13.36939 12.93143 11.07778 11.12064 10.86599 10.39632 11.41168 11.49042 11.78741 12.00982 11.57957 12.68554 12.28857 16.81596 19.11267 17.10374 17.62917 15.10644 12.49786 11.83172 13.11271 12.08539 11.51897 12.27075 12.25029 10.05081 10.51726 10.23621 9.723547 11.47403 11.38655 11.75697 12.38226 11.68046 12.32908 12.25521 16.18891 18.7452 17.12043 17.90645 15.35898 12.87751 11.93357 11.34936 12.12841 12.00346 12.70253 13.15777 10.02708 9.598401 9.508228 9.663599 10.49346 10.55344 11.21704 12.04108 11.25043 12.10459 11.84318 15.3587 18.25852 17.01021 17.94506 15.36013 11.68553 10.90639 9.600526 11.48932 11.83768 11.86593 12.23622 10.37516 10.22231 9.242025 9.690022 10.79908 10.51446 10.66708 11.09983 11.20814 11.95468 11.32153 14.94686 18.0086 16.66558 16.91915 14.43537 11.78186 10.37191 10.1009 10.64833 11.51232 11.21707 11.44729 10.38132 10.89793 11.71739 11.39077 10.99349 11.08029 10.52239 10.70206 11.1781 11.64449 11.60586 15.2814 17.80077 15.7858 15.0733 13.19273 10.99025 11.4507 10.23576 11.88874 11.69319 11.04233 10.65287 11.20542 12.47354 12.96547 12.31134 12.59687 12.5441 11.05464 11.68961 12.18429 12.52163 12.24349 15.48732 17.81838 15.57828 14.95755 13.17332 11.15086 11.35037 10.27524 11.15464 11.83677 10.82353 10.86964 10.84648 12.2185 12.01063 11.35811 12.14788 12.13265 10.27622 11.16301 10.85313 11.33077 11.19722 15.64028 18.04706 15.90875 13.46693 12.71794 10.47495 10.41679 10.41669 11.51304 10.97092 10.52732 10.51946 10.18956 11.28483 11.5248 11.06633 10.79301 11.08132 10.48834 11.23098 10.90977 10.93761 11.2342 15.691 18.08693 15.95903 14.5647 13.08687 11.96817 11.98348 10.27445 10.82906 10.65066 10.7676 10.49903 10.69828 10.99068 11.62179 10.48239 10.64531 10.73122 10.30917 10.84842 11.01107 11.19445 10.96024 15.70235 17.87411 15.54562 14.17106 13.73759 13.39945 12.94871 11.86754 12.32136 13.34113 14.04813 13.64429 12.8817 14.03526 13.78847 14.31763 14.08296 12.28475 12.26945 13.41342 15.16624 15.82314 14.65862 15.111 17.38759 15.23328 14.86325 16.06344 16.10236 14.34899 14.72656 14.66246 16.20999 16.94175 17.2274 15.76645 16.78901 16.12683 16.99647 16.62846 13.99079 13.86968 16.12244 18.25901 19.34782 17.66724 15.03301 16.61184 14.17075 13.25705 14.54141 14.69707 13.71418 15.49278 15.08241 16.18828 17.16152 16.65724 15.34151 13.99803 13.97429 15.01542 15.35275 14.87416 14.55297 15.45949 16.31717 18.42344 16.47798 13.45951 15.78569 13.98534 13.04344 13.92377 14.24774 14.06853 15.00025 15.36809 16.57527 17.38427 17.02029 15.19632 14.64439 14.65536 14.64023 15.68649 15.49167 14.9104 15.35289 16.33175 18.0865 16.37584 13.07347 14.7915 12.67954 13.23848 14.1819 13.9683 13.21752 14.69234 17.90232 17.24359 17.5149 18.04125 15.55333 15.03565 14.85524 15.23376 15.60953 15.83141 15.17968 15.23778 16.42048 17.88067 16.92698 12.37712 14.9033 13.8624 13.76913 13.30324 14.3478 14.02929 14.99968 18.80645 18.39549 18.51047 18.57759 16.0035 14.5608 15.19788 16.24825 16.87722 16.25792 15.09623 15.11478 16.32289 17.68389 16.08194 12.66646 14.60857 12.63233 12.64944 13.4228 13.81045 14.2454 15.89087 17.83408 17.56272 18.75677 18.45625 15.79576 15.1664 15.52465 16.30447 17.33408 16.53073 14.91176 15.41308 16.24126 17.18274 15.97926 12.81794 14.79919 12.64581 13.73917 14.27735 12.86728 13.65656 16.11627 17.94633 17.98828 18.37813 18.78796 17.11118 16.00847 15.83047 16.21775 16.80949 15.5775 14.92074 15.60607 15.80383 16.84433 15.66324 12.5034 15.02809 13.34704 12.59922 13.16282 13.18943 13.6498 16.22042 17.74181 18.11487 19.01717 18.76182 16.68096 15.37317 16.47843 15.88386 16.60799 16.23045 15.78561 15.60193 15.58282 16.25681 16.40265 13.06095 14.47213 11.57626 11.60358 12.57563 13.76851 13.97735 14.38274 16.31401 17.55055 18.43916 18.5317 17.04531 14.99704 16.53685 17.02856 17.58887 16.26225 14.9763 14.45201 15.51912 15.21459 16.6817 12.86505 15.85786 14.75419 13.01475 12.67307 14.4433 15.20655 15.15495 16.09785 16.51936 17.95182 18.31379 16.75537 15.01732 15.75735 16.82045 17.44093 15.66828 14.33217 14.62619 15.22149 15.17155 17.20671 13.12523 16.5502 15.50594 15.34845 14.73641 15.80987 16.79601 17.06586 17.48354 16.89506 16.9989 17.87918 16.51353 15.33819 15.52597 17.10384 16.88856 15.24374 15.05034 15.51818 15.27853 14.60615 17.90415 12.69545 15.62294 14.66864 16.31116 15.64141 15.63712 16.38996 17.50281 17.90165 17.66326 17.61484 17.62272 16.00488 15.10813 14.94744 17.00407 17.49522 15.62474 15.2027 15.69592 15.58376 14.26855 17.33854 11.70221 15.91556 15.21819 16.73549 15.93421 15.34525 15.80453 16.35826 17.22446 17.98482 17.83851 17.86388 16.83107 16.10304 15.82976 17.13237 17.91541 15.26026 15.10075 15.98048 15.72246 14.22937 16.43557 12.58039 16.54533 15.48762 17.14302 16.20825 15.26482 15.79737 16.80904 17.53083 17.92554 17.57588 16.92835 16.21835 16.24897 16.26789 16.09962 16.68681 15.19278 14.3501 15.73407 15.31177 14.58012 16.44425 12.52427 16.68682 15.6768 17.41134 16.48487 16.26741 15.93352 16.79063 17.23722 17.75588 17.59963 16.55783 16.45605 16.19305 16.34012 15.8233 16.01214 14.49679 14.05411 15.83327 15.75738 14.70327 16.81463 13.08901 16.92737 15.88609 17.48892 16.60913 16.92618 15.98914 16.84229 16.96335 17.23575 17.33563 17.23502 16.5829 16.31644 16.85165 16.5601 16.59091 14.8695 14.04865 15.1961 15.04456 15.03072 16.76081 13.25131 16.82976 15.65168 17.33111 16.53403 16.99053 16.30228 16.67911 16.8145 17.26553 17.52997 17.40855 16.6225 16.19843 16.2693 16.43582 16.03738 13.90187 14.50136 15.9589 15.88366 15.52198 16.96512 12.86011 16.4959 15.32254 16.57291 15.98928 16.51817 16.59031 17.21095 17.32273 17.24012 17.26693 17.4594 16.63605 16.95958 17.0414 16.83618 16.73441 14.66106 14.54188 15.98279 15.59871 15.42995 16.82753 12.3734 16.38073 15.23618 15.71347 15.76168 16.80319 16.83652 17.01589 17.01722 16.75942 16.97372 17.74806 16.4648 16.73439 16.26514 16.33158 16.27448 13.83779 14.71891 15.37935 14.90931 15.09158 16.92881 13.16311 16.98702 15.90418 16.86047 16.45071 17.14736 16.50004 16.52925 16.95103 16.78541 16.71283 17.1481 15.68781 16.3924 15.7757 16.42943 16.24413 13.86384 14.62436 15.48191 14.93738 14.84517 16.21951 13.59746 17.23912 16.12656 17.50044 16.93601 17.43536 16.78477 16.41955 16.75596 16.41606 17.25539 17.49482 16.25328 16.44511 15.88677 16.52536 16.53255 14.46775 14.81169 15.79123 14.8385 15.43922 17.17949 13.25004 16.94229 15.93826 17.73337 17.23859 17.89079 17.34496 15.97857 15.19893 15.15988 16.91029 17.25496 16.62859 16.25416 15.48432 15.56355 16.21918 14.83444 15.0622 15.81797 15.64522 15.32866 16.89268 12.62537 16.47641 15.74364 17.85862 17.47602 18.16114 17.55453 15.95657 15.11439 15.08639 16.68707 16.74309 16.72464 16.83375 15.94381 16.12422 16.87457 15.30209 14.94832 16.63556 16.4691 15.57759 17.3871 12.6226 16.10576 15.56736 18.04713 17.56757 18.11768 17.59097 16.34696 15.375 14.14986 15.13968 15.70977 16.85783 17.35108 16.21252 16.49694 16.90446 14.97466 14.87337 16.36794 16.10093 15.90252 17.58858 12.7855 15.88645 15.67985 18.15505 17.37622 17.52381 17.42296 16.19477 15.50058 13.98604 15.38529 15.37528 15.93515 16.47197 15.3381 15.97862 16.40454 14.95582 15.0605 16.63037 15.63746 16.15078 17.13511 12.65207 15.56413 15.72229 18.15676 17.02139 16.67873 16.7427 15.08276 14.19359 12.79751 14.48611 15.64405 16.11738 15.6327 14.42156 14.5413 15.50612 14.09361 14.9137 16.91826 15.45331 16.1494 17.52712 12.56314 15.1539 15.81251 18.0403 17.20735 16.9832 15.43454 13.55827 13.10696 12.59839 13.23814 15.90523 16.60976 15.61129 13.46397 13.59857 14.55115 13.29045 14.68942 16.51844 14.84454 16.06714 16.90926 12.64222 15.16426 16.14207 18.01224 17.03122 16.82287 13.88338 12.87623 12.53724 12.11878 13.98522 15.42566 15.64351 14.8041 13.28969 13.65548 14.46269 13.32662 13.92385 14.84129 13.31076 15.09256 15.82777 12.85059 15.56986 16.29726 18.16373 16.31842 15.27977 12.30446 12.48871 12.05114 12.02475 13.32861 15.53581 15.44006 14.6188 12.19517 12.34837 13.52474 12.41385 13.52724 14.1898 12.92852 15.22741 15.49917 12.59761 14.4621 15.45572 17.18511 15.81542 15.78824 11.84854 11.87338 12.32981 11.94361 12.86972 14.26315 14.89518 14.27585 11.97713 12.49144 13.58669 12.65414 13.09633 13.75735 14.88413 16.18767 15.3166 12.64882 14.81147 14.45962 16.38583 15.72507 15.59489 12.376 11.95343 12.09104 11.86625 12.24266 13.68499 13.91463 13.24626 10.7595 12.1026 13.03325 11.85887 12.62869 13.85928 16.20368 18.33456 16.91249 12.12053 15.05175 14.22981 15.73134 14.97451 14.68129 13.12028 11.97819 11.38219 11.20992 11.37042 12.24603 13.25563 13.08652 10.43595 10.82252 11.63596 11.33452 11.86574 13.24061 15.52648 17.4119 16.81245 11.19065 14.21162 13.51477 14.70132 14.9847 15.25536 14.19143 12.48769 11.34493 9.814653 9.99059 11.53341 12.29802 11.784 10.16933 10.75036 11.20462 10.74964 11.48954 12.01296 13.41964 14.80476 14.38404 10.00999 12.74599 12.14843 14.51654 15.13391 15.2609 13.72731 11.66748 10.16199 9.022615 10.54656 11.04408 11.06597 10.65407 9.941639 9.674333 10.40516 10.81487 11.25098 11.6855 11.23007 11.83496 12.85696 10.08466 11.83495 11.54785 14.59242 13.85901 13.03223 12.44154 11.23707 9.762304 8.823195 10.68114 10.62345 10.76976 10.03955 9.436696 9.586202 11.22563 10.83237 11.0967 10.70838 10.57485 11.49634 11.70702 10.48889 12.83749 11.55844 14.30776 13.98957 13.29756 10.27051 11.19239 10.73191 8.282329 9.798191 11.28903 11.10856 10.43637 9.679453 9.696969 10.23166 10.5042 10.2436 10.84797 10.9094 11.14272 11.04821 10.19536 11.74172 11.33944 13.41399 13.06223 13.24977 10.40681 9.719469 9.504123 8.071562 9.28103 10.37499 11.08919 10.83884 9.125082 9.426393 10.12565 10.30615 10.62199 11.02502 10.98999 11.49767 10.76202 10.88223 12.977 11.56636 10.88618 12.75476 12.96493 10.24409 9.20118 8.650577 7.399164 8.780226 9.993423 11.50119 11.16004 9.309609 9.911741 10.38707 9.787494 10.5507 10.78142 10.8794 11.07239 10.47661 10.47173 13.69682 12.45944 12.35382 12.58801 12.46847 10.00025 10.27305 11.53972 12.61611 13.00516 13.0168 12.24968 12.74772 13.46355 13.35037 12.67452 11.07662 10.77348 12.34726 13.52226 13.54476 12.45269 10.39999 12.38218 11.96567 12.83998 11.78783 11.14596 10.65086 9.983682 11.39105 12.32884 12.81081 12.60661 11.70481 12.39304 13.20282 13.14799 12.67365 11.12111 11.64005 15.3785 17.26889 19.2809 18.58731 10.06194 11.97701 11.10652 11.85843 11.02539 11.2265 10.7828 9.873035 10.32476 11.25525 11.96012 12.71968 11.64478 11.76205 12.47315 13.18736 12.99789 12.38262 13.63724 17.6046 20.06792 21.4036 21.43807 9.509731 11.85916 11.10777 12.50954 12.18235 11.80091 11.27237 10.29496 12.2601 12.32322 13.42 14.12483 13.16052 13.71877 13.45849 13.22503 14.22825 13.49225 15.37626 19.22064 21.55962 22.73142 22.24018 9.15207 11.07175 10.86126 11.87928 12.69756 12.46886 11.5245 13.08445 13.88625 14.80505 14.99481 15.52319 15.05282 15.02273 14.87423 15.29251 15.91438 14.93134 16.80274 21.40077 22.54545 22.58663 22.29738 8.860111 10.74111 10.50416 12.93807 12.55079 13.06175 12.17259 13.51095 14.48125 15.87022 17.08365 15.86352 15.00874 14.95488 15.34727 15.18754 16.02795 15.03839 16.93264 19.53366 21.6056 21.50261 21.28786 10.75877 10.37344 10.58075 12.34408 12.94353 11.96778 11.4975 12.68404 14.95128 16.74927 16.77153 15.63198 13.98707 14.3226 14.68699 15.35497 16.36192 15.49951 15.98009 17.65331 18.19219 18.41393 18.1715 9.39485 10.52738 11.42019 12.21228 12.45682 12.18025 11.33037 12.44518 14.51794 15.84477 14.62877 14.42839 14.07113 13.2896 13.65752 13.82688 15.6779 15.75582 15.67209 17.08607 16.55664 17.27306 16.92216 9.381274 11.83695 11.8863 11.62455 11.99966 11.92766 12.16977 12.76743 14.2169 15.01731 14.82383 13.0397 13.42383 13.10484 13.42112 13.71131 14.73178 14.64882 14.79978 16.09834 16.16719 17.4647 16.77292 9.585428 10.993 10.5035 11.81598 11.44083 12.43314 11.64416 12.2522 14.10823 14.41961 14.19406 12.61582 11.76546 12.10949 13.28017 13.21444 14.49621 14.27315 14.40105 16.25966 16.55149 17.44991 16.81313 8.175888 11.18484 11.35472 11.47145 12.36835 12.95294 11.74024 12.37499 14.70968 14.42316 13.73902 12.62927 11.59597 12.07641 12.50259 12.79706 14.06515 14.19124 14.13676 15.15194 15.65369 18.23908 17.15416 9.260625 10.70815 9.263671 9.806908 11.83224 12.31308 11.73443 13.4353 14.60034 15.05972 13.83386 12.88395 11.57649 12.02801 12.20291 12.59455 14.31687 14.47969 14.6405 15.52516 15.67438 18.1055 17.65921 9.911335 10.50611 10.12131 9.937845 12.0217 12.06643 12.41577 13.58587 15.64432 14.32141 13.08726 12.30006 11.95351 12.71829 11.26942 12.65187 14.17917 13.53116 13.70112 15.10717 14.98607 17.59751 17.46946 9.024209 8.987809 9.160165 10.86254 12.75719 12.29259 12.99271 14.01397 14.93609 15.38431 14.07591 12.15879 11.33199 11.99755 11.29723 12.28741 13.99432 13.90781 13.2847 14.09958 14.27385 16.84444 16.68974 11.9299 13.47678 12.837 11.34953 12.98505 12.79702 14.93977 14.99091 14.8044 15.23901 13.70815 12.30987 11.19355 11.14724 11.14456 11.97139 13.38016 13.39131 13.10051 13.16111 13.63137 15.1045 15.48153 14.41228 16.11685 15.7402 15.5474 13.80078 14.53132 14.65797 14.65964 15.91533 16.35481 13.96598 12.8188 11.46816 10.90168 10.61743 11.47446 13.77556 13.64553 13.89567 13.91599 13.57935 15.20967 15.69138 15.08783 16.8548 16.49383 16.41818 14.09665 15.30241 14.7049 14.89885 15.83918 18.0921 16.22671 14.06109 11.65885 11.18969 11.55042 12.64634 15.04636 14.6538 14.17054 14.18222 15.13279 16.13375 16.41827 15.16109 16.7801 16.56729 16.43837 15.12475 14.8846 14.26196 15.39288 16.01123 17.1432 17.07575 15.71479 12.39699 11.93664 11.86322 12.98023 15.49663 15.14287 14.6057 14.86261 15.40321 16.85805 17.07797 15.09084 16.57223 16.80362 16.58635 15.20792 15.10697 14.90998 15.40153 15.35094 16.88487 17.96318 16.37918 12.55137 12.20782 12.30409 12.03328 14.67583 15.03111 14.56669 14.42755 15.211 17.10543 17.10053 14.69408 15.81541 16.46612 16.37843 15.2229 14.59921 13.61355 14.3778 14.58977 16.18752 17.5792 16.62926 12.41473 12.08434 12.35257 11.9434 14.27981 14.79067 13.80497 13.96159 14.25573 17.45439 16.78282 14.43095 15.41959 16.21408 16.07892 15.18807 14.0085 13.96235 14.37799 14.08463 15.0561 16.641 15.33981 12.0121 10.58257 10.67117 11.07191 13.45955 14.30978 13.5234 13.39615 13.00758 15.30398 14.59562 14.58677 15.82187 15.58251 15.65558 15.2996 14.34471 13.48909 13.53928 12.62957 13.79965 15.50717 14.88582 12.17444 11.02395 10.55875 10.28314 11.87372 12.80804 12.80521 12.87114 12.06493 14.00245 13.72964 14.95683 16.3266 15.16857 15.4292 15.51012 13.59986 12.23133 12.66695 12.21721 13.14255 14.3418 13.26337 11.4309 11.01019 10.59134 10.42654 11.62912 13.19194 13.29006 13.23644 11.81969 14.27526 13.76118 15.59626 17.08241 15.06971 15.65379 14.82292 13.31317 11.43343 11.9617 11.85537 12.2777 14.29009 13.45866 10.72894 10.13381 9.537953 9.800446 11.53536 12.31185 12.60432 11.92848 11.34388 12.84455 12.54369 16.04304 17.82648 15.79309 16.24393 14.73321 13.42411 10.97739 10.73002 11.65459 12.07827 13.2604 12.44436 10.10683 9.841578 9.451722 9.291868 11.41494 11.8923 11.88242 11.91761 11.27107 12.20158 12.1325 16.25625 18.22469 16.04192 16.12708 14.96282 13.00054 10.65593 11.17855 11.14046 12.55776 12.52015 11.42063 9.433226 9.00628 9.585645 9.290247 10.70464 11.49628 11.68974 12.07785 11.17581 11.06459 11.13168 16.04482 18.14673 15.86384 14.91284 13.05532 12.45239 11.72008 11.51588 11.29592 11.78518 12.2973 11.38977 10.29393 9.548064 9.722668 10.09043 10.84775 11.8718 11.26131 11.56782 11.02544 11.18756 11.03338 15.26615 17.28764 15.16505 14.44016 13.28143 12.07429 10.97578 11.15899 11.50891 11.01097 11.61723 11.36335 10.16722 9.822009 9.901525 10.20638 10.18853 11.82158 11.44402 10.68624 10.50383 11.11971 11.41882 13.81127 16.00517 14.23292 13.67491 13.21358 11.73995 9.486867 10.56567 9.862735 10.49043 11.29869 10.67811 9.464268 9.29777 9.709767 10.42091 10.48922 10.93209 10.42687 11.04964 12.2851 12.72577 12.39185 12.14262 14.94287 14.0802 14.32626 12.80348 10.66512 9.237948 9.739904 9.596913 10.61011 11.65724 10.63011 9.505305 9.886621 10.47523 11.0215 10.59563 10.78076 11.00128 13.60528 15.06756 16.77889 16.86555 10.83472 14.31258 12.90632 12.77348 12.20279 9.816229 9.277019 10.18015 9.096459 9.997322 11.51482 10.87203 9.44985 10.83187 12.01145 12.17475 12.17965 11.82202 12.18132 14.90107 17.46739 18.73794 18.04218 11.36189 14.46365 13.13914 12.11007 11.7593 10.0019 9.75862 10.77737 11.03628 12.26316 12.78038 11.30242 11.24927 12.86973 13.40784 13.56777 13.70109 13.02316 12.83176 16.09006 18.6455 20.18859 19.64919 12.72338 15.11341 13.32158 12.74039 11.63489 10.73177 10.17774 10.56085 11.74206 12.8467 13.64448 12.64196 13.06981 14.0199 13.50293 14.09397 14.45456 13.70243 13.05322 16.6385 19.08248 21.01362 20.21127 14.20404 15.91786 14.92538 15.12413 14.77285 12.89441 12.79587 11.85586 12.40155 12.80069 14.29893 14.05416 12.61579 13.57712 13.58947 13.30546 13.65021 12.84343 13.35256 14.62488 16.85373 18.83813 18.01679 14.53132 17.33943 16.26635 18.11593 17.92229 16.41659 14.97751 13.63034 14.93866 15.25947 16.20634 15.82948 14.33713 12.11738 13.05697 13.88322 14.07832 13.04026 13.09391 14.61522 14.58644 16.06195 17.62827 14.11968 16.69542 15.12335 18.32276 17.78468 17.74669 15.92803 14.50374 15.56971 16.23568 16.50482 16.08389 14.88408 13.72153 14.5031 14.91234 14.72964 13.03544 12.99891 14.99354 14.95278 15.26584 17.54221 12.58309 15.06906 15.59264 18.20675 17.21118 17.89225 16.83617 15.57529 15.21058 16.55922 16.91265 16.39316 15.46596 14.28004 14.31382 15.09121 15.5357 13.50103 13.16001 15.68369 15.05554 15.30483 17.25786 13.38149 16.1832 16.11864 18.42098 17.48438 17.89621 18.30592 16.22846 16.11395 16.84072 17.24339 16.6131 15.43338 14.83396 15.42686 15.86161 16.32101 15.09858 13.3338 15.44106 14.9978 14.34465 16.55215 14.37599 16.83687 16.94507 18.2267 16.84422 18.06699 18.55002 15.54701 16.76327 16.83081 17.27568 17.00946 16.32395 15.44895 15.63621 15.85781 16.74874 15.47261 13.73446 15.28013 15.02808 14.89976 16.14604 15.05994 16.78429 17.38232 18.71122 17.29902 17.89909 18.18792 17.06817 16.19571 16.4189 16.93696 17.02257 16.01795 15.9466 15.9529 16.66254 17.07906 14.79625 13.80007 15.45906 15.62278 14.89583 16.3634 15.31985 17.11125 16.90094 17.50673 18.12416 17.26594 18.61826 17.81363 16.92988 17.33131 17.22307 17.6853 17.16475 17.8327 17.79674 18.01369 18.75657 16.41342 14.83692 16.64419 17.08493 16.10439 17.74908 14.81287 16.67113 17.24438 17.58853 16.56671 17.4409 19.14317 17.1272 17.22141 17.37194 17.30178 17.35553 16.81259 17.59592 17.2289 17.99676 18.54756 16.97488 15.1711 17.01239 17.41453 16.61493 18.02877 14.10214 16.48185 16.70473 17.83863 17.09863 17.92168 18.60074 17.03748 17.01916 17.1662 17.45386 16.9503 17.22705 17.88758 17.25076 18.06163 18.82708 17.06891 15.6639 17.32082 17.86867 16.99368 18.4935 14.47095 16.27239 17.20447 16.68737 16.69925 16.92639 17.55458 16.4129 16.37072 16.70506 17.13801 16.74328 16.66209 17.66596 17.03108 17.52262 18.5179 16.57609 15.3233 16.59836 16.57953 15.76227 17.69633 13.24856 14.56392 16.16074 15.96923 16.11824 17.0615 17.37887 16.89696 16.49023 16.93359 17.04477 16.61666 17.3206 18.46787 17.4531 17.96162 19.10358 16.9934 15.63334 17.35444 17.27749 16.49334 18.51469 13.37477 14.40732 15.3166 16.12179 16.0549 17.9857 18.24229 15.97747 16.51573 16.80781 17.66976 16.77187 17.07391 18.37435 17.8941 17.99025 18.43793 16.58463 15.94918 17.33995 17.58286 16.71625 18.26147 13.93172 15.95009 16.12278 16.62806 16.77155 17.70332 18.30991 16.70022 16.12438 16.63647 16.96805 16.56441 16.83017 17.72108 17.19194 17.83681 18.34489 16.32563 15.5139 17.0459 17.14361 16.61393 17.9541 13.97243 15.71532 14.24013 15.94024 16.42779 17.24181 18.20842 16.16203 15.17454 15.77178 16.21501 15.67723 16.35604 17.39831 16.76721 17.22853 17.88738 15.95963 14.72727 16.41531 16.48671 16.12189 17.57236 13.12301 15.36403 14.92359 14.51013 15.03061 17.25054 18.02694 15.68099 14.72595 15.05695 15.51794 15.62031 15.82822 17.21599 16.45444 16.81317 17.53438 15.40422 14.59688 15.75735 15.82233 15.50435 17.19834 13.63734 15.75846 15.76891 16.33092 16.02224 15.02408 15.51878 13.95916 13.93933 15.34064 15.0723 15.51362 15.4393 16.63021 16.81165 16.50006 17.1815 15.69489 14.01058 16.13823 15.96146 15.71183 17.02876 13.19862 15.13811 14.20608 14.87641 13.86195 15.69343 16.0471 14.37471 12.70754 13.07089 13.74677 13.72397 14.30151 15.42236 14.87322 14.77012 16.19817 14.61831 14.36353 14.7163 14.1343 13.27196 14.94497 13.07108 14.96432 15.33887 15.41621 16.32788 16.2543 15.70077 13.64809 12.23586 13.97429 14.36621 14.99106 14.89284 15.73454 15.09936 16.08811 17.21342 14.54043 14.93736 16.18698 15.30752 15.68343 17.1031 12.17307 13.8663 14.74691 13.82833 15.29623 15.13898 14.94032 14.15431 13.22405 12.60576 13.50053 13.70859 14.2374 14.95605 14.1026 13.79868 15.32834 13.637 13.26627 13.85343 12.49579 13.00945 15.18009 12.25888 13.0473 13.98215 15.20883 14.53955 14.94806 15.02145 12.94323 12.06552 12.47472 12.65622 12.89004 14.31748 15.0515 13.45358 13.49286 14.73266 13.38384 12.97834 13.98633 13.04967 14.18903 15.84389 12.96655 13.67219 15.57411 16.78977 16.06032 13.93955 14.09687 13.42214 11.74005 12.39577 12.6212 13.11872 14.73195 14.7253 13.47528 13.54747 14.39114 12.98527 13.10725 14.80631 13.07693 14.86841 16.53499 10.92069 13.71753 13.87495 14.55451 14.22817 13.57006 13.76763 12.60664 11.17306 11.62393 12.25004 11.81037 13.68605 13.56421 12.86382 12.15489 13.24436 12.0221 12.38628 13.08033 11.34459 12.62064 14.02351 11.5769 13.79373 14.03928 14.87669 13.80563 13.71551 14.04329 12.57617 11.19479 11.37623 10.92707 11.98935 12.46576 12.69549 12.09219 11.78906 13.35041 11.86954 12.23488 13.13238 10.95979 13.09149 14.30729 10.74847 13.18716 13.24313 12.67642 13.39273 12.77279 12.68126 11.46781 10.00143 9.96587 10.43531 11.69773 12.84946 12.46179 11.33073 10.75771 12.40113 11.34042 11.7729 12.49863 11.20993 11.8419 11.45071 11.98419 13.92745 12.27599 12.76547 12.93638 12.34464 12.64864 11.34802 10.23944 9.272176 10.22678 11.26323 11.94163 12.36338 11.0064 10.31246 12.27957 11.23496 11.376 12.09842 11.01261 11.91821 11.30618 11.78683 13.45012 12.74603 13.96315 13.49791 12.03139 12.34809 11.16278 9.914504 8.632698 10.02429 10.49186 10.53503 11.25449 10.37139 10.6025 11.64441 10.73072 11.01634 10.47035 9.727706 10.35247 10.77614 11.52162 12.46663 11.89697 14.03308 13.64052 11.73958 11.48232 9.956855 8.571227 8.986975 9.7626 10.39963 10.45375 10.46915 10.78598 10.67382 11.57074 10.30212 9.981796 10.63711 10.12906 10.43168 10.83299 10.47112 11.29303 12.18044 11.88793 10.8442 10.59727 11.06464 9.595164 9.016017 8.599607 8.99171 9.042683 10.83571 10.81611 9.935513 10.24435 10.53577 9.991421 10.32891 10.49404 10.43093 10.59912 10.33619 11.11114 12.00806 12.1118 11.56301 11.28773 11.11582 11.11947 10.14109 9.354194 9.394133 8.459903 9.571765 10.62552 10.94563 10.39587 10.17176 11.07636 10.36478 10.18448 10.5289 10.58135 11.55 12.22885 9.4698 10.58114 11.28397 11.78697 11.88663 11.19909 11.94986 8.947301 8.886659 9.0145 8.525748 9.001356 10.4408 10.03337 9.662758 9.838831 10.64479 9.835432 9.941095 11.35219 12.8765 13.6802 13.69769 9.431818 10.37749 9.402466 11.65605 12.08712 11.54609 11.73875 8.867339 9.922234 10.61318 10.76134 10.87708 10.16173 10.49702 11.13492 10.97119 10.87446 9.942475 10.69347 12.76756 14.78555 15.63049 15.3683 9.377582 10.94667 11.15134 12.46202 11.73515 10.88063 11.25175 9.65536 11.14065 11.88232 11.94413 11.89391 10.90223 11.40995 12.1747 11.62114 11.59762 10.78957 11.37593 13.46099 15.81433 17.16356 17.15998 9.576265 11.13453 10.96931 10.33049 10.23858 10.44758 10.76839 8.92027 9.525447 10.34433 9.90531 9.858282 9.904203 11.16824 11.88748 11.96853 11.37809 11.49845 11.76391 14.43392 16.65162 18.26472 17.6829 9.068971 10.9832 11.37302 11.22971 9.851135 9.574883 9.735991 9.078069 9.105554 10.11883 10.55576 10.29943 9.432137 11.80125 12.00973 12.56134 12.2724 12.0964 12.37772 14.91978 17.71165 19.49631 18.86863 10.06087 11.30585 10.13232 9.214253 8.846772 9.325168 10.23292 9.699574 10.61134 11.65377 12.32304 11.8669 11.56203 13.31346 13.75598 14.85218 14.10346 13.62769 13.95514 16.67099 18.7434 19.90597 20.01846 9.883128 9.034005 10.26573 9.922016 9.431784 8.751758 10.03959 10.56669 12.11162 13.17491 13.19539 13.8256 12.93738 14.20389 14.85687 14.53677 14.83226 13.86686 14.76633 17.12251 20.07998 22.08923 21.37822 9.735471 10.76163 10.26859 10.09679 10.99103 9.163989 9.649745 10.54053 11.75659 12.85315 12.67314 13.1372 12.42263 13.90682 15.30728 15.41667 14.59862 14.48736 15.16387 17.94337 20.98712 23.08864 22.34081 8.208311 9.269901 9.024371 9.993098 11.19902 9.208381 9.769848 11.40966 12.96586 14.02102 14.22982 14.19959 13.32056 14.34479 16.31928 16.57144 15.62925 14.52523 16.18148 18.67118 20.88604 23.1573 22.48557 8.409505 9.858494 9.497688 10.31458 11.88834 9.982258 10.32621 11.68756 12.89914 13.39427 14.21135 14.64743 13.3156 14.29278 16.14828 15.96886 15.35177 15.5271 16.91822 18.72905 21.57679 23.61708 23.15364 8.934703 9.573559 9.441955 8.765581 10.14542 9.618201 10.5309 11.58863 12.7027 13.85705 14.36015 14.13195 13.7818 15.45178 16.22048 15.6483 15.75696 15.26135 16.86555 19.28024 22.11215 24.40104 23.93007 8.684306 8.866581 8.434036 8.029984 10.91321 11.22698 10.23968 11.33583 12.85784 13.39227 14.42832 14.13936 13.58225 16.27074 17.07727 16.51017 16.3993 16.14433 16.99274 19.69513 23.2365 24.59908 24.04222 8.643711 9.807123 9.50042 9.324292 10.83774 11.15303 10.39372 11.22418 12.95454 13.35421 14.3774 13.54205 13.72393 17.05115 17.68932 16.12386 15.83425 16.01268 17.58204 19.77008 23.01275 24.67944 24.14307 7.688036 8.535404 9.236469 10.83574 11.49044 11.28016 11.46384 12.16683 13.50681 13.8899 13.76011 13.80902 13.72299 16.50299 18.20104 16.61069 16.52741 16.1986 18.36386 20.11685 22.81937 23.6178 23.35131 10.17826 8.205004 9.347319 12.3267 13.34488 11.22051 10.90597 11.83232 13.47991 13.05177 12.89349 13.7592 13.9114 16.77988 18.02056 16.96051 16.41222 16.26488 18.08109 20.25217 22.95943 23.70821 22.32704 9.040493 8.760096 8.527176 9.89751 10.56365 9.972799 10.10701 10.67076 12.86245 12.45882 13.2768 14.06905 14.12293 17.41031 18.83172 16.48821 16.42317 16.09177 17.95219 20.02211 23.01787 23.78878 22.42188 9.399467 7.837672 9.216712 10.6783 10.54392 10.52287 11.50509 11.89538 12.42534 13.73793 12.68215 13.53249 13.51577 16.23136 18.68464 17.29062 16.49525 15.83475 18.22473 19.69581 22.15342 22.9642 22.44792 8.776668 9.244227 9.925127 11.38309 10.78001 10.8051 10.342 11.05655 12.77748 14.84761 13.69246 13.08996 13.35411 16.14378 18.69108 17.32467 17.7679 16.45478 17.57494 19.5618 22.46428 22.97581 21.49464 8.894381 9.427493 10.64883 11.46896 10.78124 9.074279 10.21656 11.47114 12.82468 12.99811 12.95543 12.60641 13.26145 15.72201 18.2295 17.42356 17.95378 16.7246 17.54635 19.24829 21.3367 21.933 20.77688 9.042042 8.76036 10.59839 11.72806 12.2252 10.01876 10.65936 11.28481 12.38915 12.18661 11.73761 12.19487 12.95884 15.87654 18.47887 17.35869 17.52493 16.28156 16.84913 18.45013 20.72539 20.79898 19.75169 10.06297 12.90782 12.88049 10.60552 11.71332 10.51397 9.21656 10.82334 11.41065 12.40258 13.10792 13.42447 12.83565 15.32679 18.56764 17.4046 16.69835 15.57237 16.41321 17.4268 18.71982 19.50741 18.1189 9.921656 16.52995 17.53824 15.70275 15.32331 12.92085 12.47987 12.10413 12.42868 12.15174 12.5522 11.8612 12.07436 13.91121 17.06873 16.3721 16.04488 15.49017 15.58386 17.01062 17.89955 17.60539 17.31772 11.36264 17.33499 18.40477 17.00244 18.4658 15.7809 13.04894 11.71813 12.67283 13.29064 13.457 12.057 11.66851 13.66247 17.68314 16.57116 15.98984 14.92666 16.06848 17.17213 17.39293 17.66684 17.4516 10.62282 17.60542 18.32822 17.09484 19.33393 16.77328 12.53772 11.13757 13.03852 14.02408 14.38111 13.17555 12.76845 14.38874 17.52058 16.74355 16.38338 15.24556 15.39419 16.26055 16.64132 16.97384 16.89183 10.47606 17.70844 18.43419 17.68979 19.75669 16.95199 11.87117 12.01979 13.45656 14.36295 14.81179 13.49354 12.68675 14.77314 17.4999 16.20375 15.68843 15.2202 15.67017 16.32603 16.47589 16.68805 16.65318 10.98051 17.72518 18.46542 18.05853 19.93608 16.77472 12.27509 12.2058 13.27803 14.52329 15.10997 13.82026 12.10452 13.67547 16.55763 15.52405 15.14251 14.49046 15.37576 16.78892 16.64076 16.92625 17.4085 10.61574 17.7157 18.246 18.44892 20.22108 17.01719 13.5045 12.65141 12.83893 14.40987 15.02312 13.29914 13.55334 15.01744 16.19461 15.84118 15.6518 14.68441 15.11373 16.25138 16.23415 16.90338 17.4352 10.69256 17.79112 18.42277 18.3324 20.11359 16.95714 13.75263 13.08895 13.11321 14.44533 15.22537 13.40903 13.27475 15.41946 15.46931 15.14482 15.65731 14.71926 15.28069 17.00951 16.92454 17.32482 17.49486 10.73899 17.75406 18.27556 17.87709 19.47082 15.97545 13.59863 13.1574 13.07014 14.04729 14.62672 13.32558 12.45246 15.42138 14.76762 14.0249 15.21964 14.52955 15.10038 17.08111 17.13165 16.41658 17.86931 9.618335 17.47857 17.98661 17.55681 18.80152 14.7733 13.48202 12.65518 13.07832 13.56103 13.67241 12.99241 12.99369 14.52666 14.21892 14.50008 15.0451 14.01138 14.70819 17.09094 17.17188 17.34347 17.56815 11.57962 16.64433 17.44956 16.3053 18.07066 14.92957 13.12261 12.80251 13.23727 13.17543 12.1275 12.36365 13.38163 14.66714 14.47845 14.50121 14.2356 14.29019 15.07313 17.368 19.52579 21.40561 20.27804 10.79007 16.8456 17.36958 16.39471 18.20171 15.12339 12.79474 10.63306 11.83869 12.54484 13.22725 12.38338 12.43016 14.38861 14.98121 15.43519 15.47331 14.8543 16.05373 18.43741 20.38091 22.39174 21.13035 11.29912 15.8077 16.54896 16.36229 18.221 15.09686 11.11965 9.979053 10.83024 13.19693 13.55953 12.65395 12.45233 12.89222 15.0179 15.60445 14.92871 14.3497 15.49676 18.35275 19.81606 22.24131 21.26899 10.58634 15.52423 16.11585 16.42515 18.17402 15.00347 10.48176 11.49412 11.44849 12.50072 12.81663 12.37796 12.68344 12.88461 13.50673 14.09901 14.95052 14.7693 14.78594 17.34875 19.04901 21.56851 20.89043 9.614183 15.8431 16.38121 15.86494 17.58311 14.49032 11.02957 10.22538 9.527282 10.68686 12.11254 12.43469 12.31795 13.20986 13.51692 13.65216 14.22145 14.17002 14.99944 16.96408 18.17498 20.48696 20.18502 10.00105 14.93148 15.57334 14.18313 15.84909 13.41543 10.91846 10.40649 10.04232 11.3954 11.08972 10.65496 11.28233 12.84103 13.64318 13.3043 13.51652 13.92885 14.5559 16.84107 18.5327 20.81325 20.21984 8.364077 14.47285 15.08788 13.55744 15.35808 12.38914 10.11354 10.69198 10.48146 11.39112 12.41379 12.30688 11.5294 12.61159 13.42383 14.04588 13.40064 13.34902 14.46458 16.70078 18.35919 20.76412 19.943 9.641496 14.35918 14.95244 14.19986 15.70295 12.1898 10.18897 9.93488 11.01549 11.42438 12.44854 12.86371 11.5565 13.17326 13.65934 14.53895 13.90649 12.75882 14.03429 16.0668 18.27451 20.19135 19.50024 8.998137 15.16441 15.34586 14.19052 15.65328 11.88099 10.49521 10.64151 11.44318 12.29878 12.59886 12.93051 11.39418 13.67889 14.56925 14.55365 14.10461 13.24354 14.07761 16.63885 18.53308 20.30708 20.31402 8.946667 14.58632 14.90333 13.99691 15.40372 11.7403 9.425845 11.23817 12.30968 13.13296 12.68324 12.09499 11.59824 14.54168 14.32594 15.0352 14.37218 13.71023 14.06014 17.93824 19.09838 21.4241 20.9504 9.447927 13.22877 13.59622 13.29706 14.72807 10.7798 10.31542 10.73058 12.23221 13.26059 12.40936 13.92871 12.75949 13.78177 15.05717 15.43973 15.04269 14.58284 15.24181 18.27596 20.08396 22.0071 21.56488 8.942842 12.3533 12.72897 12.85406 14.50646 11.68498 10.16205 11.14519 12.01001 13.16905 12.63423 12.60056 13.09376 15.80599 15.64569 15.43857 15.37898 14.46924 16.22836 18.90742 20.43498 22.41726 21.382 9.982429 12.81441 13.19554 12.47804 14.03025 11.90199 10.44281 10.78242 11.68254 11.92076 12.58015 12.23102 12.68594 15.57787 14.6662 15.05085 15.23528 13.82845 15.80674 17.82709 19.04893 21.38214 19.97395 9.869902 15.98693 17.0225 15.82257 16.53093 14.39392 13.55346 13.0189 13.5896 13.15744 13.18752 12.97133 12.9559 14.33525 13.73748 13.04741 14.4363 13.70424 15.57391 16.99634 17.09068 17.86176 18.46799 11.20318 16.74047 17.93852 17.55423 19.5529 17.38312 15.2714 13.70905 14.90142 15.34691 15.5448 12.94791 14.09873 15.03901 14.75121 14.84058 15.57433 14.77669 15.42783 17.23933 17.08564 16.54724 18.42886 10.00581 16.99308 17.64376 17.35759 19.84209 17.72609 16.06901 13.94531 14.6718 16.30286 16.95507 13.571 14.54512 15.59432 15.28288 16.09251 16.91068 14.48281 15.62211 16.89838 16.95857 16.07769 17.91624 10.26451 17.10342 17.68718 17.12966 18.80752 16.72883 17.11706 14.18921 15.08757 17.02866 17.63015 14.70868 14.18901 15.36524 15.08402 16.53765 17.53717 14.94885 15.30448 16.46144 16.25202 15.7747 17.48356 10.57615 17.0614 17.78706 16.76842 18.19138 17.44588 18.12214 14.26881 15.37736 17.35711 17.82368 16.12888 14.66693 15.406 15.11084 16.10291 17.21349 14.85879 14.25072 15.92479 15.79147 15.51069 17.19426 9.48652 16.911 17.18489 17.25456 18.75069 18.27182 18.70464 15.1519 15.75929 18.05139 18.79077 18.19505 14.61217 15.21042 14.50809 16.6024 17.5759 14.97376 14.62691 15.54537 15.83502 14.67196 16.36763 9.985225 16.74782 17.24112 17.25887 18.27095 18.51624 18.83493 16.13771 15.24101 18.14103 19.13589 18.64982 14.49468 13.72041 14.16209 16.20668 16.41984 14.58272 14.20643 15.07785 16.00739 15.01148 16.37612 8.453218 16.44852 16.53209 17.24354 18.39434 18.03302 18.01833 17.08058 14.58579 18.43371 19.00238 18.1741 14.07615 12.95393 12.84746 15.36702 15.92542 14.33508 13.597 14.46982 16.11521 14.52893 17.01237 9.352406 16.0076 16.35685 16.47454 16.98188 17.873 17.68334 17.51781 14.67671 18.76287 18.72811 17.72148 13.38931 12.69698 13.39213 14.65827 15.30858 15.00858 14.27974 14.66115 15.79502 13.98777 16.22205 9.672524 14.51215 14.49281 17.57202 18.71115 18.5533 18.56325 18.01528 15.20035 18.96259 18.58512 17.13366 13.41415 12.05879 12.61457 14.21013 14.71272 14.4392 14.22963 14.40962 15.35258 14.32724 15.84399 9.294844 14.85708 15.12689 17.73894 18.71831 18.47003 18.26656 17.68312 15.53754 18.16326 17.79104 15.80158 12.8884 11.75445 11.60362 14.12353 14.61159 13.81479 13.50152 14.23705 15.36493 14.26479 16.47873 8.768968 15.45139 15.69153 17.49653 18.18467 18.7153 18.61305 16.95576 17.30786 17.01988 16.78725 15.96744 13.20623 11.91497 10.71408 13.16159 14.11679 14.18742 13.99787 14.10843 14.59204 14.09456 16.28277 9.966001 15.72716 15.85344 17.40161 18.01343 18.25241 18.0155 17.06878 17.53317 16.64179 16.41474 15.78998 13.04946 11.22962 10.81054 12.68965 14.08202 14.16896 13.95166 14.16778 15.26385 14.41844 15.19306 9.675585 15.72316 15.94752 16.87626 17.34341 17.19278 16.94996 16.84417 17.60019 16.79139 15.83696 14.38576 11.87001 11.4011 11.60792 12.10766 13.4803 13.23835 12.92072 14.22253 15.03658 14.08519 14.59369 8.843268 15.32752 15.28943 16.05486 16.22001 15.98866 16.2473 16.98972 17.01772 16.9006 16.29029 14.78596 10.99794 11.25592 11.78223 12.48373 13.76172 13.57825 13.22475 14.14124 14.77772 14.18768 15.47867 9.988932 15.02293 15.06712 16.10529 16.68101 14.5116 15.2082 16.47553 16.51361 17.52498 17.05329 14.73698 11.47603 11.26132 11.55777 12.60618 14.0904 13.70418 12.92093 14.22556 15.54817 14.19895 15.33703 9.373691 14.60107 14.44204 16.04573 16.79593 15.65233 15.8361 15.7082 15.76369 17.70542 17.72066 15.61394 12.20694 11.29502 12.29862 12.74661 13.96791 13.84649 13.18555 14.58438 16.68427 15.04027 15.47512 9.678563 14.24788 13.43199 15.21713 15.649 16.42124 16.40302 16.3937 15.09498 16.95411 17.4481 16.14875 12.54013 12.54267 13.3262 13.59261 15.50308 14.9336 13.64636 14.634 16.40599 14.55039 15.61549 10.3574 15.14911 14.75568 15.57308 15.29968 16.94623 16.488 16.12799 15.32639 15.1618 16.76408 16.33082 12.41711 12.65482 13.66632 13.70024 15.7187 15.12583 13.7085 15.76237 17.63751 14.65858 15.68508 10.7973 15.52072 14.91968 15.44418 16.11236 16.58336 16.3113 15.46747 14.99532 15.4524 15.88347 15.21543 12.29164 12.56826 12.42722 12.49476 14.77974 14.30123 13.07562 15.28318 17.01124 14.17749 15.07545 11.72055 14.70813 14.33016 15.86267 16.10855 16.00652 15.79218 14.71058 14.24063 14.49434 15.89563 14.62785 13.76968 14.33625 13.71839 14.10913 14.64376 14.01509 13.78574 15.50584 16.63034 17.31616 17.19594 11.63814 14.6362 14.03121 15.15585 15.78361 15.6864 15.34269 14.2795 14.29758 15.06682 15.55843 14.9841 14.52794 14.38037 14.58176 15.49519 16.01623 14.98994 16.1685 17.89346 19.66196 20.41212 19.85152 11.20878 14.61073 14.74267 14.05825 15.03689 14.27688 13.934 13.7751 13.63184 13.97793 14.57368 14.39714 14.21094 14.06395 14.52638 15.53573 16.57571 15.51742 17.78471 19.37989 21.206 22.15632 21.33591 10.45609 14.74396 14.32149 13.18418 13.62141 14.69138 14.50593 13.22618 13.50317 13.10417 13.68227 13.81558 14.411 13.72738 14.54855 15.41036 16.20938 15.58582 17.08364 18.51379 20.73615 22.85728 22.03742 9.892098 14.23401 13.93373 13.37699 13.63826 14.14518 13.86748 12.95281 12.58174 13.15587 13.58239 13.93001 14.0541 14.45245 14.81557 15.24402 15.24497 14.92806 16.91828 19.23318 21.00042 22.89181 22.22411 8.341251 13.11608 13.08356 12.63929 12.80791 12.68776 12.75128 13.05065 11.75436 13.81135 13.41625 12.83436 13.37474 14.62833 15.19703 15.31099 14.71062 15.49001 16.62827 18.99271 20.98364 22.86999 22.26387 9.033696 14.0476 13.55966 12.04009 12.19411 12.87305 12.72984 12.89095 12.6282 13.35929 13.01105 12.84826 12.64545 13.73565 15.17793 15.06093 14.961 14.88946 16.90281 18.75511 20.67654 22.07957 22.50922 9.733017 14.11259 13.47146 12.15287 12.6395 12.34159 11.76064 12.4338 12.91527 13.87755 13.5646 12.60468 13.0273 14.35512 15.41535 15.23291 15.34092 14.8519 15.97584 18.7154 21.41322 22.42959 23.02157 8.697401 12.64109 12.03506 13.12382 13.84305 11.54991 11.58626 11.05973 11.39041 14.03995 14.19523 13.01843 13.23257 14.71688 15.60102 14.75217 15.33405 14.82154 16.59491 18.86729 21.02257 22.58431 22.67589 9.467981 13.12758 12.64267 12.87043 13.40577 11.28999 10.91053 11.14885 11.37754 13.09841 14.32014 13.18549 12.73418 14.28728 14.77119 14.96639 15.80654 15.12319 16.99688 18.39054 20.01874 22.73198 22.52024 9.764517 13.51877 13.10358 11.6141 12.21243 11.77503 11.65425 10.68032 11.29402 14.13506 14.52542 13.75776 13.12655 14.90901 14.66903 15.17769 14.88138 14.35127 15.96097 17.97906 20.40209 22.40177 22.05331 9.448538 12.1722 12.48105 11.88218 12.70931 12.26048 11.73737 10.74498 12.15391 13.1719 13.41782 12.89102 12.99866 15.54638 15.04468 15.65555 15.56007 14.52773 15.27511 18.04018 19.91089 21.79332 21.80087 8.763973 11.93478 11.62999 11.1273 12.46282 11.85779 11.41145 11.12057 12.67596 13.37468 12.94005 12.73368 12.64572 15.58685 15.55944 15.38471 14.74936 14.22819 16.26686 18.11139 19.70222 21.42123 21.45517 8.306178 9.252882 9.844025 11.26888 10.83866 11.36586 11.08982 10.34481 11.93284 12.10324 12.52144 12.75002 12.61329 14.85645 14.61 14.17808 15.05804 14.43231 15.56323 17.80058 18.97718 20.20973 19.62204 11.66475 14.36481 14.23808 12.98364 11.47848 11.98761 11.70588 10.32386 11.46336 12.05531 11.33844 11.47684 12.1066 15.10926 14.7728 13.86291 14.54506 14.13791 14.81665 16.32619 17.66183 18.56561 18.54115 13.551 15.17671 16.76833 15.87209 15.30873 11.94541 10.92486 11.23132 11.48584 13.04966 12.27409 11.97255 11.65486 14.969 14.62882 13.83866 13.70533 13.39387 13.99928 15.66928 16.7587 16.72407 16.5293 12.76456 14.3368 17.05488 16.533 16.53849 12.9081 12.13053 12.54419 11.06146 11.80947 11.34655 11.66301 11.78405 14.4737 14.33242 13.79723 14.23168 13.66543 14.59762 15.88466 16.25202 16.19663 16.058 12.61326 13.91244 16.62031 16.31223 16.49494 13.073 12.46359 13.13346 11.08299 12.0898 12.36925 12.15002 11.55262 14.73402 14.74845 14.4159 15.61065 14.59098 14.15156 15.8146 16.68856 15.90823 15.70445 13.72736 14.60473 16.47353 16.42584 16.23803 13.49946 13.32173 13.55856 11.47504 12.57557 13.47919 12.9309 12.37103 15.21231 15.2276 15.20738 16.28225 14.82661 15.0314 16.40727 17.3156 15.99237 15.84188 13.94386 14.66504 15.96983 16.09722 16.08472 13.28472 14.21239 13.74801 11.81877 13.22909 13.79301 13.41157 12.9921 15.82657 15.1773 15.28221 16.49038 15.39782 15.09806 16.5119 17.39903 16.71843 16.71772 13.7535 15.06458 15.29338 15.41305 15.38942 12.72157 14.62464 13.94845 13.23048 13.06216 13.54 12.74474 13.10539 14.58909 14.21166 14.60993 15.12524 14.18825 14.24555 15.87136 16.5764 16.25047 16.18505 12.87529 15.11237 17.02908 16.62773 14.56104 13.15497 14.62326 14.26014 13.4457 13.14097 14.58538 14.2613 13.35599 14.02586 13.7997 13.72621 14.95759 14.69201 13.92311 15.1955 15.75672 15.51821 15.26852 14.88954 16.34912 15.96387 16.39929 15.98874 13.18963 13.59016 13.90227 13.35802 13.87966 14.67649 14.61434 13.03115 13.09564 12.67227 13.00849 14.46988 13.8509 13.29925 14.3982 14.9851 14.69154 15.44168 15.86816 17.34939 15.38919 15.75551 14.90487 13.54091 13.4477 14.09079 13.59264 14.21146 13.69315 13.91447 12.34339 11.63899 11.57346 11.78274 13.74251 13.4482 12.77586 13.67141 13.67339 14.87321 15.2977 16.05614 17.80696 15.5341 15.78276 14.98103 13.54131 13.31379 14.18915 14.42894 15.16783 13.61487 12.74171 12.90643 12.58465 11.50915 11.18896 13.20965 13.26229 12.49681 12.70356 12.91538 14.117 14.82414 16.10782 18.11083 15.80454 15.79372 14.83904 13.20489 12.75853 14.28803 15.24095 14.56751 12.98957 12.72844 12.02183 12.00667 11.41799 10.49253 12.19255 12.55818 12.08304 12.07552 12.59875 13.70636 14.76297 16.48818 18.47473 16.28432 16.31223 13.50066 12.83804 13.33812 14.4014 15.45115 14.3461 12.77997 12.5514 11.41195 11.27457 9.940119 10.18195 11.79267 12.34199 12.40519 12.08422 12.70067 13.04217 14.32282 16.58727 18.6493 16.57899 16.56668 13.67641 12.70696 13.48661 14.16076 15.01744 13.59957 12.72013 12.734 11.13864 11.15946 10.10025 10.58426 12.08072 12.54692 12.42924 12.06971 13.08699 12.87339 13.88818 16.46552 18.60275 16.49226 16.2148 14.75385 13.87186 13.3091 13.94653 14.61146 13.24284 12.09616 11.93655 11.40253 11.15538 10.07787 9.789737 11.60745 12.03494 11.88888 12.21645 12.83724 12.63594 13.60312 16.42601 18.49523 16.10097 14.80393 15.19385 14.14109 13.04128 13.45862 14.21167 13.62841 11.52437 10.68034 10.83395 10.6881 10.08846 10.43773 10.89225 11.42747 11.60774 13.2441 13.97224 11.69935 13.44734 16.38114 18.33183 15.98755 14.96587 15.34151 13.83746 12.48781 12.56362 13.59895 13.62195 11.67679 11.84699 11.38903 10.70972 10.37174 10.57339 10.79502 11.32389 11.35826 13.23451 14.09176 12.10806 13.03413 16.22431 17.94065 15.84532 15.77651 16.14402 14.11528 12.80109 13.16647 14.27707 13.8602 11.68355 11.39642 10.84387 10.61396 9.958416 9.830719 10.69155 11.12258 11.26303 13.12325 13.99851 11.67061 12.9628 15.79015 17.19271 15.68581 15.83383 16.8037 14.45622 12.3988 12.65228 14.56971 13.79517 10.82631 9.563471 10.30857 9.767759 10.45248 9.569944 10.59113 11.10918 11.09264 12.86746 13.68986 11.89357 12.99938 15.2913 16.56188 15.66566 15.6369 15.88488 12.91912 13.74727 13.40825 14.74673 12.99693 11.53082 10.84703 10.13508 9.678087 9.518613 9.16087 10.43609 11.18994 10.68452 11.71982 12.54992 12.5922 13.53928 14.92816 16.64891 16.45783 16.25064 16.19631 13.19242 13.77824 14.43863 15.26204 15.19201 12.83485 11.38921 10.91256 11.21886 10.82799 12.13972 13.95731 12.54356 12.07864 12.44756 12.12163 12.97568 14.7286 15.13246 17.03524 15.97898 15.40096 15.36011 13.36627 13.54038 14.25134 15.57904 16.03234 13.77775 12.25592 10.30315 10.69148 10.83694 12.56628 14.37519 12.44555 12.39819 13.07718 11.56385 13.12282 15.2996 15.5982 17.27533 16.06111 15.55091 15.21003 14.51325 13.98331 14.05154 14.17753 16.04241 15.2899 13.87621 11.14674 10.69581 11.96811 14.34262 14.9851 13.41596 13.65708 14.32451 13.39169 12.8552 14.58668 14.91011 16.69463 15.57334 15.01008 15.36094 14.74225 14.26171 13.92481 13.91756 15.95652 16.69785 16.57439 12.48547 11.33714 12.08421 15.43829 15.81007 13.38737 13.30834 14.67949 14.26769 13.08782 14.67955 13.62063 15.99206 15.72027 15.10223 15.1442 15.15948 14.64559 13.86851 12.91738 14.75704 17.01463 17.44593 14.92344 12.40641 12.71938 16.50565 16.63255 13.53405 12.98962 15.20941 15.12311 13.42216 15.25566 15.30581 16.69621 15.66549 15.66445 16.12411 15.10698 15.31674 14.56899 12.28834 15.10705 16.23727 16.72542 15.70731 13.46484 13.77255 16.57919 16.63644 13.61368 13.20484 14.98691 15.30538 13.48375 14.71632 14.74377 15.90853 16.02791 15.53424 15.54271 15.17513 15.70076 15.01335 12.41409 14.9216 15.6982 15.6553 14.80186 13.63735 14.12234 16.54076 16.64301 13.9333 13.65155 15.33424 15.71972 14.00131 14.723 13.63359 14.52747 16.50115 15.59644 14.78498 14.94671 15.83353 15.04419 12.83702 15.15406 14.95185 15.14444 14.53343 14.07447 14.4541 16.43644 16.78634 13.96131 13.85571 15.59888 16.54558 14.7505 15.17269 15.09095 15.96606 16.31398 15.20485 14.33777 14.76441 15.66189 15.22405 12.65838 15.33522 14.93109 15.00384 14.89501 14.88041 14.65054 16.52218 17.02337 14.22087 14.82588 15.54361 17.17436 15.60863 15.80521 15.26671 15.98887 16.00072 15.11115 14.80698 14.81987 15.41057 15.06448 12.76331 14.64497 15.39146 15.59635 15.41956 14.94571 14.81527 16.34526 16.81958 14.88231 15.31733 15.54397 16.68404 16.08439 16.50137 14.82031 15.1955 15.81392 14.74509 13.80763 14.37639 15.23381 14.08953 13.05277 14.46634 15.04908 15.01031 14.62417 15.87493 14.96298 16.19891 16.81858 14.21854 14.53428 15.09545 15.81948 15.23545 15.83264 14.47235 14.64184 15.65243 14.61598 13.88489 14.16747 15.15573 13.50578 13.0122 14.29219 15.03921 14.0275 13.43212 15.84878 14.55854 14.92103 15.28403 13.08439 14.17978 15.17877 15.71674 13.99384 15.05782 14.84271 15.37902 15.59052 14.53613 13.88661 14.49238 15.42805 13.71516 12.43119 13.77503 14.90729 14.78802 14.2214 15.8298 14.60928 14.95287 15.55999 13.44495 13.74132 15.10681 16.23884 14.13648 15.53918 14.90855 15.54294 15.92132 14.83505 13.52632 14.82017 15.56321 12.84901 12.36878 12.84481 13.59268 13.83251 13.89308 14.76446 13.99949 14.81193 15.35496 13.92693 14.23314 14.60406 16.01696 13.7629 15.32229 14.34874 14.65815 15.8946 14.89865 13.93546 14.51131 15.38126 12.69744 12.18602 11.85635 12.55572 13.3946 13.59089 14.50925 13.44721 14.08821 15.0949 13.18603 13.76213 14.69819 15.71466 14.58852 16.02038 14.12023 14.95996 14.94988 14.08591 14.26389 15.05177 15.42382 14.23856 13.6525 13.4122 13.92378 13.58581 13.71874 15.37159 13.65612 14.78279 15.35144 12.51747 13.10743 13.96306 14.74565 13.60848 15.42061 13.03794 14.3534 14.61717 14.4276 14.20311 14.88333 16.29688 13.85629 12.45 12.66146 13.211 13.02482 13.61957 15.25426 13.65302 14.40839 15.28184 12.64547 12.91868 13.65031 15.02586 13.60051 14.85588 12.80224 14.75209 15.02113 14.23392 13.57626 14.24956 14.97642 13.44714 11.19146 11.87919 12.94502 13.08048 12.71222 14.35021 13.33305 13.61649 14.14324 12.44998 12.97652 14.02602 14.98486 13.33818 14.75948 13.16971 14.54832 13.68839 12.53332 12.31186 13.85297 14.5408 12.63638 10.70129 10.50308 11.22596 12.15875 12.87752 14.50729 13.75705 13.03189 14.20643 12.62912 13.04198 13.98892 14.39815 13.00242 14.93295 12.32784 14.45602 13.87575 12.9689 12.90031 12.28457 12.79731 12.50595 11.64002 10.49457 12.00499 11.84997 12.20587 13.69985 12.74907 13.07555 13.99215 12.42866 12.85618 13.70903 14.67477 12.98654 15.42268 13.97398 15.76731 14.26718 13.93614 13.3635 12.53315 12.47679 12.46972 10.95234 10.91325 11.5195 11.66877 12.05166 13.99423 12.40961 12.80348 13.87326 12.39891 12.30221 12.87925 14.37371 12.68297 14.16082 14.184 16.03344 14.21303 12.96472 13.494 13.50742 12.40183 12.13428 11.0977 10.09598 11.73288 11.88649 11.97245 12.51878 11.91088 12.78705 13.84648 12.43722 11.65642 12.11694 12.9002 12.40637 14.5552 13.45738 15.55 14.00745 12.82178 12.33664 11.91138 12.54709 12.3248 11.18794 10.89101 11.58366 11.65439 12.35607 12.53853 11.86051 12.31624 13.99491 12.18095 11.57812 11.95029 13.21074 12.14984 13.58227 12.75044 14.95871 13.36009 13.20988 12.31619 11.93608 11.93395 12.31846 11.38457 11.1864 11.68532 11.97781 12.34169 12.93438 11.78984 12.08069 13.22225 11.86906 11.43046 11.13731 12.37698 12.51735 13.13258 12.4284 14.15335 13.07597 11.76668 11.4075 11.61571 12.59232 11.93633 12.10711 12.10692 12.07862 13.06988 12.64771 14.07678 12.7958 11.8246 12.44421 11.69291 11.27304 11.0924 11.61102 12.44975 12.95033 11.18342 11.99406 12.91778 11.29505 11.66648 10.58673 12.03916 12.36362 11.94302 11.53715 12.30084 12.70467 12.66107 14.14579 13.0996 11.72703 12.5057 11.78472 11.09719 10.43786 12.19886 12.96147 12.51465 11.16282 12.16246 10.93769 9.637576 10.93914 11.07357 12.48322 11.72473 10.95556 11.30609 12.062 12.24674 12.28014 13.23953 12.19423 12.05279 12.69395 11.68082 11.26663 10.09986 10.75675 11.19461 11.49739 10.68674 13.24407 11.97083 9.004447 9.364768 10.10863 12.20102 11.69279 10.02772 10.04208 11.35098 11.3541 12.00796 12.02115 10.81907 10.48873 11.81506 11.11288 11.23438 10.76176 10.97295 11.27559 11.05051 11.25764 13.04875 10.96754 9.594095 9.950509 9.515109 10.90454 10.44351 10.30407 10.58162 11.61821 10.79663 11.97438 12.49545 10.3045 10.45207 10.77822 10.23204 10.59221 10.55611 10.73 11.25474 10.92693 10.77957 12.84101 10.96046 9.825205 9.921305 10.27295 11.00374 9.069146 9.143576 9.619534 9.886018 9.683996 11.43353 11.68437 10.21345 9.418591 10.17027 9.919155 9.729475 10.12781 10.13701 10.20216 10.49461 10.50037 12.81704 10.93899 8.919902 9.181169 9.454815 9.864502 9.160638 7.950092 8.281847 9.608268 9.700049 10.10044 10.43497 10.07498 9.374721 10.09255 9.838331 9.777655 9.972161 10.5668 10.3991 10.44382 10.9499 12.69608 10.32951 8.873781 9.134046 8.758868 9.037214 8.199131 7.569058 8.374478 9.34644 9.717125 9.732412 10.43906 8.821301 8.579359 9.148021 9.602486 9.728423 9.711402 10.63859 10.64856 10.91956 11.27755 12.95559 10.74122 9.436187 9.256186 9.484769 9.586822 8.388662 7.160058 8.068262 9.397726 9.698923 10.2531 10.30162 9.136081 8.90623 9.838286 9.443312 9.586123 9.845777 10.52771 11.16902 11.16297 10.61487 12.45117 10.35181 8.28381 7.78183 7.990805 8.725731 8.746444 7.518696 7.472842 8.455659 9.625546 9.859873 9.179219 8.927357 9.205382 9.615867 10.14538 10.18613 10.31581 10.64848 10.60155 10.51831 9.637716 11.20578 9.314525 7.651236 7.868614 8.413736 9.356231 8.070017 8.155 7.390232 8.749864 9.116447 9.567814 9.369207 9.694729 9.147233 9.482315 9.444982 9.887435 9.599484 9.862085 10.45017 10.60415 8.626204 9.187364 9.029099 8.493851 7.209723 7.690259 8.042856 7.316092 8.150468 8.128954 8.491919 8.446475 8.681947 8.747696 8.789898 9.233255 10.31805 9.660691 9.486577 10.23518 9.970778 9.988548 10.34961 9.442098 8.689657 9.283001 7.998808 6.22693 6.962261 9.189577 8.19746 7.75057 8.493724 8.455694 7.799927 8.001998 8.729837 9.923102 9.574437 9.835016 9.547566 9.595923 10.27687 9.859653 10.14931 10.31981 9.97291 9.826776 8.408665 7.496465 8.021371 7.480401 6.859789 7.656764 8.673873 8.172565 8.807829 9.007799 9.039057 8.638908 9.110216 9.078871 9.454023 9.512172 9.644451 9.953197 10.47481 10.57586 11.22771 7.733074 9.88445 8.777633 8.313414 8.081938 7.271777 8.92068 8.634503 8.78035 8.908507 9.615075 9.58618 10.19903 9.804263 9.953383 9.936666 10.38816 9.741985 10.35782 10.95726 11.52999 11.21175 11.48313 10.96227 9.154578 8.698281 7.998504 7.728884 6.602579 8.022117 8.025263 9.123106 8.844633 8.908731 10.21477 9.655914 9.417415 9.496919 9.789172 10.42569 10.3659 11.02518 10.92264 11.54033 11.66203 11.41841 10.86337 9.16935 9.55076 7.872849 7.942523 7.244263 7.779666 7.115378 7.89739 8.183571 8.867866 9.697963 9.289954 9.11062 9.085766 9.426685 9.012211 9.846148 10.90698 10.7715 10.9265 11.21198 11.22182 9.851903 10.36412 8.908376 7.846486 7.46843 7.405447 7.65377 8.196727 7.064144 8.249885 8.761197 8.942713 9.204334 8.628345 8.864152 9.710718 9.490798 9.545791 10.44929 10.69282 10.93337 10.86275 10.97815 11.25423 10.87261 8.889456 7.461558 7.015344 7.351716 8.382879 8.503271 7.68911 7.91639 8.643186 8.87805 9.065163 9.099637 9.386837 9.786633 10.39724 10.21951 10.45584 10.46524 10.56583 10.76281 10.16936 10.68273 9.817769 8.26171 8.016673 8.054502 7.516357 7.65291 7.820787 7.519141 7.720293 7.444949 8.414156 9.215623 8.999539 9.341202 10.16718 9.897247 10.21318 10.05819 10.82438 10.51383 10.53982 10.3831 9.478124 9.167519 9.010949 7.99378 7.74503 6.204545 7.584774 7.112559 7.285814 7.478474 7.668393 7.974492 8.957026 8.854042 8.923244 10.00307 9.395614 9.709485 9.681889 10.5162 10.42807 10.61794 10.64966 10.47888 7.862177 7.167226 8.245425 7.75247 7.6353 7.317435 8.184895 7.887283 7.203204 8.485103 8.665626 8.602202 8.789666 8.851316 9.74954 9.710799 9.547979 9.842075 10.54527 10.60706 10.56509 10.56258 9.801606 8.885911 7.033187 7.478241 6.67696 7.042121 7.39953 7.7513 7.696868 7.563337 8.205177 8.162902 8.607606 8.607259 8.436271 9.256256 9.444992 9.138235 9.183046 10.3544 10.70144 10.78459 10.73416 8.729084 9.680941 8.473826 7.128935 7.117252 7.535285 7.976354 8.395122 7.388021 7.665706 7.663038 7.935491 7.918374 8.014401 9.072487 9.747068 9.442183 10.02906 9.621786 10.21271 10.62509 10.38278 10.59681 9.071483 8.072448 8.148285 8.208888 6.865083 7.357923 7.7726 7.642717 7.373379 7.314355 6.811155 8.184822 8.202291 9.007961 8.424119 9.344726 9.500482 9.494846 9.845454 10.21647 10.59387 10.59069 10.30458 9.551182 8.782715 9.017637 8.455041 7.292755 6.371716 8.139261 7.807406 6.868361 7.754928 8.373298 7.639658 8.648994 8.402566 9.127618 9.492344 9.512679 9.582137 10.01061 10.36339 10.5303 10.40906 10.77627 10.07956 9.123581 9.239129 7.188252 7.983877 7.36659 7.689083 7.349831 6.549315 7.351971 7.765708 8.071753 8.22062 8.234403 9.252606 9.165942 9.141379 9.528788 10.10328 10.09754 10.46661 10.03632 10.45256 10.45638 9.177458 8.172346 6.487576 7.374524 7.649885 7.573339 6.959404 7.260113 6.734559 7.447418 8.466086 8.382314 8.260194 8.807273 9.042309 9.807338 9.552331 9.757251 10.22166 10.39291 10.50788 10.47725 11.13613 7.758188 7.694408 7.91339 6.591579 7.690708 7.883243 6.817697 6.937893 6.617546 7.995504 8.199288 8.606889 7.930028 8.27558 9.028001 9.202659 9.807508 10.00867 10.30622 10.30117 10.22799 10.23392 10.84375 8.658377 8.964039 7.577753 5.997756 6.243629 6.59042 7.667848 7.77693 7.160565 7.672915 8.214157 7.767068 8.187228 8.741798 9.008192 8.761507 9.775722 9.991219 10.50324 10.35022 10.56752 10.42405 9.856415 8.33345 7.864082 7.394323 7.037837 7.429994 7.053414 8.148975 7.734139 7.73136 8.126728 8.250671 8.107525 8.775521 8.947971 9.013912 8.709566 9.952392 10.0177 10.55204 10.14417 10.48263 10.89007 11.22424 8.785028 8.384821 6.571542 6.668182 6.510378 7.012306 7.705905 6.736544 7.154219 8.193804 7.920104 8.426934 8.557131 8.854219 9.46376 10.04807 9.964184 9.701237 9.969363 10.31233 9.983346 10.42036 11.32489 8.361799 9.032561 7.834023 7.204043 6.074617 7.471241 8.117975 7.885279 7.726513 8.305443 8.50788 8.930935 8.875918 8.786529 9.071368 10.33387 9.977633 10.02416 10.06347 10.81268 11.20751 10.80103 10.06941 6.52937 7.571665 6.465108 6.881132 6.903685 7.100048 7.664837 8.100976 8.205462 8.043177 8.448032 8.847051 8.371434 9.149493 9.756526 10.0323 9.265886 10.12252 10.04926 10.18163 10.70782 10.76523 10.31685 7.024517 5.869543 5.841137 6.383105 6.215681 7.949264 7.746029 7.835628 7.861153 8.296052 8.204115 8.655869 8.276096 8.929706 8.994547 9.447945 9.700706 10.37251 10.27933 10.33522 10.72122 10.48557 10.91509 7.91675 8.244367 6.124669 6.732698 7.492036 8.363312 8.124249 8.108838 7.358902 8.053522 7.411808 8.716305 8.342316 8.457804 9.005593 9.336573 10.05767 9.578779 10.344 10.4169 10.55184 10.60104 10.32075 8.261191 8.136519 6.961864 6.799195 7.198459 7.713956 6.972926 6.764237 7.75519 7.804876 7.912869 8.563591 8.987835 9.309792 9.610885 9.492855 9.925476 10.05713 10.52021 10.62411 10.47692 10.59566 9.86818 8.572285 8.530177 7.359343 7.294422 6.582515 6.642591 7.496963 7.95584 7.202435 7.878167 8.503516 8.365258 9.081302 8.992274 9.197975 9.750833 9.722472 9.760623 9.966175 10.59453 10.34588 10.6256 10.25583 7.347171 7.843901 6.244213 6.5353 6.617674 7.064937 7.198507 6.530531 7.619411 7.706642 8.672579 8.665023 9.01842 9.258142 9.454097 9.65053 9.569846 10.16275 10.25629 10.61747 10.79843 11.0936 11.3455 8.169881 7.368921 6.081739 7.016907 7.807951 8.699952 7.736558 6.748681 7.378449 7.852139 8.727378 9.049452 8.352005 9.397895 9.694369 9.896957 9.87398 9.838742 10.29402 10.58788 9.819412 10.6098 11.90842 7.299352 8.247597 6.929464 5.668571 7.252095 8.041783 7.685021 7.479499 7.446598 7.486227 8.122455 8.321239 8.863303 8.986836 9.896532 10.01282 9.700945 10.13044 10.36466 10.79011 10.65473 10.96276 11.22572 8.534163 7.996068 7.321532 6.95424 7.306089 8.242614 7.205853 7.210618 7.631306 8.128415 8.210221 7.745347 8.572201 9.164312 9.454391 9.143291 9.996038 9.919705 10.61216 10.94615 11.0497 10.50996 11.99271 8.205185 9.120809 8.732939 7.727026 7.459247 9.017488 8.611053 9.431357 8.641321 9.48832 9.588237 9.180689 8.96218 9.460557 9.78753 10.30156 10.65017 10.35131 10.94515 12.2452 13.12846 12.19351 11.79253 9.627811 9.291315 7.524522 6.52378 7.294258 8.705289 7.135509 8.226054 8.742827 9.064022 9.066143 8.709431 8.971881 9.728841 9.269897 9.861171 10.09128 10.07978 10.35271 10.13663 11.0843 11.13849 10.56259 9.232968 9.15976 6.620336 6.150416 6.181613 7.583303 6.586105 7.54056 7.118359 8.163677 8.156444 8.354664 8.431437 9.365588 9.699803 9.425529 9.986162 10.02214 9.757886 9.986296 10.37123 11.12805 11.46303 8.064131 8.81135 8.263533 7.772588 6.787446 7.045297 7.507244 7.852684 7.8141 8.464418 8.278731 8.368163 9.374079 9.125239 9.165322 8.79129 9.501587 10.15753 9.792738 10.41069 10.7875 10.81474 11.05755 8.402949 8.103877 8.311771 7.382164 7.518039 8.082945 8.166703 8.587493 8.333583 7.051155 8.128522 9.163286 9.241158 9.282046 9.011143 9.606009 9.214875 9.92196 10.35358 10.19762 11.04288 11.07783 9.634427 8.981845 9.008856 8.496973 8.026294 6.744306 7.501451 7.233029 7.99301 7.752292 7.717514 8.286538 9.62907 9.19305 8.897845 9.250588 9.401032 9.651338 10.04432 10.55263 10.60681 10.55907 10.44911 9.16023 9.718575 9.712869 9.499995 9.118845 7.099794 7.596916 7.821012 7.377513 7.772183 8.825283 8.444467 8.374529 8.278049 8.336656 9.146471 9.616967 9.900914 9.985411 10.23762 10.56904 10.3051 10.82687 10.26259 9.707577 7.891645 7.938838 8.196815 7.030812 7.729892 8.539984 7.097323 7.639617 8.26931 8.103879 8.820785 8.756143 8.088627 7.633537 8.861978 9.411267 9.507934 9.617286 10.103 10.32123 10.60248 9.416736 8.067968 8.121611 8.702229 8.153371 7.398215 8.101689 7.075943 7.48716 7.682926 7.930077 7.562144 7.981254 8.482229 8.007603 8.850947 9.587449 9.971848 10.00796 10.0423 10.69032 11.02298 10.9979 9.875791 9.180859 8.33131 7.329909 7.138772 6.531456 7.820087 7.730562 7.006549 7.355982 8.221857 7.397998 8.619684 9.434539 8.325085 8.88515 9.217641 10.11225 10.50192 10.39947 10.4549 10.84156 10.37869 10.21343 8.826467 8.089176 7.33913 7.855656 7.318372 7.243741 7.606412 7.226522 7.431902 7.899468 8.143455 8.827127 9.14143 8.887341 8.847593 9.56572 9.84055 9.684552 9.931477 10.32066 10.90385 10.82047 8.685722 8.634503 8.177417 7.393768 7.107471 7.263133 7.5967 7.938039 6.885909 7.359814 8.428015 8.861872 8.920212 7.885601 8.544594 9.326226 9.538568 9.941797 10.37305 10.73129 10.24279 10.99198 10.71185 9.49738 9.815642 8.553341 7.461448 7.640052 7.98072 7.311526 8.038465 7.255682 6.560006 7.371539 7.967708 8.035154 7.652845 8.489419 9.47836 9.636602 9.799182 10.27001 10.54407 10.1862 10.5361 11.08353 9.237267 8.263541 7.987866 7.640958 7.269582 6.937474 6.849837 7.717149 7.656352 7.173209 7.225511 7.958437 8.102967 8.547636 8.357112 8.845057 9.423195 9.327521 10.10193 10.10455 10.16159 10.10588 10.53935 8.52638 7.134833 7.512567 7.138206 6.746409 7.367229 7.365469 6.383105 7.514528 7.68226 8.600569 8.164186 8.062187 8.582131 9.225581 9.787975 9.365478 9.480648 9.960615 9.841322 9.842931 10.30676 10.41945 9.151896 6.975066 6.058979 7.529419 6.584132 6.413368 7.757835 7.395633 7.860129 7.49466 8.109066 7.873742 8.698033 9.225484 9.379223 9.214903 9.393662 9.46548 9.963161 10.11975 10.1148 10.09052 10.40652 9.582273 6.791395 7.215298 7.381511 7.378876 7.854954 7.890674 7.242115 7.359837 7.425533 8.024413 7.492979 8.248519 8.686938 8.807583 9.178555 9.128061 9.372928 9.666212 9.78712 9.796471 10.31979 10.85505 ] ================================================ FILE: audio/tests/features/testdata/pitch_feat_txt.ark ================================================ test_wav [ 0.4300044 238.1164 0.7310953 238.1164 0.0589752 238.1164 0.3706925 238.1164 0.6353879 238.1164 0.4168843 238.1164 0.7615743 238.1164 0.7359886 238.1164 0.5104555 238.1164 0.843815 238.1164 0.574707 238.1164 0.8757079 238.1164 0.8545787 238.1164 0.5284878 238.1164 0.8398617 238.1164 0.8405749 238.1164 0.7291093 238.1164 0.3530312 238.1164 0.8516902 238.1164 0.8366287 238.1164 0.7860549 238.1164 0.7996263 238.1164 0.8769377 238.1164 0.8062987 238.1164 0.5502667 238.1164 0.8050084 236.9318 0.8435217 235.753 0.6781067 234.5801 0.6275977 233.4131 0.8354951 232.2518 0.7898548 231.0963 0.6786529 229.9466 0.5784115 228.8026 0.8078744 227.6642 0.7860623 226.5316 0.3529067 225.4046 0.7398534 224.2832 0.7554479 223.1673 0.3688865 222.057 0.431939 220.9523 -0.2559481 219.853 0.5161331 218.7592 0.736354 217.6709 0.2649688 216.5879 0.6187224 215.5104 0.8040497 214.4382 0.4176693 213.3714 0.7362868 212.3098 0.6412426 211.2535 0.01994592 210.2025 -0.09901931 209.1568 0.4139394 208.1162 0.7458671 207.0808 0.7015585 206.0505 0.8989595 206.0505 0.9356874 209.1568 0.9370709 212.3098 0.9640602 216.5879 0.9851464 217.6709 0.9874667 217.6709 0.9662011 215.5104 0.9561557 211.2535 0.9835509 209.1568 0.9764188 209.1568 0.8779365 208.1162 0.8911879 207.0808 0.8716732 205.0254 0.8663442 197.9909 0.9105747 191.1978 0.9614732 191.1978 0.9704162 187.4211 0.9690547 186.4887 0.9596871 187.4211 0.9392474 190.2465 0.8951484 192.1537 0.8852764 190.2465 0.9345272 185.5609 0.9304817 182.8051 0.9600235 180.0902 0.9829449 178.3027 0.9876611 178.3027 0.9889374 178.3027 0.9911457 178.3027 0.9835688 176.533 0.9755108 175.6547 0.9868198 174.7808 0.9932452 175.6547 0.9902206 175.6547 0.9920143 176.533 0.9922135 175.6547 0.9892406 174.7808 0.9888865 172.185 0.9796383 172.185 0.9825094 170.476 0.9640273 170.476 0.9416605 173.046 0.9690976 173.9112 0.9527848 173.9112 0.8625391 173.046 0.8571138 173.9112 0.826855 174.7808 0.8046249 176.533 0.6064064 178.3027 0.4831207 180.9906 0.4654697 183.7191 0.6392145 186.4887 0.6342434 190.2465 0.8626602 194.0801 0.953752 194.0801 0.987371 191.1978 0.9915444 188.3582 0.9920763 186.4887 0.9898383 184.6377 0.9908906 181.8956 0.9892344 180.9906 0.9779232 179.1942 0.962887 175.6547 0.9623674 170.476 0.9719465 171.3284 0.9843823 173.046 0.9776363 173.9112 0.9711902 173.9112 0.9477384 172.185 0.9629893 172.185 0.9716213 173.9112 0.9675733 176.533 0.9643332 178.3027 0.9592766 180.0902 0.8798139 181.8956 0.7133937 185.5609 0.558998 190.2465 0.3460312 196.0257 0.645723 201.9805 0.538826 208.1162 0.6076745 216.5879 0.5921855 228.8026 0.8826846 238.1164 0.9501736 242.9146 0.9898381 245.3498 0.9941772 245.3498 0.9901065 246.5766 0.9880084 247.8095 0.9941741 249.0485 0.9959649 249.0485 0.9930359 250.2938 0.9856881 252.8029 0.9906433 252.8029 0.9973371 252.8029 0.9980655 252.8029 0.9958057 251.5452 0.9909865 250.2938 0.990723 249.0485 0.987911 249.0485 0.9759061 251.5452 0.9722236 251.5452 0.9578422 251.5452 0.936386 250.2938 0.9094891 245.3498 0.8420637 235.753 0.6358631 218.7592 0.757064 198.9809 0.8944787 192.1537 0.9415626 188.3582 0.9400396 183.7191 0.9019431 180.9906 0.904547 175.6547 0.8742625 173.046 0.7475201 169.6279 0.5156456 164.6269 0.4781345 161.3751 0.4000205 149.7427 0.4614965 147.5188 0.4422437 141.7487 0.3527509 136.2042 0.191848 130.2255 0.3072545 128.2915 0.5506754 127.0181 0.6923887 129.5776 0.6101584 132.8496 0.3040284 138.2575 0.1897903 155.8383 0.4685728 164.6269 0.5444003 164.6269 0.5138596 162.9929 0.5802024 160.5723 0.2090085 160.5723 0.2416739 162.9929 0.2459603 168.784 0.6345571 176.533 0.5914032 184.6377 0.4447052 193.1145 0.2762254 201.9805 0.2842087 212.3098 -0.1974148 224.2832 0.5095772 238.1164 0.7442543 252.8029 0.8915138 252.8029 0.9569594 247.8095 0.9625007 242.9146 0.9194686 235.753 0.8994824 227.6642 0.9381443 218.7592 0.7226841 219.853 0.6949252 223.1673 0.6777956 222.057 0.7978759 214.4382 0.8507771 209.1568 0.7713854 211.2535 0.6789038 211.2535 0.7500904 206.0505 0.7494768 204.0054 0.7971382 206.0505 0.8222839 206.0505 0.7602305 200.9756 0.6428912 197.0059 0.6536841 193.1145 0.7034875 188.3582 0.5804744 181.8956 0.4417492 173.046 0.3494109 161.3751 0.1981726 148.2564 0.6261529 140.3417 0.7587391 136.8852 0.3861219 134.8523 0.2585415 138.2575 0.4469885 141.7487 0.7737626 140.3417 0.7246874 138.2575 0.6511324 136.8852 0.4254677 136.8852 0.1780608 141.7487 0.4341104 146.7849 0.2834992 149.7427 0.4845652 151.2439 0.4879717 151.2439 0.5601908 152.0001 0.7019184 152.0001 0.8482625 152.0001 0.8672082 152.0001 0.8626106 151.2439 0.8626055 149.7427 0.9013379 148.2564 0.8793075 146.7849 0.8914734 144.605 0.8311929 141.7487 0.6839114 139.6435 0.5378032 136.8852 0.3579432 131.531 0.3721773 123.8897 0.259927 118.4515 0.4204291 116.1118 0.7305987 117.2759 0.6386622 122.6601 0.4521356 127.0181 0.1688575 132.1886 0.2404094 136.8852 0.161655 139.6435 0.361738 140.3417 -0.02500387 138.2575 0.4358978 136.2042 0.4791997 134.8523 0.5491226 134.1814 0.6218376 133.5138 0.566164 133.5138 0.6004029 134.1814 0.4282176 134.8523 0.2462277 135.5266 0.468562 136.8852 0.1709644 137.5696 -0.1866998 138.2575 -0.2322609 138.9488 -0.3413201 138.9488 -0.5628413 138.9488 -0.3278477 138.2575 -0.1193225 138.9488 0.04384596 140.3417 0.04935479 142.4574 0.1841608 144.605 0.5726393 147.5188 0.6960948 151.2439 0.7003101 153.5239 0.7147154 155.8383 0.7900128 158.9785 0.7915136 160.5723 0.8635668 162.9929 0.9153162 167.1087 0.9632365 168.784 0.9837555 173.046 0.9895447 174.7808 0.9936979 178.3027 0.9939244 180.0902 0.9943298 180.9906 0.9935455 183.7191 0.9959602 184.6377 0.9956325 184.6377 0.9592334 185.5609 0.8768551 189.3 0.7307228 193.1145 0.511133 192.1537 0.6857247 188.3582 0.9158598 184.6377 0.9108561 186.4887 0.9116812 187.4211 0.9223366 187.4211 0.8974369 188.3582 0.8092315 189.3 0.6424754 190.2465 0.415496 193.1145 -0.09486372 194.0801 0.06201403 196.0257 0.7022306 199.9758 0.8596367 206.0505 0.8891434 212.3098 0.8837855 220.9523 0.7532349 229.9466 0.8273478 235.753 0.8926229 240.5036 0.9618158 242.9146 0.9802947 242.9146 0.9757999 241.7061 0.9556377 236.9318 0.9495205 228.8026 0.8714783 222.057 0.6913882 217.6709 0.5996734 214.4382 0.5818065 196.0257 0.7346321 182.8051 0.8720678 184.6377 0.8043494 181.8956 0.7913815 184.6377 0.8019897 179.1942 0.8272967 177.4156 0.917188 173.9112 0.948779 178.3027 0.9491397 179.1942 0.9660939 181.8956 0.948925 181.8956 0.9438759 183.7191 0.9082419 182.8051 0.8157918 182.8051 0.7726267 183.7191 0.7925529 184.6377 0.82323 185.5609 0.7710455 186.4887 0.7245523 187.4211 0.6725792 188.3582 0.6098945 190.2465 0.6053364 192.1537 0.5669799 194.0801 0.6425812 196.0257 0.5920788 198.9809 0.5982969 201.9805 0.5845767 206.0505 0.8673239 210.2025 0.8958703 213.3714 0.9322492 215.5104 0.9763456 216.5879 0.9871499 217.6709 0.9847117 216.5879 0.9803717 215.5104 0.9864718 214.4382 0.9891353 213.3714 0.9886542 212.3098 0.9887235 211.2535 0.9895412 211.2535 0.987739 210.2025 0.9813522 211.2535 0.979372 210.2025 0.9715059 211.2535 0.9659958 212.3098 0.9582934 213.3714 0.9457313 214.4382 0.9001306 214.4382 0.8375491 214.4382 0.8580287 213.3714 0.8090529 212.3098 0.7204515 211.2535 0.727868 211.2535 0.8134795 211.2535 0.7847017 212.3098 0.855688 212.3098 0.9308017 212.3098 0.8832355 211.2535 0.7976366 210.2025 0.6125828 208.1162 0.7335693 206.0505 0.5974885 204.0054 0.5784881 201.9805 0.626056 199.9758 0.3227086 197.9909 0.4882276 196.0257 0.5797763 194.0801 0.6834005 191.1978 0.8976591 190.2465 0.9618267 188.3582 0.9768698 185.5609 0.9630268 181.8956 0.951674 178.3027 0.9476838 173.9112 0.9517156 172.185 0.9504529 169.6279 0.9870636 169.6279 0.9741296 168.784 0.9508372 168.784 0.90883 165.4501 0.8581914 161.3751 0.8267851 156.6175 0.6312259 150.4914 0.546525 146.7849 0.5260749 146.7849 0.4342186 153.5239 0.492891 160.5723 0.6401276 166.2773 0.7607003 168.784 0.8006893 169.6279 0.754485 169.6279 0.3563844 168.784 0.2301813 168.784 0.5213931 168.784 0.4302804 169.6279 0.203999 170.476 0.5803608 172.185 0.799207 173.9112 0.7838959 175.6547 0.6272278 177.4156 0.5649745 179.1942 0.1334038 180.9906 0.4665532 182.8051 0.7017906 184.6377 0.574991 186.4887 0.1776394 188.3582 0.7058933 190.2465 0.7285945 192.1537 0.5696192 194.0801 0.5714518 196.0257 0.8047431 198.9809 0.7406042 200.9756 0.3201705 202.9904 0.7420282 205.0254 0.8154832 207.0808 0.7317356 209.1568 0.3067544 211.2535 0.8014479 213.3714 0.8102676 215.5104 0.4439816 217.6709 0.8234195 219.853 0.7885534 222.057 0.4245847 224.2832 0.00418177 226.5316 0.3035149 228.8026 0.6538261 231.0963 0.847946 233.4131 0.6219971 235.753 0.858582 236.9318 0.8284138 239.307 0.4044586 240.5036 0.7807371 241.7061 0.6421613 242.9146 0.4366452 244.1292 0.8172922 245.3498 0.7077252 246.5766 0.7137164 247.8095 0.8416377 249.0485 0.8084357 250.2938 0.6429872 251.5452 0.8479958 252.8029 0.8376269 254.067 0.5148344 255.3373 0.8253111 256.614 0.792549 257.8971 0.7535735 259.1866 0.08307214 260.4825 0.7227954 261.7849 0.7564813 264.4093 0.4621202 265.7313 0.4633192 267.06 0.7247673 268.3953 0.7581604 269.7372 0.5511292 271.0859 0.9282034 272.4414 0.9706463 271.0859 0.9854098 273.8036 0.9971125 273.8036 0.9954729 272.4414 0.9888761 269.7372 0.9950762 267.06 0.9968371 269.7372 0.9980098 269.7372 0.997749 268.3953 0.9915248 265.7313 0.9653835 259.1866 0.9663866 256.614 0.9707376 259.1866 0.9852746 263.0938 0.982106 265.7313 0.9469596 267.06 0.9675582 264.4093 0.9636477 261.7849 0.9427549 257.8971 0.7895892 251.5452 0.8654758 245.3498 0.5468963 235.753 0.683558 220.9523 0.8124123 211.2535 0.9160304 205.0254 0.9279389 197.0059 0.9523526 191.1978 0.9704132 186.4887 0.9692958 185.5609 0.9680378 184.6377 0.9765167 184.6377 0.9860514 182.8051 0.9883636 182.8051 0.9909548 181.8956 0.991558 183.7191 0.9909708 185.5609 0.9903755 187.4211 0.9908676 189.3 0.9932029 191.1978 0.9957952 191.1978 0.9942914 191.1978 0.9921359 189.3 0.9943052 187.4211 0.9959483 186.4887 0.995445 188.3582 0.9905357 190.2465 0.9810765 189.3 0.9172173 189.3 0.8372061 189.3 0.7548154 189.3 0.7888815 189.3 0.7481033 187.4211 0.598231 181.8956 0.4594265 180.9906 0.3907863 181.8956 0.3352165 180.9906 0.1176405 178.3027 0.07078327 173.046 -0.04527154 169.6279 -0.1348021 168.784 0.04466751 167.1087 0.09953013 164.6269 0.0682964 162.182 0.06978174 163.8079 0.1322864 165.4501 0.2013361 169.6279 0.2920707 174.7808 0.3333177 176.533 0.3332107 176.533 0.3530797 177.4156 0.4650808 179.1942 0.5486825 180.9906 0.4580497 182.8051 0.4908407 184.6377 0.4697383 186.4887 0.3304503 188.3582 0.3914385 190.2465 0.6257187 192.1537 0.3618582 195.0505 0.1043633 197.9909 0.3943349 200.9756 0.5306126 204.0054 0.1373097 207.0808 0.2010625 210.2025 0.3670651 213.3714 0.3145425 216.5879 0.8130425 219.853 0.8798357 222.057 0.9403205 223.1673 0.97297 224.2832 0.9836287 223.1673 0.9911686 222.057 0.9915301 220.9523 0.9894016 219.853 0.9908847 218.7592 0.9930059 217.6709 0.9904228 217.6709 0.962741 213.3714 0.9670218 209.1568 0.9779282 206.0505 0.9113222 202.9904 0.863717 196.0257 0.7813085 193.1145 0.7102375 197.0059 0.6673803 201.9805 0.7775867 202.9904 0.8043374 204.0054 0.7297218 200.9756 0.5714095 197.0059 0.5821126 194.0801 0.7140544 193.1145 0.7262678 194.0801 0.7389845 195.0505 0.7598057 196.0257 0.7466297 197.9909 0.6394933 199.9758 0.6129577 201.9805 0.672642 202.9904 0.715472 202.9904 0.7394825 202.9904 0.5446303 202.9904 0.7562882 202.9904 0.7478679 202.9904 0.3738182 201.9805 0.7470279 200.9756 0.7631992 199.9758 0.4866134 198.9809 0.6727687 197.9909 0.6740197 197.0059 0.5121869 196.0257 0.5960711 195.0505 0.4775652 194.0801 0.7727789 193.1145 0.7569727 192.1537 0.3645771 190.2465 0.7480979 188.3582 0.669458 186.4887 0.06009803 184.6377 -0.2068706 182.8051 0.2833839 180.9906 0.6422815 179.1942 0.3581112 177.4156 0.2500266 175.6547 0.3498747 173.9112 0.569603 172.185 0.097353 170.476 0.3730714 168.784 -0.1027659 167.1087 -0.1343261 165.4501 -0.1674749 163.8079 -0.09346908 162.182 0.02017644 160.5723 0.01829195 158.9785 0.2345988 157.4006 0.254218 155.8383 0.4619125 154.2915 0.2792292 165.4501 0.6047359 176.533 0.7835823 178.3027 0.8670148 175.6547 0.9359789 173.9112 0.9631585 175.6547 0.9587292 176.533 0.9695755 176.533 0.9835575 179.1942 0.9900097 179.1942 0.9886937 180.0902 0.9895495 180.9906 0.9944302 183.7191 0.9966992 183.7191 0.9946688 186.4887 0.992237 189.3 0.9917749 191.1978 0.9863276 192.1537 0.9785607 192.1537 0.9806378 190.2465 0.9924863 189.3 0.99017 188.3582 0.9820646 187.4211 0.9470521 188.3582 0.8216711 187.4211 0.7153458 190.2465 0.7442878 193.1145 0.5942695 196.0257 0.5665525 197.0059 0.535006 195.0505 0.6266476 193.1145 0.6059493 194.0801 0.6425897 198.9809 0.8118222 206.0505 0.8551767 210.2025 0.8889339 211.2535 0.947816 211.2535 0.9787855 209.1568 0.988611 208.1162 0.987321 207.0808 0.9843316 205.0254 0.9737096 204.0054 0.9765185 202.9904 0.9856598 202.9904 0.9898718 204.0054 0.9886413 204.0054 0.989678 202.9904 0.9851701 200.9756 0.9817263 198.9809 0.9766667 196.0257 0.9717003 194.0801 0.9652438 193.1145 0.9332103 193.1145 0.9138572 194.0801 0.8846416 194.0801 0.9482771 195.0505 0.9305538 196.0257 0.8390872 197.0059 0.7701216 197.9909 0.7264634 197.9909 0.7708728 197.9909 0.8309863 197.9909 0.8339165 197.9909 0.723191 197.0059 0.7247626 196.0257 0.608819 195.0505 0.3213559 194.0801 0.2234745 193.1145 -0.02573975 191.1978 0.05725723 189.3 0.218053 187.4211 0.4777128 185.5609 0.5337029 182.8051 0.2318052 180.0902 0.4889631 177.4156 0.08109105 174.7808 0.7427355 172.185 0.8433576 171.3284 0.938632 170.476 0.9607551 168.784 0.9642593 167.1087 0.963613 166.2773 0.9651926 167.1087 0.9591027 168.784 0.9754831 172.185 0.9820764 176.533 0.9875088 180.0902 0.9851621 181.8956 0.9825414 183.7191 0.9723955 185.5609 0.9567259 187.4211 0.8835074 189.3 0.8628154 192.1537 0.9157982 195.0505 0.5938084 198.9809 0.6943321 209.1568 0.7714629 212.3098 0.8662375 211.2535 0.849728 205.0254 0.7945137 196.0257 0.7933522 188.3582 0.6368725 178.3027 0.5897154 167.1087 0.3229582 158.1876 0.2969382 144.605 0.3351896 141.7487 0.384491 146.0546 0.04096958 151.2439 0.1369363 172.185 0.3727793 180.9906 0.4194036 183.7191 0.4396896 185.5609 0.5275242 185.5609 0.2498598 186.4887 0.05898202 190.2465 0.04901373 195.0505 0.1100158 197.9909 0.2187118 198.9809 0.4847157 197.9909 0.4972816 197.9909 0.5150168 198.9809 0.5341532 200.9756 0.2631531 202.9904 0.1344986 205.0254 0.1769232 207.0808 0.2019505 209.1568 0.3217678 211.2535 0.366561 213.3714 0.3891162 215.5104 0.3456501 217.6709 0.3461981 219.853 0.1349857 222.057 0.06558777 224.2832 0.397542 226.5316 0.697022 228.8026 0.4396819 231.0963 0.7819827 233.4131 0.7121504 235.753 0.2208821 238.1164 0.7816582 240.5036 0.7002975 242.9146 0.03593514 245.3498 0.1999688 247.8095 0.6519101 249.0485 0.5185443 251.5452 0.9164662 254.067 0.9069665 255.3373 0.9549389 254.067 0.9885621 252.8029 0.9925307 251.5452 0.9942389 249.0485 0.996495 249.0485 0.9955549 247.8095 0.9936098 246.5766 0.980476 245.3498 0.9671 246.5766 0.9642795 249.0485 0.9722587 249.0485 0.974653 249.0485 0.9627596 247.8095 0.9594576 247.8095 0.9352374 247.8095 0.9516878 246.5766 0.9676836 245.3498 0.9551129 246.5766 0.9023392 249.0485 0.8472683 251.5452 0.8856258 254.067 0.8884159 255.3373 0.9254211 255.3373 0.9612991 254.067 0.9673759 250.2938 0.9728466 245.3498 0.967782 242.9146 0.9654288 240.5036 0.9444144 238.1164 0.9269778 236.9318 0.9488637 236.9318 0.9771202 236.9318 0.9830479 235.753 0.97499 234.5801 0.968623 233.4131 0.9521769 233.4131 0.9390221 233.4131 0.9339334 233.4131 0.887956 232.2518 0.9046763 231.0963 0.8827981 229.9466 0.8236388 231.0963 0.7853005 231.0963 0.8529194 229.9466 0.8421693 227.6642 0.880672 224.2832 0.8143209 219.853 0.8765387 215.5104 0.8224545 210.2025 0.5476995 204.0054 0.3984698 197.0059 0.2524756 189.3 0.0114817 180.9906 0.2040667 172.185 -0.1669366 163.8079 0.504205 154.2915 0.7180874 151.2439 0.8632782 151.2439 0.8973259 150.4914 0.9185986 151.2439 0.7587776 154.2915 0.7147576 159.7734 0.7589291 165.4501 0.8840488 171.3284 0.972356 175.6547 0.9816653 179.1942 0.988443 180.9906 0.9923041 181.8956 0.9943824 182.8051 0.9964477 183.7191 0.9936554 181.8956 0.9887792 180.0902 0.9771134 175.6547 0.9618319 170.476 0.9328524 167.9442 0.819974 168.784 0.8450117 170.476 0.8293109 171.3284 0.6963592 171.3284 0.6338254 164.6269 0.7285098 158.9785 0.7664092 154.2915 0.8064316 152.0001 0.9278697 152.0001 0.9533199 151.2439 0.9601526 149.7427 0.9562845 148.9977 0.963026 149.7427 0.9602929 149.7427 0.8744306 150.4914 0.5927675 154.2915 0.3564559 159.7734 0.2405773 164.6269 0.2860079 169.6279 0.6529107 173.9112 0.835753 176.533 0.8849658 179.1942 0.875807 180.9906 0.823069 182.8051 0.6626108 184.6377 0.2836408 187.4211 0.6051244 190.2465 0.7253854 193.1145 0.765985 196.0257 0.8194041 198.9809 0.6263421 201.9805 0.8017131 205.0254 0.682602 209.1568 0.5036187 213.3714 0.5814967 218.7592 0.814868 224.2832 0.8269848 229.9466 0.7358219 235.753 0.4268066 241.7061 0.8835183 247.8095 0.8267587 254.067 0.5491355 259.1866 0.8746379 264.4093 0.8389229 269.7372 0.6826822 275.1726 0.9028191 280.7175 0.8286572 286.3741 0.4525082 292.1447 0.7583002 298.0316 0.9073849 304.037 0.9051184 310.1635 0.64346 316.4135 0.9253378 322.7894 0.9132795 329.2938 0.6598362 334.2579 0.9356085 339.2969 0.9236958 344.4118 0.8228285 349.6039 0.9376769 354.8742 0.9356694 360.224 0.9184375 365.6544 0.9058462 371.1667 0.9012623 374.8877 0.9611984 378.6459 0.9567629 382.4419 0.7675866 384.3541 0.9645271 386.2758 0.9546855 388.2072 0.7844603 388.2072 0.9640375 388.2072 0.9452955 388.2072 0.5753929 388.2072 0.394645 388.2072 0.5464906 388.2072 0.7876784 388.2072 0.7982122 388.2072 0.5932955 388.2072 0.4936025 388.2072 0.7250561 388.2072 0.6559195 388.2072 0.7656435 388.2072 0.9420093 388.2072 0.7749707 388.2072 ] ================================================ FILE: audio/tools/setup_helpers/__init__.py ================================================ from .extension import * ================================================ FILE: audio/tools/setup_helpers/extension.py ================================================ import os import platform import subprocess from pathlib import Path import distutils.sysconfig from setuptools import Extension from setuptools.command.build_ext import build_ext __all__ = [ "get_ext_modules", "CMakeBuild", ] _THIS_DIR = Path(__file__).parent.resolve() _ROOT_DIR = _THIS_DIR.parent.parent.resolve() _PADDLESPEECH_DIR = _ROOT_DIR / "paddleaudio" def _get_build(var, default=False): if var not in os.environ: return default val = os.environ.get(var, "0") trues = ["1", "true", "TRUE", "on", "ON", "yes", "YES"] falses = ["0", "false", "FALSE", "off", "OFF", "no", "NO"] if val in trues: return True if val not in falses: print(f"WARNING: Unexpected environment variable value `{var}={val}`. " f"Expected one of {trues + falses}") return False _BUILD_SOX = False if platform.system() == "Windows" else _get_build( "BUILD_SOX", True) _BUILD_MAD = _get_build("BUILD_MAD", False) _BUILD_KALDI = False if platform.system() == "Windows" else _get_build( "BUILD_KALDI", True) _PADDLESPEECH_CUDA_ARCH_LIST = os.environ.get("PADDLESPEECH_CUDA_ARCH_LIST", None) def get_ext_modules(): if platform.system() == "Windows": return [] modules = [ Extension(name="paddleaudio.lib.libpaddleaudio", sources=[]), Extension(name="paddleaudio._paddleaudio", sources=[]), ] return modules # Based off of # https://github.com/pybind/cmake_example/blob/580c5fd29d4651db99d8874714b07c0c49a53f8a/setup.py class CMakeBuild(build_ext): def run(self): try: subprocess.check_output(["cmake", "--version"]) except OSError: raise RuntimeError("CMake is not available.") from None super().run() def build_extension(self, ext): # Since two library files (libpaddleaudio and _paddleaudio) need to be # recognized by setuptools, we instantiate `Extension` twice. (see `get_ext_modules`) # This leads to the situation where this `build_extension` method is called twice. # However, the following `cmake` command will build all of them at the same time, # so, we do not need to perform `cmake` twice. # Therefore we call `cmake` only for `paddleaudio._paddleaudio`. if ext.name != "paddleaudio._paddleaudio": return extdir = os.path.abspath( os.path.dirname(self.get_ext_fullpath(ext.name))) # required for auto-detection of auxiliary "native" libs if not extdir.endswith(os.path.sep): extdir += os.path.sep cfg = "Debug" if self.debug else "Release" cmake_args = [ f"-DCMAKE_BUILD_TYPE={cfg}", # f"-DCMAKE_PREFIX_PATH={torch.utils.cmake_prefix_path}", f"-DCMAKE_INSTALL_PREFIX={extdir}", "-DCMAKE_VERBOSE_MAKEFILE=ON", f"-DPYTHON_INCLUDE_DIR={distutils.sysconfig.get_python_inc()}", #f"-DPYTHON_LIBRARY={distutils.sysconfig.get_config_var('LIBDIR')}", f"-DBUILD_SOX:BOOL={'ON' if _BUILD_SOX else 'OFF'}", f"-DBUILD_MAD:BOOL={'ON' if _BUILD_MAD else 'OFF'}", f"-DBUILD_KALDI:BOOL={'ON' if _BUILD_KALDI else 'OFF'}", # f"-DBUILD_RNNT:BOOL={'ON' if _BUILD_RNNT else 'OFF'}", # f"-DBUILD_CTC_DECODER:BOOL={'ON' if _BUILD_CTC_DECODER else 'OFF'}", "-DBUILD_PADDLEAUDIO_PYTHON_EXTENSION:BOOL=ON", # f"-DUSE_ROCM:BOOL={'ON' if _USE_ROCM else 'OFF'}", # f"-DUSE_CUDA:BOOL={'ON' if _USE_CUDA else 'OFF'}", # f"-DUSE_OPENMP:BOOL={'ON' if _USE_OPENMP else 'OFF'}", # f"-DUSE_FFMPEG:BOOL={'ON' if _USE_FFMPEG else 'OFF'}", ] build_args = ["--target", "install"] # Pass CUDA architecture to cmake if _PADDLESPEECH_CUDA_ARCH_LIST is not None: # Convert MAJOR.MINOR[+PTX] list to new style one # defined at https://cmake.org/cmake/help/latest/prop_tgt/CUDA_ARCHITECTURES.html _arches = _PADDLESPEECH_CUDA_ARCH_LIST.replace(".", "").replace( " ", ";").split(";") _arches = [ arch[:-4] if arch.endswith("+PTX") else f"{arch}-real" for arch in _arches ] cmake_args += [f"-DCMAKE_CUDA_ARCHITECTURES={';'.join(_arches)}"] # Default to Ninja if "CMAKE_GENERATOR" not in os.environ or platform.system() == "Windows": cmake_args += ["-GNinja"] if platform.system() == "Windows": import sys python_version = sys.version_info cmake_args += [ "-DCMAKE_C_COMPILER=cl", "-DCMAKE_CXX_COMPILER=cl", f"-DPYTHON_VERSION={python_version.major}.{python_version.minor}", ] # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level # across all generators. if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: # self.parallel is a Python 3 only way to set parallel jobs by hand # using -j in the build_ext call, not supported by pip or PyPA-build. if hasattr(self, "parallel") and self.parallel: # CMake 3.12+ only. build_args += ["-j{}".format(self.parallel)] if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) print( f"cmake {_ROOT_DIR} {' '.join(cmake_args)}, cwd={self.build_temp}") subprocess.check_call( ["cmake", str(_ROOT_DIR)] + cmake_args, cwd=self.build_temp) print(f"cmake --build . {' '.join(build_args)}, cwd={self.build_temp}") subprocess.check_call( ["cmake", "--build", "."] + build_args, cwd=self.build_temp) def get_ext_filename(self, fullname): ext_filename = super().get_ext_filename(fullname) ext_filename_parts = ext_filename.split(".") without_abi = ext_filename_parts[:-2] + ext_filename_parts[-1:] ext_filename = ".".join(without_abi) return ext_filename ================================================ FILE: dataset/aishell/.gitignore ================================================ data_aishell* *.meta manifest.* *.tgz resource_aishell ================================================ FILE: dataset/aishell/aishell.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Aishell mandarin dataset Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ from paddlespeech.dataset.aishell import aishell_main if __name__ == '__main__': aishell_main() ================================================ FILE: dataset/aishell3/README.md ================================================ # [Aishell3](http://www.openslr.org/93/) AISHELL-3 is a large-scale and high-fidelity multi-speaker Mandarin speech corpus which could be used to train multi-speaker Text-to-Speech (TTS) systems. The corpus contains roughly **85 hours** of emotion-neutral recordings spoken by 218 native Chinese mandarin speakers and total 88035 utterances. Their auxiliary attributes such as gender, age group and native accents are explicitly marked and provided in the corpus. Accordingly, transcripts in Chinese character-level and pinyin-level are provided along with the recordings. The word & tone transcription accuracy rate is above 98%, through professional speech annotation and strict quality inspection for tone and prosody. ( This database is free for academic research, not in the commerce, if without permission. ) ================================================ FILE: dataset/chime3_background/chime3_background.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare CHiME3 background data. Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import io import json import os import zipfile import soundfile import wget from paddle.v2.dataset.common import md5file # DATA_HOME = os.path.expanduser('~/.cache/paddle/dataset/speech') DATA_HOME = os.path.expanduser('.') URL = "https://d4s.myairbridge.com/packagev2/AG0Y3DNBE5IWRRTV/?dlid=W19XG7T0NNHB027139H0EQ" MD5 = "c3ff512618d7a67d4f85566ea1bc39ec" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/chime3_background", type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_filepath", default="manifest.chime3.background", type=str, help="Filepath for output manifests. (default: %(default)s)") args = parser.parse_args() def download(url, md5sum, target_dir, filename=None): """Download file from url to target_dir, and check md5sum.""" if filename is None: filename = url.split("/")[-1] if not os.path.exists(target_dir): os.makedirs(target_dir) filepath = os.path.join(target_dir, filename) if not (os.path.exists(filepath) and md5file(filepath) == md5sum): print("Downloading %s ..." % url) wget.download(url, target_dir) print("\nMD5 Checksum %s ..." % filepath) if not md5file(filepath) == md5sum: raise RuntimeError("MD5 checksum failed.") else: print("File exists, skip downloading. (%s)" % filepath) return filepath def unpack(filepath, target_dir): """Unpack the file to the target_dir.""" print("Unpacking %s ..." % filepath) if filepath.endswith('.zip'): zip = zipfile.ZipFile(filepath, 'r') zip.extractall(target_dir) zip.close() elif filepath.endswith('.tar') or filepath.endswith('.tar.gz'): tar = zipfile.open(filepath) tar.extractall(target_dir) tar.close() else: raise ValueError("File format is not supported for unpacking.") def create_manifest(data_dir, manifest_path): """Create a manifest json file summarizing the data set, with each line containing the meta data (i.e. audio filepath, transcription text, audio duration) of each audio file within the data set. """ print("Creating manifest %s ..." % manifest_path) json_lines = [] for subfolder, _, filelist in sorted(os.walk(data_dir)): for filename in filelist: if filename.endswith('.wav'): filepath = os.path.join(data_dir, subfolder, filename) audio_data, samplerate = soundfile.read(filepath) duration = float(len(audio_data)) / samplerate json_lines.append( json.dumps( { 'utt': os.path.splitext(os.path.basename(filepath))[ 0], 'feat': filepath, 'feat_shape': (duration, ), # second 'type': 'background' })) with io.open(manifest_path, mode='w', encoding='utf8') as out_file: for line in json_lines: out_file.write(line + '\n') def prepare_chime3(url, md5sum, target_dir, manifest_path): """Download, unpack and create summary manifest file.""" if not os.path.exists(os.path.join(target_dir, "CHiME3")): # download filepath = download(url, md5sum, target_dir, "myairbridge-AG0Y3DNBE5IWRRTV.zip") # unpack unpack(filepath, target_dir) unpack( os.path.join(target_dir, 'CHiME3_background_bus.zip'), target_dir) unpack( os.path.join(target_dir, 'CHiME3_background_caf.zip'), target_dir) unpack( os.path.join(target_dir, 'CHiME3_background_ped.zip'), target_dir) unpack( os.path.join(target_dir, 'CHiME3_background_str.zip'), target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) # create manifest json file create_manifest(target_dir, manifest_path) def main(): prepare_chime3( url=URL, md5sum=MD5, target_dir=args.target_dir, manifest_path=args.manifest_filepath) if __name__ == '__main__': main() ================================================ FILE: dataset/gigaspeech/.gitignore ================================================ GigaSpeech/ ================================================ FILE: dataset/gigaspeech/README.md ================================================ # [GigaSpeech](https://github.com/SpeechColab/GigaSpeech) ``` git clone https://github.com/SpeechColab/GigaSpeech.git cd GigaSpeech utils/gigaspeech_download.sh /disk1/audio_data/gigaspeech toolkits/kaldi/gigaspeech_data_prep.sh --train-subset XL /disk1/audio_data/gigaspeech ../data cd .. ``` ================================================ FILE: dataset/gigaspeech/gigaspeech.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. ================================================ FILE: dataset/gigaspeech/run.sh ================================================ #!/bin/bash set -e curdir=$PWD test -d GigaSpeech || git clone https://github.com/SpeechColab/GigaSpeech.git pushd GigaSpeech source env_vars.sh ./utils/download_gigaspeech.sh ${curdir}/ #toolkits/kaldi/gigaspeech_data_prep.sh --train-subset XL /disk1/audio_data/gigaspeech ../data popd ================================================ FILE: dataset/librispeech/.gitignore ================================================ dev-clean dev-other test-clean test-other train-clean-100 train-clean-360 train-other-500 *.meta manifest.* ================================================ FILE: dataset/librispeech/librispeech.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Librispeech ASR datasets. Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import io import json import os from multiprocessing.pool import Pool import distutils.util import soundfile from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unpack from paddlespeech.utils.argparse import strtobool URL_ROOT = "http://openslr.elda.org/resources/12" #URL_ROOT = "https://openslr.magicdatatech.com/resources/12" URL_TEST_CLEAN = URL_ROOT + "/test-clean.tar.gz" URL_TEST_OTHER = URL_ROOT + "/test-other.tar.gz" URL_DEV_CLEAN = URL_ROOT + "/dev-clean.tar.gz" URL_DEV_OTHER = URL_ROOT + "/dev-other.tar.gz" URL_TRAIN_CLEAN_100 = URL_ROOT + "/train-clean-100.tar.gz" URL_TRAIN_CLEAN_360 = URL_ROOT + "/train-clean-360.tar.gz" URL_TRAIN_OTHER_500 = URL_ROOT + "/train-other-500.tar.gz" MD5_TEST_CLEAN = "32fa31d27d2e1cad72775fee3f4849a9" MD5_TEST_OTHER = "fb5a50374b501bb3bac4815ee91d3135" MD5_DEV_CLEAN = "42e2234ba48799c1f50f24a7926300a1" MD5_DEV_OTHER = "c8d0bcc9cca99d4f8b62fcc847357931" MD5_TRAIN_CLEAN_100 = "2a93770f6d5c6c964bc36631d331a522" MD5_TRAIN_CLEAN_360 = "c0e676e450a7ff2f54aeade5171606fa" MD5_TRAIN_OTHER_500 = "d1a0fd59409feb2c614ce4d30c387708" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default='~/.cache/paddle/dataset/speech/libri', type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") parser.add_argument( "--full_download", default="True", type=strtobool, help="Download all datasets for Librispeech." " If False, only download a minimal requirement (test-clean, dev-clean" " train-clean-100). (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path): """Create a manifest json file summarizing the data set, with each line containing the meta data (i.e. audio filepath, transcription text, audio duration) of each audio file within the data set. """ print("Creating manifest %s ..." % manifest_path) json_lines = [] total_sec = 0.0 total_char = 0.0 total_num = 0 for subfolder, _, filelist in sorted(os.walk(data_dir)): text_filelist = [ filename for filename in filelist if filename.endswith('trans.txt') ] if len(text_filelist) > 0: text_filepath = os.path.join(subfolder, text_filelist[0]) for line in io.open(text_filepath, encoding="utf8"): segments = line.strip().split() nchars = len(segments[1:]) text = ' '.join(segments[1:]).lower() audio_filepath = os.path.abspath( os.path.join(subfolder, segments[0] + '.flac')) audio_data, samplerate = soundfile.read(audio_filepath) duration = float(len(audio_data)) / samplerate utt = os.path.splitext(os.path.basename(audio_filepath))[0] utt2spk = '-'.join(utt.split('-')[:2]) json_lines.append( json.dumps({ 'utt': utt, 'utt2spk': utt2spk, 'feat': audio_filepath, 'feat_shape': (duration, ), # second 'text': text, })) total_sec += duration total_char += nchars total_num += 1 with codecs.open(manifest_path, 'w', 'utf-8') as out_file: for line in json_lines: out_file.write(line + '\n') subset = os.path.splitext(manifest_path)[1][1:] manifest_dir = os.path.dirname(manifest_path) data_dir_name = os.path.split(data_dir)[-1] meta_path = os.path.join(manifest_dir, data_dir_name) + '.meta' with open(meta_path, 'w') as f: print(f"{subset}:", file=f) print(f"{total_num} utts", file=f) print(f"{total_sec / (60*60)} h", file=f) print(f"{total_char} char", file=f) print(f"{total_char / total_sec} char/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def prepare_dataset(url, md5sum, target_dir, manifest_path): """Download, unpack and create summary manifest file. """ if not os.path.exists(os.path.join(target_dir, "LibriSpeech")): # download filepath = download(url, md5sum, target_dir) # unpack unpack(filepath, target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) # create manifest json file create_manifest(target_dir, manifest_path) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) tasks = [ (URL_TEST_CLEAN, MD5_TEST_CLEAN, os.path.join(args.target_dir, "test-clean"), args.manifest_prefix + ".test-clean"), (URL_DEV_CLEAN, MD5_DEV_CLEAN, os.path.join( args.target_dir, "dev-clean"), args.manifest_prefix + ".dev-clean"), ] if args.full_download: tasks.extend([ (URL_TRAIN_CLEAN_100, MD5_TRAIN_CLEAN_100, os.path.join(args.target_dir, "train-clean-100"), args.manifest_prefix + ".train-clean-100"), (URL_TEST_OTHER, MD5_TEST_OTHER, os.path.join(args.target_dir, "test-other"), args.manifest_prefix + ".test-other"), (URL_DEV_OTHER, MD5_DEV_OTHER, os.path.join(args.target_dir, "dev-other"), args.manifest_prefix + ".dev-other"), (URL_TRAIN_CLEAN_360, MD5_TRAIN_CLEAN_360, os.path.join(args.target_dir, "train-clean-360"), args.manifest_prefix + ".train-clean-360"), (URL_TRAIN_OTHER_500, MD5_TRAIN_OTHER_500, os.path.join(args.target_dir, "train-other-500"), args.manifest_prefix + ".train-other-500"), ]) with Pool(7) as pool: pool.starmap(prepare_dataset, tasks) print("Data download and manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/magicdata/README.md ================================================ # [MagicData](http://openslr.elda.org/68/) MAGICDATA Mandarin Chinese Read Speech Corpus was developed by MAGIC DATA Technology Co., Ltd. and freely published for non-commercial use. The contents and the corresponding descriptions of the corpus include: * The corpus contains 755 hours of speech data, which is mostly mobile recorded data. * 1080 speakers from different accent areas in China are invited to participate in the recording. * The sentence transcription accuracy is higher than 98%. * Recordings are conducted in a quiet indoor environment. * The database is divided into training set, validation set, and testing set in a ratio of 51: 1: 2. * Detail information such as speech data coding and speaker information is preserved in the metadata file. * The domain of recording texts is diversified, including interactive Q&A, music search, SNS messages, home command and control, etc. * Segmented transcripts are also provided. The corpus aims to support researchers in speech recognition, machine translation, speaker recognition, and other speech-related fields. Therefore, the corpus is totally free for academic use. ================================================ FILE: dataset/mini_librispeech/.gitignore ================================================ dev-clean/ manifest.dev-clean manifest.train-clean train-clean/ *.meta ================================================ FILE: dataset/mini_librispeech/mini_librispeech.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Librispeech ASR datasets. Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import io import json import os from multiprocessing.pool import Pool import soundfile from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unpack URL_ROOT = "http://openslr.elda.org/resources/31" URL_TRAIN_CLEAN = URL_ROOT + "/train-clean-5.tar.gz" URL_DEV_CLEAN = URL_ROOT + "/dev-clean-2.tar.gz" MD5_TRAIN_CLEAN = "5df7d4e78065366204ca6845bb08f490" MD5_DEV_CLEAN = "6d7ab67ac6a1d2c993d050e16d61080d" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default='~/.cache/paddle/dataset/speech/libri', type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path): """Create a manifest json file summarizing the data set, with each line containing the meta data (i.e. audio filepath, transcription text, audio duration) of each audio file within the data set. """ print("Creating manifest %s ..." % manifest_path) json_lines = [] total_sec = 0.0 total_text = 0.0 total_num = 0 for subfolder, _, filelist in sorted(os.walk(data_dir)): text_filelist = [ filename for filename in filelist if filename.endswith('trans.txt') ] if len(text_filelist) > 0: text_filepath = os.path.join(subfolder, text_filelist[0]) for line in io.open(text_filepath, encoding="utf8"): segments = line.strip().split() text = ' '.join(segments[1:]).lower() audio_filepath = os.path.join(subfolder, segments[0] + '.flac') audio_data, samplerate = soundfile.read(audio_filepath) duration = float(len(audio_data)) / samplerate utt = os.path.splitext(os.path.basename(audio_filepath))[0] utt2spk = '-'.join(utt.split('-')[:2]) json_lines.append( json.dumps({ 'utt': utt, 'utt2spk': utt2spk, 'feat': audio_filepath, 'feat_shape': (duration, ), #second 'text': text, })) total_sec += duration total_text += len(text) total_num += 1 with codecs.open(manifest_path, 'w', 'utf-8') as out_file: for line in json_lines: out_file.write(line + '\n') subset = os.path.splitext(manifest_path)[1][1:] manifest_dir = os.path.dirname(manifest_path) data_dir_name = os.path.split(data_dir)[-1] meta_path = os.path.join(manifest_dir, data_dir_name) + '.meta' with open(meta_path, 'w') as f: print(f"{subset}:", file=f) print(f"{total_num} utts", file=f) print(f"{total_sec / (60*60)} h", file=f) print(f"{total_text} text", file=f) print(f"{total_text / total_sec} text/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def prepare_dataset(url, md5sum, target_dir, manifest_path): """Download, unpack and create summary manifest file. """ if not os.path.exists(os.path.join(target_dir, "LibriSpeech")): # download filepath = download(url, md5sum, target_dir) # unpack unpack(filepath, target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) # create manifest json file create_manifest(target_dir, manifest_path) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) tasks = [ (URL_TRAIN_CLEAN, MD5_TRAIN_CLEAN, os.path.join(args.target_dir, "train-clean"), args.manifest_prefix + ".train-clean"), (URL_DEV_CLEAN, MD5_DEV_CLEAN, os.path.join( args.target_dir, "dev-clean"), args.manifest_prefix + ".dev-clean"), ] with Pool(2) as pool: pool.starmap(prepare_dataset, tasks) print("Data download and manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/multi_cn/README.md ================================================ # multi-cn This is a Chinese speech recognition recipe that trains on all Chinese corpora on OpenSLR, including: * Aidatatang (140 hours) * Aishell (151 hours) * MagicData (712 hours) * Primewords (99 hours) * ST-CMDS (110 hours) * THCHS-30 (26 hours) * optional AISHELL2 (~1000 hours) if available ================================================ FILE: dataset/primewords/README.md ================================================ # [Primewords](http://openslr.elda.org/47/) This free Chinese Mandarin speech corpus set is released by Shanghai Primewords Information Technology Co., Ltd. The corpus is recorded by smart mobile phones from 296 native Chinese speakers. The transcription accuracy is larger than 98%, at the confidence level of 95%. It is free for academic use. The mapping between the transcript and utterance is given in JSON format. ================================================ FILE: dataset/rir_noise/.gitignore ================================================ RIRS_NOISES/ manifest.pointsource_noises manifest.real_rirs_isotropic_noises manifest.simulated_rirs rirs_noises.zip ================================================ FILE: dataset/rir_noise/rir_noise.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Aishell mandarin dataset Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import argparse import codecs import json import os import soundfile from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unzip DATA_HOME = os.path.expanduser('~/.cache/paddle/dataset/speech') URL_ROOT = '--no-check-certificate https://us.openslr.org/resources/28/rirs_noises.zip' DATA_URL = URL_ROOT + '/rirs_noises.zip' MD5_DATA = 'e6f48e257286e05de56413b4779d8ffb' parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/rirs_noise", type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path_prefix): print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] data_types = [ 'pointsource_noises', 'real_rirs_isotropic_noises', 'simulated_rirs' ] for dtype in data_types: del json_lines[:] audio_dir = os.path.join(data_dir, dtype) for subfolder, _, filelist in sorted(os.walk(audio_dir)): for fname in filelist: audio_path = os.path.join(subfolder, fname) if not audio_path.endswith('.wav'): continue audio_data, samplerate = soundfile.read(audio_path) duration = float(len(audio_data) / samplerate) json_lines.append( json.dumps( { 'utt': os.path.splitext(os.path.basename(audio_path))[0], 'feat': audio_path, 'feat_shape': (duration, ), #second 'type': dtype, }, ensure_ascii=False)) manifest_path = manifest_path_prefix + '.' + dtype if not os.path.exists(os.path.dirname(manifest_path)): os.makedirs(os.path.dirname(manifest_path)) with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') def prepare_dataset(url, md5sum, target_dir, manifest_path): """Download, unzip and create manifest file.""" data_dir = os.path.join(target_dir, 'RIRS_NOISES') if not os.path.exists(data_dir): filepath = download(url, md5sum, target_dir) unzip(filepath, target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) create_manifest(data_dir, manifest_path) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) prepare_dataset( url=DATA_URL, md5sum=MD5_DATA, target_dir=args.target_dir, manifest_path=args.manifest_prefix) if __name__ == '__main__': main() ================================================ FILE: dataset/st-cmds/README.md ================================================ # [FreeST](http://openslr.elda.org/38/) ================================================ FILE: dataset/tal_cs/README.md ================================================ # [TAL_CSASR](https://ai.100tal.com/dataset/) This data set is TAL English class audio, including mixed Chinese and English speech. Each audio has only one speaker, and this data set has more than 100 speakers. (File 63.36G) This data contains the sample of intra sentence and inter sentence mixing. The ratio between Chinese characters and English words in the data is 13:1. - Total data: 587H (train_set: 555.9H, dev_set: 8H, test_set: 23.6H) - Sample rate: 16000 - Sample bit: 16 - Recording device: microphone - Speaker number: 200+ - Recording time: 2019 - Data format: audio: .wav; test: .txt - Audio duration: 1-60s - Data type: audio of English teachers' teaching ================================================ FILE: dataset/tal_cs/tal_cs.py ================================================ # Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare TALCS ASR datasets. create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import io import json import os import soundfile parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() TRAIN_SET = os.path.join(args.target_dir, "train_set") DEV_SET = os.path.join(args.target_dir, "dev_set") TEST_SET = os.path.join(args.target_dir, "test_set") manifest_train_path = os.path.join(args.manifest_prefix, "manifest.train.raw") manifest_dev_path = os.path.join(args.manifest_prefix, "manifest.dev.raw") manifest_test_path = os.path.join(args.manifest_prefix, "manifest.test.raw") def create_manifest(data_dir, manifest_path): """Create a manifest json file summarizing the data set, with each line containing the meta data (i.e. audio filepath, transcription text, audio duration) of each audio file within the data set. """ print("Creating manifest %s ..." % manifest_path) json_lines = [] total_sec = 0.0 total_char = 0.0 total_num = 0 wav_dir = os.path.join(data_dir, 'wav') text_filepath = os.path.join(data_dir, 'label.txt') for subfolder, _, filelist in sorted(os.walk(wav_dir)): for line in io.open(text_filepath, encoding="utf8"): segments = line.strip().split() nchars = len(segments[1:]) text = ' '.join(segments[1:]).lower() audio_filepath = os.path.abspath( os.path.join(subfolder, segments[0] + '.wav')) audio_data, samplerate = soundfile.read(audio_filepath) duration = float(len(audio_data)) / samplerate utt = os.path.splitext(os.path.basename(audio_filepath))[0] utt2spk = '-'.join(utt.split('-')[:2]) json_lines.append( json.dumps({ 'utt': utt, 'utt2spk': utt2spk, 'feat': audio_filepath, 'feat_shape': (duration, ), # second 'text': text, })) total_sec += duration total_char += nchars total_num += 1 with codecs.open(manifest_path, 'w', 'utf-8') as out_file: for line in json_lines: out_file.write(line + '\n') subset = os.path.splitext(manifest_path)[1][1:] manifest_dir = os.path.dirname(manifest_path) data_dir_name = os.path.split(data_dir)[-1] meta_path = os.path.join(manifest_dir, data_dir_name) + '.meta' with open(meta_path, 'w') as f: print(f"{subset}:", file=f) print(f"{total_num} utts", file=f) print(f"{total_sec / (60*60)} h", file=f) print(f"{total_char} char", file=f) print(f"{total_char / total_sec} char/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) create_manifest(TRAIN_SET, manifest_train_path) create_manifest(DEV_SET, manifest_dev_path) create_manifest(TEST_SET, manifest_test_path) print("Data download and manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/ted_en_zh/.gitignore ================================================ *.tar.gz.* manifest.* *.md EN-ZH/ train-split/ test-segment/ ================================================ FILE: dataset/ted_en_zh/ted_en_zh.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Ted-En-Zh speech translation dataset Create manifest files from splited dataset. dev set: tst2010, test set: tst2015 Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import json import os import soundfile parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--src-dir", default="", type=str, help="Directory to kaldi splited data. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path_prefix): print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] data_types_infos = [ ('train', 'train-split/train-segment', 'En-Zh/train.en-zh'), ('dev', 'test-segment/tst2010', 'En-Zh/tst2010.en-zh'), ('test', 'test-segment/tst2015', 'En-Zh/tst2015.en-zh') ] for data_info in data_types_infos: dtype, audio_relative_dir, text_relative_path = data_info del json_lines[:] total_sec = 0.0 total_text = 0.0 total_num = 0 text_path = os.path.join(data_dir, text_relative_path) audio_dir = os.path.join(data_dir, audio_relative_dir) for line in codecs.open(text_path, 'r', 'utf-8', errors='ignore'): line = line.strip() if len(line) < 1: continue audio_id, trancription, translation = line.split('\t') utt = audio_id.split('.')[0] audio_path = os.path.join(audio_dir, audio_id) if os.path.exists(audio_path): if os.path.getsize(audio_path) < 30000: continue audio_data, samplerate = soundfile.read(audio_path) duration = float(len(audio_data) / samplerate) translation_str = " ".join(translation.split()) trancription_str = " ".join(trancription.split()) json_lines.append( json.dumps( { 'utt': utt, 'feat': audio_path, 'feat_shape': (duration, ), # second 'text': [translation_str, trancription_str], }, ensure_ascii=False)) total_sec += duration total_text += len(translation.split()) total_num += 1 if not total_num % 1000: print(dtype, 'Processed:', total_num) manifest_path = manifest_path_prefix + '.' + dtype + '.raw' with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') def prepare_dataset(src_dir, manifest_path=None): """create manifest file.""" if os.path.isdir(manifest_path): manifest_path = os.path.join(manifest_path, 'manifest') if manifest_path: create_manifest(src_dir, manifest_path) def main(): if args.src_dir.startswith('~'): args.src_dir = os.path.expanduser(args.src_dir) prepare_dataset(src_dir=args.src_dir, manifest_path=args.manifest_prefix) print("manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/thchs30/.gitignore ================================================ *.tgz manifest.* data_thchs30 resource test-noise *.meta ================================================ FILE: dataset/thchs30/README.md ================================================ # [THCHS30](http://openslr.elda.org/18/) This is the *data part* of the `THCHS30 2015` acoustic data & scripts dataset. The dataset is described in more detail in the paper ``THCHS-30 : A Free Chinese Speech Corpus`` by Dong Wang, Xuewei Zhang. A paper (if it can be called a paper) 13 years ago regarding the database: Dong Wang, Dalei Wu, Xiaoyan Zhu, ``TCMSD: A new Chinese Continuous Speech Database``, International Conference on Chinese Computing (ICCC'01), 2001, Singapore. The layout of this data pack is the following: ``data`` ``*.wav`` audio data ``*.wav.trn`` transcriptions ``{train,dev,test}`` contain symlinks into the ``data`` directory for both audio and transcription files. Contents of these directories define the train/dev/test split of the data. ``{lm_word}`` ``word.3gram.lm`` trigram LM based on word ``lexicon.txt`` lexicon based on word ``{lm_phone}`` ``phone.3gram.lm`` trigram LM based on phone ``lexicon.txt`` lexicon based on phone ``README.TXT`` this file Data statistics =============== Statistics for the data are as follows: =========== ========== ========== =========== **dataset** **audio** **#sents** **#words** =========== ========== ========== =========== train 25 10,000 198,252 dev 2:14 893 17,743 test 6:15 2,495 49,085 =========== ========== ========== =========== ================================================ FILE: dataset/thchs30/thchs30.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare THCHS-30 mandarin dataset Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import json import os from multiprocessing.pool import Pool from pathlib import Path import soundfile from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unpack DATA_HOME = os.path.expanduser('~/.cache/paddle/dataset/speech') URL_ROOT = 'http://openslr.elda.org/resources/18' # URL_ROOT = 'https://openslr.magicdatatech.com/resources/18' DATA_URL = URL_ROOT + '/data_thchs30.tgz' TEST_NOISE_URL = URL_ROOT + '/test-noise.tgz' RESOURCE_URL = URL_ROOT + '/resource.tgz' MD5_DATA = '2d2252bde5c8429929e1841d4cb95e90' MD5_TEST_NOISE = '7e8a985fb965b84141b68c68556c2030' MD5_RESOURCE = 'c0b2a565b4970a0c4fe89fefbf2d97e1' parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/THCHS30", type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def read_trn(filepath): """read trn file. word text in first line. syllable text in second line. phoneme text in third line. Args: filepath (str): trn path. Returns: list(str): (word, syllable, phone) """ texts = [] with open(filepath, 'r') as f: lines = f.read().strip().split('\n') assert len(lines) == 3, lines # character text, remove whitespace texts.append(''.join(lines[0].split())) texts.extend(lines[1:]) return texts def resolve_symlink(filepath): """resolve symlink which content is norm file. Args: filepath (str): norm file symlink. """ sym_path = Path(filepath) relative_link = sym_path.read_text().strip() relative = Path(relative_link) relpath = sym_path.parent / relative return relpath.resolve() def create_manifest(data_dir, manifest_path_prefix): print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] data_types = ['train', 'dev', 'test'] for dtype in data_types: del json_lines[:] total_sec = 0.0 total_text = 0.0 total_num = 0 audio_dir = os.path.join(data_dir, dtype) for subfolder, _, filelist in sorted(os.walk(audio_dir)): for fname in filelist: file_path = os.path.join(subfolder, fname) if file_path.endswith('.wav'): audio_path = os.path.abspath(file_path) text_path = resolve_symlink(audio_path + '.trn') else: continue assert os.path.exists(audio_path) and os.path.exists(text_path) audio_id = os.path.basename(audio_path)[:-4] spk = audio_id.split('_')[0] word_text, syllable_text, phone_text = read_trn(text_path) audio_data, samplerate = soundfile.read(audio_path) duration = float(len(audio_data) / samplerate) # not dump alignment infos json_lines.append( json.dumps( { 'utt': audio_id, 'utt2spk': spk, 'feat': audio_path, 'feat_shape': (duration, ), # second 'text': word_text, # character 'syllable': syllable_text, 'phone': phone_text, }, ensure_ascii=False)) total_sec += duration total_text += len(word_text) total_num += 1 manifest_path = manifest_path_prefix + '.' + dtype with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') manifest_dir = os.path.dirname(manifest_path_prefix) meta_path = os.path.join(manifest_dir, dtype) + '.meta' with open(meta_path, 'w') as f: print(f"{dtype}:", file=f) print(f"{total_num} utts", file=f) print(f"{total_sec / (60*60)} h", file=f) print(f"{total_text} text", file=f) print(f"{total_text / total_sec} text/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def prepare_dataset(url, md5sum, target_dir, manifest_path, subset): """Download, unpack and create manifest file.""" datadir = os.path.join(target_dir, subset) if not os.path.exists(datadir): filepath = download(url, md5sum, target_dir) unpack(filepath, target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) if subset == 'data_thchs30': create_manifest(datadir, manifest_path) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) tasks = [ (DATA_URL, MD5_DATA, args.target_dir, args.manifest_prefix, "data_thchs30"), (TEST_NOISE_URL, MD5_TEST_NOISE, args.target_dir, args.manifest_prefix, "test-noise"), (RESOURCE_URL, MD5_RESOURCE, args.target_dir, args.manifest_prefix, "resource"), ] with Pool(7) as pool: pool.starmap(prepare_dataset, tasks) print("Data download and manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/timit/.gitignore ================================================ TIMIT.* TIMIT manifest.* *.meta ================================================ FILE: dataset/timit/timit.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare Librispeech ASR datasets. Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import json import os import re import string from pathlib import Path import soundfile from paddlespeech.dataset.download import unzip URL_ROOT = "" MD5_DATA = "45c68037c7fdfe063a43c851f181fb2d" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default='~/.cache/paddle/dataset/speech/timit', type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() #: A string containing Chinese punctuation marks (non-stops). non_stops = ( # Fullwidth ASCII variants '\uFF02\uFF03\uFF04\uFF05\uFF06\uFF07\uFF08\uFF09\uFF0A\uFF0B\uFF0C\uFF0D' '\uFF0F\uFF1A\uFF1B\uFF1C\uFF1D\uFF1E\uFF20\uFF3B\uFF3C\uFF3D\uFF3E\uFF3F' '\uFF40\uFF5B\uFF5C\uFF5D\uFF5E\uFF5F\uFF60' # Halfwidth CJK punctuation '\uFF62\uFF63\uFF64' # CJK symbols and punctuation '\u3000\u3001\u3003' # CJK angle and corner brackets '\u3008\u3009\u300A\u300B\u300C\u300D\u300E\u300F\u3010\u3011' # CJK brackets and symbols/punctuation '\u3014\u3015\u3016\u3017\u3018\u3019\u301A\u301B\u301C\u301D\u301E\u301F' # Other CJK symbols '\u3030' # Special CJK indicators '\u303E\u303F' # Dashes '\u2013\u2014' # Quotation marks and apostrophe '\u2018\u2019\u201B\u201C\u201D\u201E\u201F' # General punctuation '\u2026\u2027' # Overscores and underscores '\uFE4F' # Small form variants '\uFE51\uFE54' # Latin punctuation '\u00B7') #: A string of Chinese stops. stops = ( '\uFF01' # Fullwidth exclamation mark '\uFF1F' # Fullwidth question mark '\uFF61' # Halfwidth ideographic full stop '\u3002' # Ideographic full stop ) #: A string containing all Chinese punctuation. punctuation = non_stops + stops def tn(text): # lower text text = text.lower() # remove punc text = re.sub(f'[{punctuation}{string.punctuation}]', "", text) return text def read_txt(filepath: str) -> str: with open(filepath, 'r') as f: line = f.read().strip().split(maxsplit=2)[2] return tn(line) def read_algin(filepath: str) -> str: """read word or phone alignment file. Args: filepath (str): [description] Returns: str: token separate by """ aligns = [] # (start, end, token) with open(filepath, 'r') as f: for line in f: items = line.strip().split() # for phone: (Note: beginning and ending silence regions are marked with h#) if items[2].strip() == 'h#': continue aligns.append(items) return ' '.join([item[2] for item in aligns]) def create_manifest(data_dir, manifest_path_prefix): """Create a manifest json file summarizing the data set, with each line containing the meta data (i.e. audio filepath, transcription text, audio duration) of each audio file within the data set. """ print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] utts = set() data_types = ['TRAIN', 'TEST'] for dtype in data_types: del json_lines[:] total_sec = 0.0 total_text = 0.0 total_num = 0 audio_dir = Path(os.path.join(data_dir, dtype)) for fname in sorted(audio_dir.rglob('*.WAV')): audio_path = fname.resolve() # .WAV audio_id = audio_path.stem # if uttid exits, then skipped if audio_id in utts: continue utts.add(audio_id) text_path = audio_path.with_suffix('.TXT') phone_path = audio_path.with_suffix('.PHN') word_path = audio_path.with_suffix('.WRD') audio_data, samplerate = soundfile.read( str(audio_path), dtype='int16') duration = float(len(audio_data) / samplerate) word_text = read_txt(text_path) phone_text = read_algin(phone_path) gender_spk = str(audio_path.parent.stem) spk = gender_spk[1:] gender = gender_spk[0] utt_id = '_'.join([spk, gender, audio_id]) # not dump alignment infos json_lines.append( json.dumps( { 'utt': utt_id, 'utt2spk': spk, 'utt2gender': gender, 'feat': str(audio_path), 'feat_shape': (duration, ), # second 'text': word_text, # word 'phone': phone_text, }, ensure_ascii=False)) total_sec += duration total_text += len(word_text.split()) total_num += 1 manifest_path = manifest_path_prefix + '.' + dtype.lower() with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') manifest_dir = os.path.dirname(manifest_path_prefix) meta_path = os.path.join(manifest_dir, dtype.lower()) + '.meta' with open(meta_path, 'w') as f: print(f"{dtype}:", file=f) print(f"{total_num} utts", file=f) print(f"{total_sec / (60*60)} h", file=f) print(f"{total_text} text", file=f) print(f"{total_text / total_sec} text/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def prepare_dataset(url, md5sum, target_dir, manifest_path): """Download, unpack and create summary manifest file. """ filepath = os.path.join(target_dir, "TIMIT.zip") if not os.path.exists(filepath): print(f"Please download TIMIT.zip into {target_dir}.") raise FileNotFoundError if not os.path.exists(os.path.join(target_dir, "TIMIT")): # check md5sum assert check_md5sum(filepath, md5sum) # unpack unzip(filepath, target_dir) else: print("Skip downloading and unpacking. Data already exists in %s." % target_dir) # create manifest json file create_manifest(os.path.join(target_dir, "TIMIT"), manifest_path) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) prepare_dataset(URL_ROOT, MD5_DATA, args.target_dir, args.manifest_prefix) print("Data download and manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/timit/timit_kaldi_standard_split.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare TIMIT dataset (Standard split from Kaldi) Create manifest files from splited dataset. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import json import os from pathlib import Path import soundfile parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--src_dir", default="", type=str, help="Directory to kaldi splited data. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path_prefix): print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] data_types = ['train', 'dev', 'test'] for dtype in data_types: del json_lines[:] total_sec = 0.0 total_text = 0.0 total_num = 0 phn_path = os.path.join(data_dir, dtype + '.text') phn_dict = {} for line in codecs.open(phn_path, 'r', 'utf-8'): line = line.strip() if line == '': continue audio_id, text = line.split(' ', 1) phn_dict[audio_id] = text audio_dir = os.path.join(data_dir, dtype + '_sph.scp') for line in codecs.open(audio_dir, 'r', 'utf-8'): audio_id, audio_path = line.strip().split() # if no transcription for audio then raise error assert audio_id in phn_dict audio_data, samplerate = soundfile.read(audio_path) duration = float(len(audio_data) / samplerate) text = phn_dict[audio_id] gender_spk = str(Path(audio_path).parent.stem) spk = gender_spk[1:] gender = gender_spk[0] utt_id = '_'.join([spk, gender, audio_id]) json_lines.append( json.dumps( { 'utt': audio_id, 'utt2spk': spk, 'utt2gender': gender, 'feat': audio_path, 'feat_shape': (duration, ), # second 'text': text }, ensure_ascii=False)) total_sec += duration total_text += len(text) total_num += 1 manifest_path = manifest_path_prefix + '.' + dtype + '.raw' with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') def prepare_dataset(src_dir, manifest_path=None): """create manifest file.""" if os.path.isdir(manifest_path): manifest_path = os.path.join(manifest_path, 'manifest') if manifest_path: create_manifest(src_dir, manifest_path) def main(): if args.src_dir.startswith('~'): args.src_dir = os.path.expanduser(args.src_dir) prepare_dataset(src_dir=args.src_dir, manifest_path=args.manifest_prefix) print("manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/voxceleb/README.md ================================================ # [VoxCeleb](http://www.robots.ox.ac.uk/~vgg/data/voxceleb/) VoxCeleb is an audio-visual dataset consisting of short clips of human speech, extracted from interview videos uploaded to YouTube。 VoxCeleb contains speech from speakers spanning a wide range of different ethnicities, accents, professions and ages. All speaking face-tracks are captured "in the wild", with background chatter, laughter, overlapping speech, pose variation and different lighting conditions. VoxCeleb consists of both audio and video. Each segment is at least 3 seconds long. The dataset consists of two versions, VoxCeleb1 and VoxCeleb2. Each version has it's own train/test split. For each we provide YouTube URLs, face detections and tracks, audio files, cropped face videos and speaker meta-data. There is no overlap between the two versions. more info in details refers to http://www.robots.ox.ac.uk/~vgg/data/voxceleb/ ================================================ FILE: dataset/voxceleb/voxceleb1.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare VoxCeleb1 dataset create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. researchers should download the voxceleb1 dataset yourselves through google form to get the username & password and unpack the data """ import argparse import codecs import glob import json import os import subprocess from pathlib import Path import soundfile from paddlespeech.dataset.download import check_md5sum from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unzip # all the data will be download in the current data/voxceleb directory default DATA_HOME = os.path.expanduser('.') # if you use the http://www.robots.ox.ac.uk/~vgg/data/voxceleb/vox1a/ as the download base url # you need to get the username & password via the google form # if you use the https://thor.robots.ox.ac.uk/~vgg/data/voxceleb/vox1a as the download base url, # you need use --no-check-certificate to connect the target download url BASE_URL = "https://thor.robots.ox.ac.uk/~vgg/data/voxceleb/vox1a" # dev data DEV_LIST = { "vox1_dev_wav_partaa": "e395d020928bc15670b570a21695ed96", "vox1_dev_wav_partab": "bbfaaccefab65d82b21903e81a8a8020", "vox1_dev_wav_partac": "017d579a2a96a077f40042ec33e51512", "vox1_dev_wav_partad": "7bb1e9f70fddc7a678fa998ea8b3ba19", } DEV_TARGET_DATA = "vox1_dev_wav_parta* vox1_dev_wav.zip ae63e55b951748cc486645f532ba230b" # test data TEST_LIST = {"vox1_test_wav.zip": "185fdc63c3c739954633d50379a3d102"} TEST_TARGET_DATA = "vox1_test_wav.zip vox1_test_wav.zip 185fdc63c3c739954633d50379a3d102" # voxceleb trial TRIAL_BASE_URL = "https://www.robots.ox.ac.uk/~vgg/data/voxceleb/meta/" TRIAL_LIST = { "veri_test.txt": "29fc7cc1c5d59f0816dc15d6e8be60f7", # voxceleb1 "veri_test2.txt": "b73110731c9223c1461fe49cb48dddfc", # voxceleb1(cleaned) "list_test_hard.txt": "21c341b6b2168eea2634df0fb4b8fff1", # voxceleb1-H "list_test_hard2.txt": "857790e09d579a68eb2e339a090343c8", # voxceleb1-H(cleaned) "list_test_all.txt": "b9ecf7aa49d4b656aa927a8092844e4a", # voxceleb1-E "list_test_all2.txt": "a53e059deb562ffcfc092bf5d90d9f3a" # voxceleb1-E(cleaned) } parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/voxceleb1/", type=str, help="Directory to save the voxceleb1 dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path_prefix): print(f"Creating manifest {manifest_path_prefix} from {data_dir}") json_lines = [] data_path = os.path.join(data_dir, "wav", "**", "*.wav") total_sec = 0.0 total_text = 0.0 total_num = 0 speakers = set() for audio_path in glob.glob(data_path, recursive=True): audio_id = "-".join(audio_path.split("/")[-3:]) utt2spk = audio_path.split("/")[-3] duration = soundfile.info(audio_path).duration text = "" json_lines.append( json.dumps( { "utt": audio_id, "utt2spk": str(utt2spk), "feat": audio_path, "feat_shape": (duration, ), "text": text # compatible with asr data format }, ensure_ascii=False)) total_sec += duration total_text += len(text) total_num += 1 speakers.add(utt2spk) # data_dir_name refer to dev or test # voxceleb1 is given explicit in the path data_dir_name = Path(data_dir).name manifest_path_prefix = manifest_path_prefix + "." + data_dir_name if not os.path.exists(os.path.dirname(manifest_path_prefix)): os.makedirs(os.path.dirname(manifest_path_prefix)) with codecs.open(manifest_path_prefix, 'w', encoding='utf-8') as f: for line in json_lines: f.write(line + "\n") manifest_dir = os.path.dirname(manifest_path_prefix) meta_path = os.path.join(manifest_dir, "voxceleb1." + data_dir_name) + ".meta" with codecs.open(meta_path, 'w', encoding='utf-8') as f: print(f"{total_num} utts", file=f) print(f"{len(speakers)} speakers", file=f) print(f"{total_sec / (60 * 60)} h", file=f) print(f"{total_text} text", file=f) print(f"{total_text / total_sec} text/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def prepare_dataset(base_url, data_list, target_dir, manifest_path, target_data): if not os.path.exists(target_dir): os.makedirs(target_dir) # wav directory already exists, it need do nothing # we will download the voxceleb1 data to ${target_dir}/vox1/dev/ or ${target_dir}/vox1/test directory if not os.path.exists(os.path.join(target_dir, "wav")): # download all dataset part print(f"start to download the vox1 zip package to {target_dir}") for zip_part in data_list.keys(): download_url = " --no-check-certificate " + base_url + "/" + zip_part download( url=download_url, md5sum=data_list[zip_part], target_dir=target_dir) # pack the all part to target zip file all_target_part, target_name, target_md5sum = target_data.split() target_name = os.path.join(target_dir, target_name) if not os.path.exists(target_name): pack_part_cmd = "cat {}/{} > {}".format(target_dir, all_target_part, target_name) subprocess.call(pack_part_cmd, shell=True) # check the target zip file md5sum if not check_md5sum(target_name, target_md5sum): raise RuntimeError("{} MD5 checksum failed".format(target_name)) else: print("Check {} md5sum successfully".format(target_name)) # unzip the all zip file if target_name.endswith(".zip"): unzip(target_name, target_dir) # create the manifest file create_manifest(data_dir=target_dir, manifest_path_prefix=manifest_path) def prepare_trial(base_url, data_list, target_dir): if not os.path.exists(target_dir): os.makedirs(target_dir) for trial, md5sum in data_list.items(): target_trial = os.path.join(target_dir, trial) if not os.path.exists(os.path.join(target_dir, trial)): download_url = " --no-check-certificate " + base_url + "/" + trial download(url=download_url, md5sum=md5sum, target_dir=target_dir) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) # prepare the vox1 dev data prepare_dataset( base_url=BASE_URL, data_list=DEV_LIST, target_dir=os.path.join(args.target_dir, "dev"), manifest_path=args.manifest_prefix, target_data=DEV_TARGET_DATA) # prepare the vox1 test data prepare_dataset( base_url=BASE_URL, data_list=TEST_LIST, target_dir=os.path.join(args.target_dir, "test"), manifest_path=args.manifest_prefix, target_data=TEST_TARGET_DATA) # prepare the vox1 trial prepare_trial( base_url=TRIAL_BASE_URL, data_list=TRIAL_LIST, target_dir=os.path.dirname(args.manifest_prefix)) print("Manifest prepare done!") if __name__ == '__main__': main() ================================================ FILE: dataset/voxceleb/voxceleb2.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare VoxCeleb2 dataset Download and unpack the voxceleb2 data files. Voxceleb2 data is stored as the m4a format, so we need convert the m4a to wav with the convert.sh scripts """ import argparse import codecs import glob import json import os import subprocess from pathlib import Path import soundfile from paddlespeech.dataset.download import check_md5sum from paddlespeech.dataset.download import download from paddlespeech.dataset.download import unzip # all the data will be download in the current data/voxceleb directory default DATA_HOME = os.path.expanduser('.') BASE_URL = "--no-check-certificate https://www.robots.ox.ac.uk/~vgg/data/voxceleb/data/" # dev data DEV_LIST = { "vox2_dev_aac_partaa": "da070494c573e5c0564b1d11c3b20577", "vox2_dev_aac_partab": "17fe6dab2b32b48abaf1676429cdd06f", "vox2_dev_aac_partac": "1de58e086c5edf63625af1cb6d831528", "vox2_dev_aac_partad": "5a043eb03e15c5a918ee6a52aad477f9", "vox2_dev_aac_partae": "cea401b624983e2d0b2a87fb5d59aa60", "vox2_dev_aac_partaf": "fc886d9ba90ab88e7880ee98effd6ae9", "vox2_dev_aac_partag": "d160ecc3f6ee3eed54d55349531cb42e", "vox2_dev_aac_partah": "6b84a81b9af72a9d9eecbb3b1f602e65", } DEV_TARGET_DATA = "vox2_dev_aac_parta* vox2_dev_aac.zip bbc063c46078a602ca71605645c2a402" # test data TEST_LIST = {"vox2_test_aac.zip": "0d2b3ea430a821c33263b5ea37ede312"} TEST_TARGET_DATA = "vox2_test_aac.zip vox2_test_aac.zip 0d2b3ea430a821c33263b5ea37ede312" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/voxceleb2/", type=str, help="Directory to save the voxceleb1 dataset. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") parser.add_argument( "--download", default=False, action="store_true", help="Download the voxceleb2 dataset. (default: %(default)s)") parser.add_argument( "--generate", default=False, action="store_true", help="Generate the manifest files. (default: %(default)s)") args = parser.parse_args() def create_manifest(data_dir, manifest_path_prefix): """Generate the voxceleb2 dataset manifest file. We will create the ${manifest_path_prefix}.vox2 as the final manifest file The dev and test wav info will be put in one manifest file. Args: data_dir (str): voxceleb2 wav directory, which include dev and test subdataset manifest_path_prefix (str): manifest file prefix """ print("Creating manifest %s ..." % manifest_path_prefix) json_lines = [] data_path = os.path.join(data_dir, "**", "*.wav") total_sec = 0.0 total_text = 0.0 total_num = 0 speakers = set() for audio_path in glob.glob(data_path, recursive=True): audio_id = "-".join(audio_path.split("/")[-3:]) utt2spk = audio_path.split("/")[-3] duration = soundfile.info(audio_path).duration text = "" json_lines.append( json.dumps( { "utt": audio_id, "utt2spk": str(utt2spk), "feat": audio_path, "feat_shape": (duration, ), "text": text # compatible with asr data format }, ensure_ascii=False)) total_sec += duration total_text += len(text) total_num += 1 speakers.add(utt2spk) # data_dir_name refer to dev or test # voxceleb2 is given explicit in the path data_dir_name = Path(data_dir).name manifest_path_prefix = manifest_path_prefix + "." + data_dir_name if not os.path.exists(os.path.dirname(manifest_path_prefix)): os.makedirs(os.path.dirname(manifest_path_prefix)) with codecs.open(manifest_path_prefix, 'w', encoding='utf-8') as f: for line in json_lines: f.write(line + "\n") manifest_dir = os.path.dirname(manifest_path_prefix) meta_path = os.path.join(manifest_dir, "voxceleb2." + data_dir_name) + ".meta" with codecs.open(meta_path, 'w', encoding='utf-8') as f: print(f"{total_num} utts", file=f) print(f"{len(speakers)} speakers", file=f) print(f"{total_sec / (60 * 60)} h", file=f) print(f"{total_text} text", file=f) print(f"{total_text / total_sec} text/sec", file=f) print(f"{total_sec / total_num} sec/utt", file=f) def download_dataset(base_url, data_list, target_data, target_dir, dataset): """Download the voxceleb2 zip package Args: base_url (str): the voxceleb2 dataset download baseline url data_list (dict): the dataset part zip package and the md5 value target_data (str): the final dataset zip info target_dir (str): the dataset stored directory dataset (str): the dataset name, dev or test Raises: RuntimeError: the md5sum occurs error """ if not os.path.exists(target_dir): os.makedirs(target_dir) # wav directory already exists, it need do nothing print("target dir {}".format(os.path.join(target_dir, dataset))) # unzip the dev dataset will create the dev and unzip the m4a to dev dir # but the test dataset will unzip to aac # so, wo create the ${target_dir}/test and unzip the m4a to test dir if not os.path.exists(os.path.join(target_dir, dataset)): print(f"start to download the vox2 zip package to {target_dir}") for zip_part in data_list.keys(): download_url = " --no-check-certificate " + base_url + "/" + zip_part download( url=download_url, md5sum=data_list[zip_part], target_dir=target_dir) # pack the all part to target zip file all_target_part, target_name, target_md5sum = target_data.split() target_name = os.path.join(target_dir, target_name) if not os.path.exists(target_name): pack_part_cmd = "cat {}/{} > {}".format(target_dir, all_target_part, target_name) subprocess.call(pack_part_cmd, shell=True) # check the target zip file md5sum if not check_md5sum(target_name, target_md5sum): raise RuntimeError("{} MD5 checksum failed".format(target_name)) else: print("Check {} md5sum successfully".format(target_name)) if dataset == "test": # we need make the test directory unzip(target_name, os.path.join(target_dir, "test")) else: # unzip dev zip package and will create the dev directory unzip(target_name, target_dir) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) # download and unpack the vox2-dev data print("download: {}".format(args.download)) if args.download: download_dataset( base_url=BASE_URL, data_list=DEV_LIST, target_data=DEV_TARGET_DATA, target_dir=args.target_dir, dataset="dev") download_dataset( base_url=BASE_URL, data_list=TEST_LIST, target_data=TEST_TARGET_DATA, target_dir=args.target_dir, dataset="test") print("VoxCeleb2 download is done!") if args.generate: create_manifest( args.target_dir, manifest_path_prefix=args.manifest_prefix) if __name__ == '__main__': main() ================================================ FILE: dataset/voxforge/run_data.sh ================================================ #! /usr/bin/env bash TARGET_DIR=${MAIN_ROOT}/dataset/voxforge mkdir -p ${TARGET_DIR} # download data, generate manifests python ${MAIN_ROOT}/dataset/voxforge/voxforge.py \ --manifest_prefix="${TARGET_DIR}/manifest" \ --target_dir="${TARGET_DIR}" \ --is_merge_dialect=True \ --dialects 'american' 'british' 'australian' 'european' 'irish' 'canadian' 'indian' if [ $? -ne 0 ]; then echo "Prepare VoxForge failed. Terminated." exit 1 fi echo "VoxForge Data preparation done." exit 0 ================================================ FILE: dataset/voxforge/voxforge.py ================================================ # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # 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. """Prepare VoxForge dataset Download, unpack and create manifest files. Manifest file is a json-format file with each line containing the meta data (i.e. audio filepath, transcript and audio duration) of each audio file in the data set. """ import argparse import codecs import datetime import json import os import shutil import subprocess import soundfile from paddlespeech.dataset.download import download_multi from paddlespeech.dataset.download import getfile_insensitive from paddlespeech.dataset.download import unpack DATA_HOME = os.path.expanduser('~/.cache/paddle/dataset/speech') DATA_URL = 'http://www.repository.voxforge1.org/downloads/SpeechCorpus/Trunk/' \ 'Audio/Main/16kHz_16bit' parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--target_dir", default=DATA_HOME + "/VoxForge", type=str, help="Directory to save the dataset. (default: %(default)s)") parser.add_argument( "--dialects", default=[ 'american', 'british', 'australian', 'european', 'irish', 'canadian', 'indian' ], nargs='+', type=str, help="Dialect types. (default: %(default)s)") parser.add_argument( "--is_merge_dialect", default=True, type=bool, help="If set True, manifests of american dialect and canadian dialect will " "be merged to american-canadian dialect; manifests of british " "dialect, irish dialect and australian dialect will be merged to " "commonwealth dialect. (default: %(default)s)") parser.add_argument( "--manifest_prefix", default="manifest", type=str, help="Filepath prefix for output manifests. (default: %(default)s)") args = parser.parse_args() def download_and_unpack(target_dir, url): wget_args = '-q -l 1 -N -nd -c -e robots=off -A tgz -r -np' tgz_dir = os.path.join(target_dir, 'tgz') exit_code = download_multi(url, tgz_dir, wget_args) if exit_code != 0: print('Download tgz audio files failed with exit code %d.' % exit_code) else: print('Download done, start unpacking ...') audio_dir = os.path.join(target_dir, 'audio') for root, dirs, files in os.walk(tgz_dir): for file in files: print(file) if file.endswith('.tgz'): unpack(os.path.join(root, file), audio_dir) def select_dialects(target_dir, dialect_list): """Classify audio files by dialect.""" dialect_root_dir = os.path.join(target_dir, 'dialect') if os.path.exists(dialect_root_dir): shutil.rmtree(dialect_root_dir) os.mkdir(dialect_root_dir) audio_dir = os.path.abspath(os.path.join(target_dir, 'audio')) for dialect in dialect_list: # filter files by dialect command = 'find %s -iwholename "*etc/readme*" -exec egrep -iHl \ "pronunciation dialect.*%s" {} \;' % (audio_dir, dialect) p = subprocess.Popen( command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) output, err = p.communicate() dialect_dir = os.path.join(dialect_root_dir, dialect) if os.path.exists(dialect_dir): shutil.rmtree(dialect_dir) os.mkdir(dialect_dir) for path in output.splitlines(): src_dir = os.path.dirname(os.path.dirname(path)) link = os.path.basename(os.path.normpath(src_dir)) os.symlink(src_dir, os.path.join(dialect_dir, link)) def generate_manifest(data_dir, manifest_path): json_lines = [] for path in os.listdir(data_dir): audio_link = os.path.join(data_dir, path) assert os.path.islink( audio_link), '%s should be symbolic link.' % audio_link actual_audio_dir = os.path.abspath(os.readlink(audio_link)) audio_type = '' if os.path.isdir(os.path.join(actual_audio_dir, 'wav')): audio_type = 'wav' elif os.path.isdir(os.path.join(actual_audio_dir, 'flac')): audio_type = 'flac' else: print('Unknown audio type, skipped processing %s.' % actual_audio_dir) continue etc_dir = os.path.join(actual_audio_dir, 'etc') prompts_file = os.path.join(etc_dir, 'PROMPTS') if not os.path.isfile(prompts_file): print('PROMPTS file missing, skip processing %s.' % actual_audio_dir) continue readme_file = getfile_insensitive(os.path.join(etc_dir, 'README')) if readme_file is None: print('README file missing, skip processing %s.' % actual_audio_dir) continue for line in file(prompts_file): u, trans = line.strip().split(None, 1) u_parts = u.split('/') # try to format the date time try: speaker, date, sfx = u_parts[-3].split('-') obj = datetime.datetime.strptime(date, '%y.%m.%d') formatted = obj.strftime('%Y%m%d') u_parts[-3] = '-'.join([speaker, formatted, sfx]) except Exception as e: pass if len(u_parts) < 2: u_parts = [audio_type] + u_parts u_parts[-2] = audio_type u_parts[-1] += '.' + audio_type u = os.path.join(actual_audio_dir, '/'.join(u_parts[-2:])) if not os.path.isfile(u): print('Audio file missing, skip processing %s.' % u) continue if os.stat(u).st_size == 0: print('Empty audio file, skip processing %s.' % u) continue trans = trans.strip().replace('-', ' ') if not trans.isupper() or \ not trans.strip().replace(' ', '').replace("'", "").isalpha(): print("Transcript not normalized properly, skip processing %s." % u) continue audio_data, samplerate = soundfile.read(u) duration = float(len(audio_data)) / samplerate utt = os.path.splitext(os.path.basename(u))[0] json_lines.append( json.dumps({ 'utt': utt, 'utt2spk': speaker, 'feat': u, 'feat_shape': (duration, ), #second 'text': trans.lower() })) with codecs.open(manifest_path, 'w', 'utf-8') as fout: for line in json_lines: fout.write(line + '\n') def merge_manifests(manifest_files, save_path): lines = [] for manifest_file in manifest_files: line = codecs.open(manifest_file, 'r', 'utf-8').readlines() lines += line with codecs.open(save_path, 'w', 'utf-8') as fout: for line in lines: fout.write(line) def prepare_dataset(url, dialects, target_dir, manifest_prefix, is_merge): download_and_unpack(target_dir, url) select_dialects(target_dir, dialects) american_canadian_manifests = [] commonwealth_manifests = [] for dialect in dialects: dialect_dir = os.path.join(target_dir, 'dialect', dialect) manifest_fpath = manifest_prefix + '.' + dialect if dialect == 'american' or dialect == 'canadian': american_canadian_manifests.append(manifest_fpath) if dialect == 'australian' \ or dialect == 'british' \ or dialect == 'irish': commonwealth_manifests.append(manifest_fpath) generate_manifest(dialect_dir, manifest_fpath) if is_merge: if len(american_canadian_manifests) > 0: manifest_fpath = manifest_prefix + '.american-canadian' merge_manifests(american_canadian_manifests, manifest_fpath) if len(commonwealth_manifests) > 0: manifest_fpath = manifest_prefix + '.commonwealth' merge_manifests(commonwealth_manifests, manifest_fpath) def main(): if args.target_dir.startswith('~'): args.target_dir = os.path.expanduser(args.target_dir) prepare_dataset(DATA_URL, args.dialects, args.target_dir, args.manifest_prefix, args.is_merge_dialect) if __name__ == '__main__': main() ================================================ FILE: demos/README.md ================================================ # Speech Application based on PaddleSpeech ([简体中文](./README_cn.md)|English) This directory contains many speech applications in multiple scenarios. * audio searching - mass audio similarity retrieval * audio tagging - multi-label tagging of an audio file * automatic_video_subtitles - generate subtitles from a video * metaverse - 2D AR with TTS * punctuation_restoration - restore punctuation from raw text * speech recognition - recognize text of an audio file * speech server - Server for Speech Task, e.g. ASR,TTS,CLS * streaming asr server - receive audio stream from websocket, and recognize to transcript. * streaming tts server - receive text from http or websocket, and streaming audio data stream. * speech translation - end to end speech translation * story talker - book reader based on OCR and TTS * style_fs2 - multi style control for FastSpeech2 model * text_to_speech - convert text into speech * self supervised pretraining - speech feature extraction and speech recognition based on wav2vec2 * Whisper - speech recognize and translate based on Whisper model ================================================ FILE: demos/README_cn.md ================================================ # PaddleSpeech 语音应用 Demo (简体中文|[English](./README.md)) 该目录包含基于 PaddleSpeech 开发的不同场景的语音应用 Demo: * 声音检索 - 海量音频相似性检索。 * 声音分类 - 基于 AudioSet 的 527 类标签的音频多标签分类。 * 视频字幕生成 - 识别视频中语音的文本,并进行文本后处理。 * 元宇宙 - 基于语音合成的 2D 增强现实。 * 标点恢复 - 通常作为语音识别的文本后处理任务,为一段无标点的纯文本添加相应的标点符号。 * 语音识别 - 识别一段音频中包含的语音文字。 * 语音服务 - 离线语音服务,包括ASR、TTS、CLS等。 * 流式语音识别服务 - 流式输入语音数据流识别音频中的文字。 * 流式语音合成服务 - 根据待合成文本流式生成合成音频数据流。 * 语音翻译 - 实时识别音频中的语言,并同时翻译成目标语言。 * 会说话的故事书 - 基于 OCR 和语音合成的会说话的故事书。 * 个性化语音合成 - 基于 FastSpeech2 模型的个性化语音合成。 * 语音合成 - 基于给定的文本生成语音音频。 * 自监督预训练模型 - 基于wav2vec2的语音特征提取和语音识别。 * Whisper - 基于Whisper模型的语音识别与翻译。 ================================================ FILE: demos/TTSAndroid/.gitignore ================================================ *.iml .gradle /local.properties /.idea/caches /.idea/libraries /.idea/modules.xml /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml .DS_Store /build /captures .externalNativeBuild ================================================ FILE: demos/TTSAndroid/README.md ================================================ # 语音合成 Java API Demo 使用指南 在 Android 上实现语音合成功能,此 Demo 有很好的易用性和开放性,如在 Demo 中跑自己训练好的模型等。 本文主要介绍语音合成 Demo 运行方法。 ## 如何运行语音合成 Demo ### 环境准备 1. 在本地环境安装好 Android Studio 工具,详细安装方法请见 [Android Studio 官网](https://developer.android.com/studio)。 2. 准备一部 Android 手机,并开启 USB 调试模式。开启方法: `手机设置 -> 查找开发者选项 -> 打开开发者选项和 USB 调试模式`。 **注意**: > 如果您的 Android Studio 尚未配置 NDK ,请根据 Android Studio 用户指南中的[安装及配置 NDK 和 CMake ](https://developer.android.com/studio/projects/install-ndk)内容,预先配置好 NDK 。您可以选择最新的 NDK 版本,或者使用 Paddle Lite 预测库版本一样的 NDK。 ### 部署步骤 1. 用 Android Studio 打开 TTSAndroid 工程。 2. 手机连接电脑,打开 USB 调试和文件传输模式,并在 Android Studio 上连接自己的手机设备(手机需要开启允许从 USB 安装软件权限)。 **注意:** >1. 如果您在导入项目、编译或者运行过程中遇到 NDK 配置错误的提示,请打开 `File > Project Structure > SDK Location`,修改 `Android NDK location` 为您本机配置的 NDK 所在路径。 >2. 如果您是通过 Android Studio 的 SDK Tools 下载的 NDK (见本章节"环境准备"),可以直接点击下拉框选择默认路径。 >3. 还有一种 NDK 配置方法,你可以在 `TTSAndroid/local.properties` 文件中手动添加 NDK 路径配置 `nkd.dir=/root/android-ndk-r20b` >4. 如果以上步骤仍旧无法解决 NDK 配置错误,请尝试根据 Android Studio 官方文档中的[更新 Android Gradle 插件](https://developer.android.com/studio/releases/gradle-plugin?hl=zh-cn#updating-plugin)章节,尝试更新 Android Gradle plugin 版本。 3. 点击 Run 按钮,自动编译 APP 并安装到手机。(该过程会自动下载 Paddle Lite 预测库和模型,需要联网) 成功后效果如下: - pic 1:APP 安装到手机。 - pic 2:APP 打开后的效果,在下拉框中选择待合成的文本。 - pic 3:合成后点击按钮播放音频。

## 更新预测库 * Paddle Lite 项目:[https://github.com/PaddlePaddle/Paddle-Lite](https://github.com/PaddlePaddle/Paddle-Lite)。 参考 [Paddle Lite 源码编译文档](https://www.paddlepaddle.org.cn/lite/v2.11/source_compile/compile_env.html),编译 Android 预测库。 * 编译最终产物位于 `build.lite.xxx.xxx.xxx` 下的 `inference_lite_lib.xxx.xxx` * 替换 java 库 * jar 包 将生成的 `build.lite.android.xxx.gcc/inference_lite_lib.android.xxx/java/jar/PaddlePredictor.jar` 替换 Demo 中的 `TTSAndroid/app/libs/PaddlePredictor.jar`。 * Java so * arm64-v8a 将生成的 `build.lite.android.armv8.gcc/inference_lite_lib.android.armv8/java/so/libpaddle_lite_jni.so` 库替换 Demo 中的 `TTSAndroid/app/src/main/jniLibs/arm64-v8a/libpaddle_lite_jni.so`。 ## Demo 内容介绍 先整体介绍下目标检测 Demo 的代码结构,然后介绍 Java 各功能模块的功能。

image

### 重点关注内容 1. `Predictor.java`: 预测代码。 ```bash # 位置: TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/Predictor.java ``` 2. `fastspeech2_csmsc_arm.nb` 和 `mb_melgan_csmsc_arm.nb`: 模型文件 (opt 工具转化后 Paddle Lite 模型) ,分别来自 [fastspeech2_cnndecoder_csmsc_pdlite_1.3.0.zip](https://paddlespeech.cdn.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_cnndecoder_csmsc_pdlite_1.3.0.zip) 和 [mb_melgan_csmsc_pdlite_1.3.0.zip](https://paddlespeech.cdn.bcebos.com/Parakeet/released_models/mb_melgan/mb_melgan_csmsc_pdlite_1.3.0.zip)。 ```bash # 位置: TTSAndroid/app/src/main/assets/models/cpu/fastspeech2_csmsc_arm.nb TTSAndroid/app/src/main/assets/models/cpu/mb_melgan_csmsc_arm.nb ``` 3. `libpaddle_lite_jni.so`、`PaddlePredictor.jar`:Paddle Lite Java 预测库与 jar 包。 ```bash # 位置 TTSAndroid/app/src/main/jniLibs/arm64-v8a/libpaddle_lite_jni.so TTSAndroid/app/libs/PaddlePredictor.jar ``` > 如果要替换动态库 so 和 jar 文件,则将新的动态库 so 更新到 `TTSAndroid/app/src/main/jniLibs/arm64-v8a/` 目录下 新的 jar 文件更新到 `TTSAndroid/app/libs/` 目录下 4. `build.gradle` : 定义编译过程的 gradle 脚本。(不用改动,定义了自动下载 Paddle Lite 预测和模型的过程) ```bash # 位置 TTSAndroid/app/build.gradle ``` 如果需要手动更新模型和预测库,则可将 gradle 脚本中的 `download*` 接口注释即可, 将新的预测库替换至相应目录下 ### Java 端 * 模型存放,将下载好的模型解压存放在 `app/src/assets/models` 目录下。 * TTSAndroid Java 包在 `app/src/main/java/com/baidu/paddle/lite/demo/tts` 目录下,实现 APP 界面消息事件。 * MainActivity 实现 APP 的创建、运行、释放功能,重点关注 `onLoadModel` 和 `onRunModel` 函数,实现 APP 界面值传递和推理处理。 ```java public boolean onLoadModel() { return predictor.init(MainActivity.this, modelPath, AMmodelName, VOCmodelName, cpuThreadNum, cpuPowerMode); } public boolean onRunModel() { return predictor.isLoaded() && predictor.runModel(phones); } ``` * SettingActivity 实现设置界面各个元素的更新与显示如模型地址、线程数、输入 shape 大小等,如果新增/删除界面的某个元素,均在这个类里面实现: - 参数的默认值可在 `app/src/main/res/values/strings.xml` 查看 - 每个元素的 ID 和 value 是对应 `app/src/main/res/xml/settings.xml` 和 `app/src/main/res/values/string.xml` 文件中的值 - 这部分内容不建议修改,如果有新增属性,可以按照此格式进行添加 * Predictor 使用 Java API 实现语音合成模型的预测功能,重点关注 `init`、和 `runModel` 函数,实现 Paddle Lite 端侧推理功能: ```java // 初始化函数,完成预测器初始化 public boolean init(Context appCtx, String modelPath, String AMmodelName, String VOCmodelName, int cpuThreadNum, String cpuPowerMode); // 模型推理函数 public boolean runModel(float[] phones); ``` ## 代码讲解 (使用 Paddle Lite `Java API` 执行预测) Android 示例基于 Java API 开发,调用 Paddle Lite `Java API` 包括以下五步。更详细的 `API` 描述参考:[Paddle Lite Java API ](https://www.paddlepaddle.org.cn/lite/v2.11/api_reference/java_api_doc.html)。 ## 如何更新模型和输入 ### 更新模型 1. 将优化后的模型存放到目录 `TTSAndroid/app/src/main/assets/models/cpu/` 下,可任意换成 [released_model.md](https://github.com/PaddlePaddle/PaddleSpeech/blob/develop/docs/source/released_model.md) 中的 `*_pdlite_*.zip/*_arm.nb` 格式的声学模型和声码器,注意更换声学模型需要对应修改 `TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/MainActivity.java` 中的 `sentencesToChoose` 数组。 2. 如果模型名字跟工程中模型名字一模一样,即均是使用`fastspeech2_csmsc_arm.nb` (假设声学模型的 `phone_id_map.txt` 也一样)和 `mb_melgan_csmsc_arm.nb` ,则代码不需更新;否则,需要修改 `TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/MainActivity.java` 中的 `AMmodelName` 和 `VOCmodelName`:

3. 如果更新模型的输入/输出 Tensor 个数、shape 和 Dtype 发生更新,需要更新文件 `TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/Predictor.java`。 ### 更新输入 **本 Demo 不包含文本前端模块**,通过下拉框选择预先设置好的文本,在代码中映射成对应的 phone_id,**如需文本前端模块请自行处理**,可参考: - C++ 中文前端 [lym0302/paddlespeech_tts_cpp](https://github.com/lym0302/paddlespeech_tts_cpp) - C++ 英文 g2p [yazone/g2pE_mobile](https://github.com/yazone/g2pE_mobile) `phone_id_map.txt` 请参考 [fastspeech2_cnndecoder_csmsc_pdlite_1.3.0.zip](https://paddlespeech.cdn.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_cnndecoder_csmsc_pdlite_1.3.0.zip)。 ## 通过 setting 界面更新语音合成的相关参数 ### setting 界面参数介绍 可通过 APP 上的 Settings 按钮,实现语音合成 Demo 中参数的更新,目前支持以下参数的更新: 参数的默认值可在 `app/src/main/res/values/strings.xml` 查看 - CPU setting: - power_mode 默认是 `LITE_POWER_HIGH` - thread_num 默认是 1 ### setting 界面参数更新 1. 打开 APP,点击右上角的 `:` 符合,选择 `Settings..` 选项,打开 setting 界面; 2. 再将 setting 界面的 Enable custom settings 选中☑️,然后更新部分参数; 3. 假设更新线程数据,将 CPU Thread Num 设置为 4,更新后,返回原界面,APP 将自动重新加载模型,在下拉框中选择文本会进行合成,合成结束后悔打印 4 线程的耗时和结果 ## 性能优化方法 如果你觉得当前性能不符合需求,想进一步提升模型性能,可参考[性能优化文档](https://github.com/PaddlePaddle/Paddle-Lite-Demo#%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96)完成性能优化。 ## Release [2022-11-29-app-release.apk](https://paddlespeech.cdn.bcebos.com/demos/TTSAndroid/2022-11-29-app-release.apk) ## More 本 Demo 合并自 [yt605155624/TTSAndroid](https://github.com/yt605155624/TTSAndroid)。 ================================================ FILE: demos/TTSAndroid/app/.gitignore ================================================ /build ================================================ FILE: demos/TTSAndroid/app/build.gradle ================================================ import java.security.MessageDigest apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.baidu.paddle.lite.demo.tts" minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:28.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation files('libs/PaddlePredictor.jar') } def paddleLiteLibs = 'https://paddlespeech.cdn.bcebos.com/demos/TTSAndroid/paddle_lite_libs_68b66fd3.tar.gz' task downloadAndExtractPaddleLiteLibs(type: DefaultTask) { doFirst { println "Downloading and extracting Paddle Lite libs" } doLast { // Prepare cache folder for libs if (!file("cache").exists()) { mkdir "cache" } // Generate cache name for libs MessageDigest messageDigest = MessageDigest.getInstance('MD5') messageDigest.update(paddleLiteLibs.bytes) String cacheName = new BigInteger(1, messageDigest.digest()).toString(32) // Download libs if (!file("cache/${cacheName}.tar.gz").exists()) { ant.get(src: paddleLiteLibs, dest: file("cache/${cacheName}.tar.gz")) } // Unpack libs if (!file("cache/${cacheName}").exists()) { copy { from tarTree("cache/${cacheName}.tar.gz") into "cache/${cacheName}" } } // Copy PaddlePredictor.jar if (!file("libs/PaddlePredictor.jar").exists()) { copy { from "cache/${cacheName}/java/PaddlePredictor.jar" into "libs" } } if (!file("src/main/jniLibs/arm64-v8a/libpaddle_lite_jni.so").exists()) { copy { from "cache/${cacheName}/java/libs/arm64-v8a/" into "src/main/jniLibs/arm64-v8a" } } } } preBuild.dependsOn downloadAndExtractPaddleLiteLibs def paddleLiteModels = [['src' : 'https://paddlespeech.cdn.bcebos.com/demos/TTSAndroid/fs2cnn_mbmelgan_cpu_v1.3.0.tar.gz', 'dest': 'src/main/assets/models'],] task downloadAndExtractPaddleLiteModels(type: DefaultTask) { doFirst { println "Downloading and extracting Paddle Lite models" } doLast { // Prepare cache folder for models String cachePath = "cache" if (!file("${cachePath}").exists()) { mkdir "${cachePath}" } paddleLiteModels.eachWithIndex { model, index -> MessageDigest messageDigest = MessageDigest.getInstance('MD5') messageDigest.update(model.src.bytes) String cacheName = new BigInteger(1, messageDigest.digest()).toString(32) // Download the target model if not exists boolean copyFiles = !file("${model.dest}").exists() if (!file("${cachePath}/${cacheName}.tar.gz").exists()) { ant.get(src: model.src, dest: file("${cachePath}/${cacheName}.tar.gz")) copyFiles = true // force to copy files from the latest archive files } // Copy model file if (copyFiles) { copy { from tarTree("${cachePath}/${cacheName}.tar.gz") into "${model.dest}" } } } } } preBuild.dependsOn downloadAndExtractPaddleLiteModels ================================================ FILE: demos/TTSAndroid/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: demos/TTSAndroid/app/src/androidTest/java/com/baidu/paddle/lite/demo/tts/ExampleInstrumentedTest.java ================================================ package com.baidu.paddle.lite.demo.tts; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumented test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.baidu.paddle.lite.demo", appContext.getPackageName()); } } ================================================ FILE: demos/TTSAndroid/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: demos/TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/AppCompatPreferenceActivity.java ================================================ /* * Copyright (C) 2014 The Android Open Source Project * * 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. */ package com.baidu.paddle.lite.demo.tts; import android.content.res.Configuration; import android.os.Bundle; import android.preference.PreferenceActivity; import android.support.annotation.LayoutRes; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatDelegate; import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; /** * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls * to be used with AppCompat. *

* This technique can be used with an {@link android.app.Activity} class, not just * {@link android.preference.PreferenceActivity}. */ public abstract class AppCompatPreferenceActivity extends PreferenceActivity { private AppCompatDelegate mDelegate; @Override protected void onCreate(Bundle savedInstanceState) { getDelegate().installViewFactory(); getDelegate().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); getDelegate().onPostCreate(savedInstanceState); } public ActionBar getSupportActionBar() { return getDelegate().getSupportActionBar(); } @Override public MenuInflater getMenuInflater() { return getDelegate().getMenuInflater(); } @Override public void setContentView(@LayoutRes int layoutResID) { getDelegate().setContentView(layoutResID); } @Override public void setContentView(View view) { getDelegate().setContentView(view); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { getDelegate().setContentView(view, params); } @Override public void addContentView(View view, ViewGroup.LayoutParams params) { getDelegate().addContentView(view, params); } @Override protected void onPostResume() { super.onPostResume(); getDelegate().onPostResume(); } @Override protected void onTitleChanged(CharSequence title, int color) { super.onTitleChanged(title, color); getDelegate().setTitle(title); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); getDelegate().onConfigurationChanged(newConfig); } @Override protected void onStop() { super.onStop(); getDelegate().onStop(); } @Override protected void onDestroy() { super.onDestroy(); getDelegate().onDestroy(); } public void invalidateOptionsMenu() { getDelegate().invalidateOptionsMenu(); } private AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, null); } return mDelegate; } } ================================================ FILE: demos/TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/MainActivity.java ================================================ package com.baidu.paddle.lite.demo.tts; import android.Manifest; import android.app.ProgressDialog; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.IOException; public class MainActivity extends AppCompatActivity implements View.OnClickListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, AdapterView.OnItemSelectedListener { public static final int REQUEST_LOAD_MODEL = 0; public static final int REQUEST_RUN_MODEL = 1; public static final int RESPONSE_LOAD_MODEL_SUCCESSED = 0; public static final int RESPONSE_LOAD_MODEL_FAILED = 1; public static final int RESPONSE_RUN_MODEL_SUCCESSED = 2; public static final int RESPONSE_RUN_MODEL_FAILED = 3; public MediaPlayer mediaPlayer = new MediaPlayer(); private static final String TAG = Predictor.class.getSimpleName(); protected ProgressDialog pbLoadModel = null; protected ProgressDialog pbRunModel = null; // Receive messages from worker thread protected Handler receiver = null; // Send command to worker thread protected Handler sender = null; // Worker thread to load&run model protected HandlerThread worker = null; // UI components of image classification protected TextView tvInputSetting; protected TextView tvInferenceTime; protected Button btn_play; protected Button btn_pause; protected Button btn_stop; // Model settings of image classification protected String modelPath = ""; protected int cpuThreadNum = 1; protected String cpuPowerMode = ""; protected Predictor predictor = new Predictor(); int sampleRate = 24000; private final String wavName = "tts_output.wav"; private final String wavFile = Environment.getExternalStorageDirectory() + File.separator + wavName; private final String AMmodelName = "fastspeech2_csmsc_arm.nb"; private final String VOCmodelName = "mb_melgan_csmsc_arm.nb"; private float[] phones = {}; private final float[][] sentencesToChoose = { // 009901 昨日,这名“伤者”与医生全部被警方依法刑事拘留。 {261, 231, 175, 116, 179, 262, 44, 154, 126, 177, 19, 262, 42, 241, 72, 177, 56, 174, 245, 37, 186, 37, 49, 151, 127, 69, 19, 179, 72, 69, 4, 260, 126, 177, 116, 151, 239, 153, 141}, // 009902 钱伟长想到上海来办学校是经过深思熟虑的。 {174, 83, 213, 39, 20, 260, 89, 40, 30, 177, 22, 71, 9, 153, 8, 37, 17, 260, 251, 260, 99, 179, 177, 116, 151, 125, 70, 233, 177, 51, 176, 108, 177, 184, 153, 242, 40, 45}, // 009903 她见我一进门就骂,吃饭时也骂,骂得我抬不起头。 {182, 2, 151, 85, 232, 73, 151, 123, 154, 52, 151, 143, 154, 5, 179, 39, 113, 69, 17, 177, 114, 105, 154, 5, 179, 154, 5, 40, 45, 232, 182, 8, 37, 186, 174, 74, 182, 168}, // 009904 李述德在离开之前,只说了一句“柱驼杀父亲了”。 {153, 74, 177, 186, 40, 42, 261, 10, 153, 73, 152, 7, 262, 113, 174, 83, 179, 262, 115, 177, 230, 153, 45, 73, 151, 242, 180, 262, 186, 182, 231, 177, 2, 69, 186, 174, 124, 153, 45}, // 009905 这种车票和保险单捆绑出售属于重复性购买。 {262, 44, 262, 163, 39, 41, 173, 99, 71, 42, 37, 28, 260, 84, 40, 14, 179, 152, 220, 37, 21, 39, 183, 177, 170, 179, 177, 185, 240, 39, 162, 69, 186, 260, 128, 70, 170, 154, 9}, // 009906 戴佩妮的男友西米露接唱情歌,让她非常开心。 {40, 10, 173, 49, 155, 72, 40, 45, 155, 15, 142, 260, 72, 154, 74, 153, 186, 179, 151, 103, 39, 22, 174, 126, 70, 41, 179, 175, 22, 182, 2, 69, 46, 39, 20, 152, 7, 260, 120}, // 009907 观大势、谋大局、出大策始终是该院的办院方针。 {70, 199, 40, 5, 177, 116, 154, 168, 40, 5, 151, 240, 179, 39, 183, 40, 5, 38, 44, 179, 177, 115, 262, 161, 177, 116, 70, 7, 247, 40, 45, 37, 17, 247, 69, 19, 262, 51}, // 009908 他们骑着摩托回家,正好为农忙时的父母帮忙。 {182, 2, 154, 55, 174, 73, 262, 45, 154, 157, 182, 230, 71, 212, 151, 77, 180, 262, 59, 71, 29, 214, 155, 162, 154, 20, 177, 114, 40, 45, 69, 186, 154, 185, 37, 19, 154, 20}, // 009909 但是因为还没到退休年龄,只能掰着指头捱日子。 {40, 17, 177, 116, 120, 214, 71, 8, 154, 47, 40, 30, 182, 214, 260, 140, 155, 83, 153, 126, 180, 262, 115, 155, 57, 37, 7, 262, 45, 262, 115, 182, 171, 8, 175, 116, 261, 112}, // 009910 这几天雨水不断,人们恨不得待在家里不出门。 {262, 44, 151, 74, 182, 82, 240, 177, 213, 37, 184, 40, 202, 180, 175, 52, 154, 55, 71, 54, 37, 186, 40, 42, 40, 7, 261, 10, 151, 77, 153, 74, 37, 186, 39, 183, 154, 52} }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_play: if (!mediaPlayer.isPlaying()) { mediaPlayer.start(); } break; case R.id.btn_pause: if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } break; case R.id.btn_stop: if (mediaPlayer.isPlaying()) { mediaPlayer.reset(); initMediaPlayer(); } break; default: break; } } private void initMediaPlayer() { try { File file = new File(wavFile); // 指定音频文件的路径 mediaPlayer.setDataSource(file.getPath()); // 让 MediaPlayer 进入到准备状态 mediaPlayer.prepare(); // 该方法使得进入应用时就播放音频 // mediaPlayer.setOnPreparedListener(this); // prepare async to not block main thread mediaPlayer.prepareAsync(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onPrepared(MediaPlayer player) { player.start(); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { // The MediaPlayer has moved to the Error state, must be reset! mediaPlayer.reset(); initMediaPlayer(); return true; } @Override protected void onCreate(Bundle savedInstanceState) { requestAllPermissions(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化控件 Spinner spinner = findViewById(R.id.spinner1); // 建立数据源 String[] sentences = getResources().getStringArray(R.array.text); // 建立 Adapter 并且绑定数据源 ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, sentences); // 第一个参数表示在哪个 Activity 上显示,第二个参数是系统下拉框的样式,第三个参数是数组。 spinner.setAdapter(adapter);//绑定Adapter到控件 spinner.setOnItemSelectedListener(this); btn_play = findViewById(R.id.btn_play); btn_pause = findViewById(R.id.btn_pause); btn_stop = findViewById(R.id.btn_stop); btn_play.setOnClickListener(this); btn_pause.setOnClickListener(this); btn_stop.setOnClickListener(this); btn_play.setVisibility(View.INVISIBLE); btn_pause.setVisibility(View.INVISIBLE); btn_stop.setVisibility(View.INVISIBLE); // Clear all setting items to avoid app crashing due to the incorrect settings SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.clear(); editor.commit(); // Prepare the worker thread for mode loading and inference receiver = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case RESPONSE_LOAD_MODEL_SUCCESSED: pbLoadModel.dismiss(); onLoadModelSuccessed(); break; case RESPONSE_LOAD_MODEL_FAILED: pbLoadModel.dismiss(); Toast.makeText(MainActivity.this, "Load model failed!", Toast.LENGTH_SHORT).show(); onLoadModelFailed(); break; case RESPONSE_RUN_MODEL_SUCCESSED: pbRunModel.dismiss(); onRunModelSuccessed(); break; case RESPONSE_RUN_MODEL_FAILED: pbRunModel.dismiss(); Toast.makeText(MainActivity.this, "Run model failed!", Toast.LENGTH_SHORT).show(); onRunModelFailed(); break; default: break; } } }; worker = new HandlerThread("Predictor Worker"); worker.start(); sender = new Handler(worker.getLooper()) { public void handleMessage(Message msg) { switch (msg.what) { case REQUEST_LOAD_MODEL: // Load model and reload test image if (onLoadModel()) { receiver.sendEmptyMessage(RESPONSE_LOAD_MODEL_SUCCESSED); } else { receiver.sendEmptyMessage(RESPONSE_LOAD_MODEL_FAILED); } break; case REQUEST_RUN_MODEL: // Run model if model is loaded if (onRunModel()) { receiver.sendEmptyMessage(RESPONSE_RUN_MODEL_SUCCESSED); } else { receiver.sendEmptyMessage(RESPONSE_RUN_MODEL_FAILED); } break; default: break; } } }; // Setup the UI components tvInputSetting = findViewById(R.id.tv_input_setting); tvInferenceTime = findViewById(R.id.tv_inference_time); tvInputSetting.setMovementMethod(ScrollingMovementMethod.getInstance()); } @Override protected void onResume() { super.onResume(); boolean settingsChanged = false; SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); String model_path = sharedPreferences.getString(getString(R.string.MODEL_PATH_KEY), getString(R.string.MODEL_PATH_DEFAULT)); settingsChanged |= !model_path.equalsIgnoreCase(modelPath); int cpu_thread_num = Integer.parseInt(sharedPreferences.getString(getString(R.string.CPU_THREAD_NUM_KEY), getString(R.string.CPU_THREAD_NUM_DEFAULT))); settingsChanged |= cpu_thread_num != cpuThreadNum; String cpu_power_mode = sharedPreferences.getString(getString(R.string.CPU_POWER_MODE_KEY), getString(R.string.CPU_POWER_MODE_DEFAULT)); settingsChanged |= !cpu_power_mode.equalsIgnoreCase(cpuPowerMode); if (settingsChanged) { modelPath = model_path; cpuThreadNum = cpu_thread_num; cpuPowerMode = cpu_power_mode; // Update UI tvInputSetting.setText("Model: " + modelPath.substring(modelPath.lastIndexOf("/") + 1) + "\n" + "CPU" + " Thread Num: " + cpuThreadNum + "\n" + "CPU Power Mode: " + cpuPowerMode + "\n"); tvInputSetting.scrollTo(0, 0); // Reload model if configure has been changed loadModel(); } } public void loadModel() { pbLoadModel = ProgressDialog.show(this, "", "Loading model...", false, false); sender.sendEmptyMessage(REQUEST_LOAD_MODEL); } public void runModel() { pbRunModel = ProgressDialog.show(this, "", "Running model...", false, false); sender.sendEmptyMessage(REQUEST_RUN_MODEL); } public boolean onLoadModel() { return predictor.init(MainActivity.this, modelPath, AMmodelName, VOCmodelName, cpuThreadNum, cpuPowerMode); } public boolean onRunModel() { return predictor.isLoaded() && predictor.runModel(phones); } public boolean onLoadModelSuccessed() { // Load test image from path and run model // runModel(); return true; } public void onLoadModelFailed() { } public void onRunModelSuccessed() { // Obtain results and update UI btn_play.setVisibility(View.VISIBLE); btn_pause.setVisibility(View.VISIBLE); btn_stop.setVisibility(View.VISIBLE); tvInferenceTime.setText("Inference done!\nInference time: " + predictor.inferenceTime() + " ms" + "\nRTF: " + predictor.inferenceTime() * sampleRate / (predictor.wav.length * 1000) + "\nAudio saved in " + wavFile); try { Utils.rawToWave(wavFile, predictor.wav, sampleRate); } catch (IOException e) { e.printStackTrace(); } if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } else { // 初始化 MediaPlayer initMediaPlayer(); } } public void onRunModelFailed() { } public void onSettingsClicked() { startActivity(new Intent(MainActivity.this, SettingsActivity.class)); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_action_options, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); break; case R.id.settings: onSettingsClicked(); } return super.onOptionsItemSelected(item); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy() { if (predictor != null) { predictor.releaseModel(); } worker.quit(); super.onDestroy(); if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } } private boolean requestAllPermissions() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); return false; } return true; } @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { if (position > 0) { phones = sentencesToChoose[position - 1]; runModel(); } } @Override public void onNothingSelected(AdapterView parent) { } } ================================================ FILE: demos/TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/Predictor.java ================================================ package com.baidu.paddle.lite.demo.tts; import android.content.Context; import android.util.Log; import com.baidu.paddle.lite.MobileConfig; import com.baidu.paddle.lite.PaddlePredictor; import com.baidu.paddle.lite.PowerMode; import com.baidu.paddle.lite.Tensor; import java.io.File; import java.util.Date; public class Predictor { private static final String TAG = Predictor.class.getSimpleName(); public boolean isLoaded = false; public int cpuThreadNum = 1; public String cpuPowerMode = "LITE_POWER_HIGH"; public String modelPath = ""; protected PaddlePredictor AMPredictor = null; protected PaddlePredictor VOCPredictor = null; protected float inferenceTime = 0; protected float[] wav; public boolean init(Context appCtx, String modelPath, String AMmodelName, String VOCmodelName, int cpuThreadNum, String cpuPowerMode) { // Release model if exists releaseModel(); AMPredictor = loadModel(appCtx, modelPath, AMmodelName, cpuThreadNum, cpuPowerMode); if (AMPredictor == null) { return false; } VOCPredictor = loadModel(appCtx, modelPath, VOCmodelName, cpuThreadNum, cpuPowerMode); if (VOCPredictor == null) { return false; } isLoaded = true; return true; } protected PaddlePredictor loadModel(Context appCtx, String modelPath, String modelName, int cpuThreadNum, String cpuPowerMode) { // Load model if (modelPath.isEmpty()) { return null; } String realPath = modelPath; if (modelPath.charAt(0) != '/') { // Read model files from custom path if the first character of mode path is '/' // otherwise copy model to cache from assets realPath = appCtx.getCacheDir() + "/" + modelPath; // push model to mobile Utils.copyDirectoryFromAssets(appCtx, modelPath, realPath); } if (realPath.isEmpty()) { return null; } MobileConfig config = new MobileConfig(); config.setModelFromFile(realPath + File.separator + modelName); Log.e(TAG, "File:" + realPath + File.separator + modelName); config.setThreads(cpuThreadNum); if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_HIGH")) { config.setPowerMode(PowerMode.LITE_POWER_HIGH); } else if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_LOW")) { config.setPowerMode(PowerMode.LITE_POWER_LOW); } else if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_FULL")) { config.setPowerMode(PowerMode.LITE_POWER_FULL); } else if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_NO_BIND")) { config.setPowerMode(PowerMode.LITE_POWER_NO_BIND); } else if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_RAND_HIGH")) { config.setPowerMode(PowerMode.LITE_POWER_RAND_HIGH); } else if (cpuPowerMode.equalsIgnoreCase("LITE_POWER_RAND_LOW")) { config.setPowerMode(PowerMode.LITE_POWER_RAND_LOW); } else { Log.e(TAG, "Unknown cpu power mode!"); return null; } return PaddlePredictor.createPaddlePredictor(config); } public void releaseModel() { AMPredictor = null; VOCPredictor = null; isLoaded = false; cpuThreadNum = 1; cpuPowerMode = "LITE_POWER_HIGH"; modelPath = ""; } public boolean runModel(float[] phones) { if (!isLoaded()) { return false; } Date start = new Date(); Tensor am_output_handle = getAMOutput(phones, AMPredictor); wav = getVOCOutput(am_output_handle, VOCPredictor); Date end = new Date(); inferenceTime = (end.getTime() - start.getTime()); return true; } public Tensor getAMOutput(float[] phones, PaddlePredictor am_predictor) { Tensor phones_handle = am_predictor.getInput(0); long[] dims = {phones.length}; phones_handle.resize(dims); phones_handle.setData(phones); am_predictor.run(); Tensor am_output_handle = am_predictor.getOutput(0); // [?, 80] // long outputShape[] = am_output_handle.shape(); float[] am_output_data = am_output_handle.getFloatData(); // [? x 80] // long[] am_output_data_shape = {am_output_data.length}; // Log.e(TAG, Arrays.toString(am_output_data)); // 打印 mel 数组 // for (int i=0;i preInstalledModelPaths = null; List preInstalledCPUThreadNums = null; List preInstalledCPUPowerModes = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); ActionBar supportActionBar = getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setDisplayHomeAsUpEnabled(true); } // Initialized pre-installed models preInstalledModelPaths = new ArrayList(); preInstalledCPUThreadNums = new ArrayList(); preInstalledCPUPowerModes = new ArrayList(); preInstalledModelPaths.add(getString(R.string.MODEL_PATH_DEFAULT)); preInstalledCPUThreadNums.add(getString(R.string.CPU_THREAD_NUM_DEFAULT)); preInstalledCPUPowerModes.add(getString(R.string.CPU_POWER_MODE_DEFAULT)); // Setup UI components lpChoosePreInstalledModel = (ListPreference) findPreference(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY)); String[] preInstalledModelNames = new String[preInstalledModelPaths.size()]; for (int i = 0; i < preInstalledModelPaths.size(); i++) { preInstalledModelNames[i] = preInstalledModelPaths.get(i).substring(preInstalledModelPaths.get(i).lastIndexOf("/") + 1); } lpChoosePreInstalledModel.setEntries(preInstalledModelNames); lpChoosePreInstalledModel.setEntryValues(preInstalledModelPaths.toArray(new String[preInstalledModelPaths.size()])); lpCPUThreadNum = (ListPreference) findPreference(getString(R.string.CPU_THREAD_NUM_KEY)); lpCPUPowerMode = (ListPreference) findPreference(getString(R.string.CPU_POWER_MODE_KEY)); cbEnableCustomSettings = (CheckBoxPreference) findPreference(getString(R.string.ENABLE_CUSTOM_SETTINGS_KEY)); etModelPath = (EditTextPreference) findPreference(getString(R.string.MODEL_PATH_KEY)); etModelPath.setTitle("Model Path (SDCard: " + Utils.getSDCardDirectory() + ")"); } private void reloadPreferenceAndUpdateUI() { SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); boolean enableCustomSettings = sharedPreferences.getBoolean(getString(R.string.ENABLE_CUSTOM_SETTINGS_KEY), false); String modelPath = sharedPreferences.getString(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY), getString(R.string.MODEL_PATH_DEFAULT)); int modelIdx = lpChoosePreInstalledModel.findIndexOfValue(modelPath); if (modelIdx >= 0 && modelIdx < preInstalledModelPaths.size()) { if (!enableCustomSettings) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(getString(R.string.MODEL_PATH_KEY), preInstalledModelPaths.get(modelIdx)); editor.putString(getString(R.string.CPU_THREAD_NUM_KEY), preInstalledCPUThreadNums.get(modelIdx)); editor.putString(getString(R.string.CPU_POWER_MODE_KEY), preInstalledCPUPowerModes.get(modelIdx)); editor.commit(); } lpChoosePreInstalledModel.setSummary(modelPath); } cbEnableCustomSettings.setChecked(enableCustomSettings); etModelPath.setEnabled(enableCustomSettings); lpCPUThreadNum.setEnabled(enableCustomSettings); lpCPUPowerMode.setEnabled(enableCustomSettings); modelPath = sharedPreferences.getString(getString(R.string.MODEL_PATH_KEY), getString(R.string.MODEL_PATH_DEFAULT)); String cpuThreadNum = sharedPreferences.getString(getString(R.string.CPU_THREAD_NUM_KEY), getString(R.string.CPU_THREAD_NUM_DEFAULT)); String cpuPowerMode = sharedPreferences.getString(getString(R.string.CPU_POWER_MODE_KEY), getString(R.string.CPU_POWER_MODE_DEFAULT)); etModelPath.setSummary(modelPath); etModelPath.setText(modelPath); lpCPUThreadNum.setValue(cpuThreadNum); lpCPUThreadNum.setSummary(cpuThreadNum); lpCPUPowerMode.setValue(cpuPowerMode); lpCPUPowerMode.setSummary(cpuPowerMode); } @Override protected void onResume() { super.onResume(); getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); reloadPreferenceAndUpdateUI(); } @Override protected void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY))) { SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(getString(R.string.ENABLE_CUSTOM_SETTINGS_KEY), false); editor.commit(); } reloadPreferenceAndUpdateUI(); } } ================================================ FILE: demos/TTSAndroid/app/src/main/java/com/baidu/paddle/lite/demo/tts/Utils.java ================================================ package com.baidu.paddle.lite.demo.tts; import static java.lang.Math.abs; import android.content.Context; import android.os.Environment; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Utils { public static void copyFileFromAssets(Context appCtx, String srcPath, String dstPath) { if (srcPath.isEmpty() || dstPath.isEmpty()) { return; } InputStream is = null; OutputStream os = null; try { is = new BufferedInputStream(appCtx.getAssets().open(srcPath)); os = new BufferedOutputStream(new FileOutputStream(new File(dstPath))); byte[] buffer = new byte[1024]; int length = 0; while ((length = is.read(buffer)) != -1) { os.write(buffer, 0, length); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { os.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void copyDirectoryFromAssets(Context appCtx, String srcDir, String dstDir) { if (srcDir.isEmpty() || dstDir.isEmpty()) { return; } try { if (!new File(dstDir).exists()) { new File(dstDir).mkdirs(); } for (String fileName : appCtx.getAssets().list(srcDir)) { String srcSubPath = srcDir + File.separator + fileName; String dstSubPath = dstDir + File.separator + fileName; if (new File(srcSubPath).isDirectory()) { copyDirectoryFromAssets(appCtx, srcSubPath, dstSubPath); } else { copyFileFromAssets(appCtx, srcSubPath, dstSubPath); } } } catch (Exception e) { e.printStackTrace(); } } public static String getSDCardDirectory() { return Environment.getExternalStorageDirectory().getAbsolutePath(); } public static void rawToWave(String file, float[] data, int samplerate) throws IOException { // creating the empty wav file. File waveFile = new File(file); waveFile.createNewFile(); //following block is converting raw to wav. DataOutputStream output = null; try { output = new DataOutputStream(new FileOutputStream(waveFile)); // WAVE header // chunk id writeString(output, "RIFF"); // chunk size writeInt(output, 36 + data.length * 2); // format writeString(output, "WAVE"); // subchunk 1 id writeString(output, "fmt "); // subchunk 1 size writeInt(output, 16); // audio format (1 = PCM) writeShort(output, (short) 1); // number of channels writeShort(output, (short) 1); // sample rate writeInt(output, samplerate); // byte rate writeInt(output, samplerate * 2); // block align writeShort(output, (short) 2); // bits per sample writeShort(output, (short) 16); // subchunk 2 id writeString(output, "data"); // subchunk 2 size writeInt(output, data.length * 2); short[] short_data = FloatArray2ShortArray(data); for (int i = 0; i < short_data.length; i++) { writeShort(output, short_data[i]); } } finally { if (output != null) { output.close(); } } } private static void writeInt(final DataOutputStream output, final int value) throws IOException { output.write(value); output.write(value >> 8); output.write(value >> 16); output.write(value >> 24); } private static void writeShort(final DataOutputStream output, final short value) throws IOException { output.write(value); output.write(value >> 8); } private static void writeString(final DataOutputStream output, final String value) throws IOException { for (int i = 0; i < value.length(); i++) { output.write(value.charAt(i)); } } public static short[] FloatArray2ShortArray(float[] values) { float mmax = (float) 0.01; short[] ret = new short[values.length]; for (int i = 0; i < values.length; i++) { if (abs(values[i]) > mmax) { mmax = abs(values[i]); } } for (int i = 0; i < values.length; i++) { values[i] = values[i] * (32767 / mmax); ret[i] = (short) (values[i]); } return ret; } } ================================================ FILE: demos/TTSAndroid/app/src/main/res/drawable/button_drawable.xml ================================================ ================================================ FILE: demos/TTSAndroid/app/src/main/res/layout/activity_main.xml ================================================