├── .gitattributes ├── .gitignore ├── DF ├── Baseline-CQCC-GMM │ ├── matlab │ │ ├── CQCC │ │ ├── CQCC_GMM_ASVspoof_2021_baseline.m │ │ ├── GMM │ │ ├── LICENSE │ │ └── README.md │ └── python │ │ ├── CQCC │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-GMM │ ├── matlab │ │ ├── GMM │ │ ├── LFCC │ │ ├── LFCC_GMM_ASVspoof_2021_baseline.m │ │ └── README.md │ └── python │ │ ├── LFCC_pipeline.py │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-LCNN │ ├── LICENSE │ ├── README.md │ ├── core_modules │ ├── core_scripts │ ├── env.sh │ ├── env.yml │ ├── project │ │ ├── 00_download.sh │ │ ├── 01_wrapper_eval.sh │ │ ├── 02_toy_example.sh │ │ ├── 99_del.sh │ │ ├── DATA │ │ │ └── .gitkeep │ │ ├── README │ │ ├── baseline_DF │ │ │ ├── 00_train.sh │ │ │ ├── 01_eval.sh │ │ │ ├── 02_eval_alternative.sh │ │ │ ├── __pretrained │ │ │ │ └── .gitkeep │ │ │ ├── config.py │ │ │ ├── config_auto.py │ │ │ ├── main.py │ │ │ └── model.py │ │ └── conda.sh │ └── sandbox └── Baseline-RawNet2 │ ├── LICENSE │ ├── README.md │ ├── core_scripts │ ├── data_utils.py │ ├── main.py │ ├── model.py │ ├── model_config_RawNet.yaml │ └── requirements.txt ├── LA ├── Baseline-CQCC-GMM │ ├── matlab │ │ ├── CQCC │ │ │ ├── .DS_Store │ │ │ ├── CQT_toolbox_2013 │ │ │ │ ├── cqt.m │ │ │ │ ├── cqtCell2Sparse.m │ │ │ │ ├── cqtFillSparse.m │ │ │ │ ├── cqtSparse2Cell.m │ │ │ │ ├── hp.m │ │ │ │ ├── icqt.m │ │ │ │ ├── nsdual.m │ │ │ │ ├── nsgcqwin.m │ │ │ │ ├── nsgtf_real.m │ │ │ │ ├── nsigtf_real.m │ │ │ │ ├── plotnsgtf.m │ │ │ │ └── winfuns.m │ │ │ ├── D18_1000001.wav │ │ │ ├── DEMO.m │ │ │ ├── README.txt │ │ │ └── cqcc.m │ │ ├── CQCC_GMM_ASVspoof_2021_baseline.m │ │ ├── GMM │ │ │ ├── .DS_Store │ │ │ ├── compute_llk.m │ │ │ ├── lgmmprob.m │ │ │ ├── logsumexp.m │ │ │ └── vlfeat │ │ │ │ ├── mexa64 │ │ │ │ ├── libvl.so │ │ │ │ └── vl_gmm.mexa64 │ │ │ │ ├── mexglx │ │ │ │ ├── libvl.so │ │ │ │ └── vl_gmm.mexglx │ │ │ │ ├── mexmaci │ │ │ │ ├── libvl.dylib │ │ │ │ └── vl_gmm.mexmaci │ │ │ │ ├── mexmaci64 │ │ │ │ ├── libvl.dylib │ │ │ │ └── vl_gmm.mexmaci64 │ │ │ │ ├── mexw32 │ │ │ │ ├── msvcr100.dll │ │ │ │ ├── vl.dll │ │ │ │ └── vl_gmm.mexw32 │ │ │ │ └── mexw64 │ │ │ │ ├── msvcr100.dll │ │ │ │ ├── vl.dll │ │ │ │ ├── vl_aib.mexw64 │ │ │ │ ├── vl_aibhist.mexw64 │ │ │ │ ├── vl_alldist.mexw64 │ │ │ │ ├── vl_alldist2.mexw64 │ │ │ │ ├── vl_binsearch.mexw64 │ │ │ │ ├── vl_binsum.mexw64 │ │ │ │ ├── vl_covdet.mexw64 │ │ │ │ ├── vl_cummax.mexw64 │ │ │ │ ├── vl_dsift.mexw64 │ │ │ │ ├── vl_erfill.mexw64 │ │ │ │ ├── vl_fisher.mexw64 │ │ │ │ ├── vl_getpid.mexw64 │ │ │ │ ├── vl_gmm.mexw64 │ │ │ │ ├── vl_hikmeans.mexw64 │ │ │ │ ├── vl_hikmeanspush.mexw64 │ │ │ │ ├── vl_hog.mexw64 │ │ │ │ ├── vl_homkermap.mexw64 │ │ │ │ ├── vl_ihashfind.mexw64 │ │ │ │ ├── vl_ihashsum.mexw64 │ │ │ │ ├── vl_ikmeans.mexw64 │ │ │ │ ├── vl_ikmeanspush.mexw64 │ │ │ │ ├── vl_imdisttf.mexw64 │ │ │ │ ├── vl_imintegral.mexw64 │ │ │ │ ├── vl_imsmooth.mexw64 │ │ │ │ ├── vl_imwbackwardmx.mexw64 │ │ │ │ ├── vl_inthist.mexw64 │ │ │ │ ├── vl_irodr.mexw64 │ │ │ │ ├── vl_kdtreebuild.mexw64 │ │ │ │ ├── vl_kdtreequery.mexw64 │ │ │ │ ├── vl_kmeans.mexw64 │ │ │ │ ├── vl_lbp.mexw64 │ │ │ │ ├── vl_liop.mexw64 │ │ │ │ ├── vl_localmax.mexw64 │ │ │ │ ├── vl_mser.mexw64 │ │ │ │ ├── vl_quickshift.mexw64 │ │ │ │ ├── vl_rodr.mexw64 │ │ │ │ ├── vl_sampleinthist.mexw64 │ │ │ │ ├── vl_sift.mexw64 │ │ │ │ ├── vl_siftdescriptor.mexw64 │ │ │ │ ├── vl_simdctrl.mexw64 │ │ │ │ ├── vl_slic.mexw64 │ │ │ │ ├── vl_svmtrain.mexw64 │ │ │ │ ├── vl_threads.mexw64 │ │ │ │ ├── vl_tpsumx.mexw64 │ │ │ │ ├── vl_twister.mexw64 │ │ │ │ ├── vl_ubcmatch.mexw64 │ │ │ │ ├── vl_version.mexw64 │ │ │ │ └── vl_vlad.mexw64 │ │ ├── LICENSE │ │ └── README.md │ └── python │ │ ├── CQCC │ │ ├── CQT_toolbox_2013 │ │ │ ├── __init__.py │ │ │ ├── cqt.py │ │ │ ├── cqtCell2Sparse.py │ │ │ ├── cqtFillSparse.py │ │ │ ├── cqtSparse2Cell.py │ │ │ ├── hp.py │ │ │ ├── icqt.py │ │ │ ├── nsdual.py │ │ │ ├── nsgcqwin.py │ │ │ ├── nsgtf_real.py │ │ │ ├── nsigtf_real.py │ │ │ └── winfuns.py │ │ ├── README.txt │ │ ├── __init__.py │ │ ├── cqcc.py │ │ ├── cqcc_ori.py │ │ └── demo.py │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-GMM │ ├── matlab │ │ ├── GMM │ │ ├── LFCC │ │ │ ├── .DS_Store │ │ │ └── lfcc_bp.m │ │ ├── LFCC_GMM_ASVspoof_2021_baseline.m │ │ ├── LICENSE │ │ └── README.md │ └── python │ │ ├── LFCC_pipeline.py │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-LCNN │ ├── LICENSE │ ├── README.md │ ├── core_modules │ │ ├── a_softmax.py │ │ ├── am_softmax.py │ │ ├── grad_rev.py │ │ ├── oc_softmax.py │ │ └── p2sgrad.py │ ├── core_scripts │ │ ├── __init__.py │ │ ├── config_parse │ │ │ ├── __init__.py │ │ │ ├── arg_parse.py │ │ │ └── config_parse.py │ │ ├── data_io │ │ │ ├── __init__.py │ │ │ ├── conf.py │ │ │ ├── customize_collate_fn.py │ │ │ ├── customize_dataset.py │ │ │ ├── customize_sampler.py │ │ │ ├── default_data_io.py │ │ │ ├── io_tools.py │ │ │ ├── seq_info.py │ │ │ ├── text_process │ │ │ │ ├── text_io.py │ │ │ │ ├── tmp.txt │ │ │ │ ├── toolkit_all.py │ │ │ │ └── toolkit_en.py │ │ │ └── wav_tools.py │ │ ├── math_tools │ │ │ ├── __init__.py │ │ │ ├── random_tools.py │ │ │ └── stats.py │ │ ├── nn_manager │ │ │ ├── nn_manager.py │ │ │ ├── nn_manager_GAN.py │ │ │ ├── nn_manager_conf.py │ │ │ └── nn_manager_tools.py │ │ ├── op_manager │ │ │ ├── conf.py │ │ │ ├── lr_scheduler.py │ │ │ ├── op_display_tools.py │ │ │ ├── op_manager.py │ │ │ └── op_process_monitor.py │ │ ├── other_tools │ │ │ ├── __init__.py │ │ │ ├── data_warehouse.py │ │ │ ├── debug.py │ │ │ ├── display.py │ │ │ ├── list_tools.py │ │ │ ├── log_parser.py │ │ │ ├── random_name_mgn.py │ │ │ ├── script_model_para.py │ │ │ └── str_tools.py │ │ └── startup_config.py │ ├── env.sh │ ├── env.yml │ ├── project │ │ ├── 00_download.sh │ │ ├── 01_wrapper_eval.sh │ │ ├── 02_toy_example.sh │ │ ├── 99_del.sh │ │ ├── DATA │ │ │ └── .gitkeep │ │ ├── README │ │ ├── baseline_LA │ │ │ ├── 00_train.sh │ │ │ ├── 01_eval.sh │ │ │ ├── 02_eval_alternative.sh │ │ │ ├── __pretrained │ │ │ │ └── .gitkeep │ │ │ ├── config.py │ │ │ ├── config_auto.py │ │ │ ├── main.py │ │ │ └── model.py │ │ └── conda.sh │ └── sandbox │ │ ├── __init__.py │ │ ├── block_dist.py │ │ ├── block_nn.py │ │ ├── block_nsf.py │ │ ├── block_resnet.py │ │ ├── dist.py │ │ ├── dynamic_prog.py │ │ ├── eval_asvspoof.py │ │ ├── eval_music.py │ │ ├── util_dsp.py │ │ ├── util_frontend.py │ │ └── util_music.py └── Baseline-RawNet2 │ ├── LICENSE │ ├── README.md │ ├── core_scripts │ ├── data_utils.py │ ├── main.py │ ├── model.py │ ├── model_config_RawNet.yaml │ └── requirements.txt ├── PA ├── Baseline-CQCC-GMM │ ├── matlab │ │ ├── CQCC │ │ ├── CQCC_GMM_ASVspoof_2021_baseline.m │ │ ├── GMM │ │ ├── LICENSE │ │ └── README.md │ └── python │ │ ├── CQCC │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-GMM │ ├── matlab │ │ ├── GMM │ │ ├── LFCC │ │ ├── LFCC_GMM_ASVspoof_2021_baseline.m │ │ ├── LICENSE │ │ └── README.md │ └── python │ │ ├── LFCC_pipeline.py │ │ ├── README.md │ │ ├── asvspoof2021_baseline.py │ │ ├── gmm.py │ │ └── gmm_scoring_asvspoof21.py ├── Baseline-LFCC-LCNN │ ├── LICENSE │ ├── README.md │ ├── core_modules │ ├── core_scripts │ ├── env.sh │ ├── env.yml │ ├── project │ │ ├── 00_download.sh │ │ ├── 01_wrapper_eval.sh │ │ ├── 02_toy_example.sh │ │ ├── 99_del.sh │ │ ├── DATA │ │ │ └── .gitkeep │ │ ├── README │ │ ├── baseline_PA │ │ │ ├── 00_train.sh │ │ │ ├── 01_eval.sh │ │ │ ├── 02_eval_alternative.sh │ │ │ ├── __pretrained │ │ │ │ └── .gitkeep │ │ │ ├── config.py │ │ │ ├── config_auto.py │ │ │ ├── main.py │ │ │ └── model.py │ │ └── conda.sh │ └── sandbox └── Baseline-RawNet2 │ ├── LICENSE │ ├── README.md │ ├── core_scripts │ ├── data_utils.py │ ├── main.py │ ├── model.py │ ├── model_config_RawNet.yaml │ └── requirements.txt ├── README.md └── eval-package ├── ASVspoof2021_eval_notebook.ipynb ├── README.md ├── archived-package-stage-1 ├── DF │ └── package-stage-1 │ │ ├── README.txt │ │ ├── download.sh │ │ ├── eval_metrics.py │ │ └── evaluate.py ├── LA │ └── package-stage-1 │ │ ├── README.txt │ │ ├── download.sh │ │ ├── eval_metrics.py │ │ └── evaluate.py └── PA │ └── package-stage-1 │ ├── README.txt │ ├── download.sh │ ├── eval_metrics.py │ └── evaluate.py ├── config.py ├── download.sh ├── eval_metrics.py ├── eval_wrapper.py ├── main.py ├── pd_tools.py └── table_API.py /.gitattributes: -------------------------------------------------------------------------------- 1 | *metadata* filter=lfs diff=lfs merge=lfs -text 2 | *score* filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/matlab/CQCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/CQCC -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/matlab/GMM: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/GMM -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/matlab/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/LICENSE -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # CQCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-end: 9 | - high-time resolution constant Q cepstral coefficients (CQCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### CQCC 16 | Matlab implementation of constant Q cepstral coefficients. 17 | 18 | For further details on CQCC, refer to the following publication: 19 | 20 | - M. Todisco, H. Delgado and N. Evans, "Constant Q cepstral coefficients: a spoofing countermeasure for automatic speaker verification", Computer, Speech and Language, vol. 45, pp. 516 –535, 2017. 21 | 22 | - M. Todisco, H. Delgado, N. Evans, "A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients," in Proc. ODYSSEY 2016, The Speaker and Language Recognition Workshop, 2016. 23 | 24 | ### GMM 25 | VLFeat open source library that implements the GMMs. 26 | 27 | For further details, refer to: 28 | http://www.vlfeat.org/ 29 | 30 | ### CQCC_GMM_ASVspoof_2021_baseline.m 31 | This script implements the CQCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Deep Fake (DF) task. 32 | Front-ends include high-time resolution CQCC features, while back-end is based on GMMs. 33 | CQCC features use 12 bins per octave. Re-sampling is applied with a sampling period of 16 and the features dimension is set to 19 coefficients + 0th, with the static, delta and delta-delta coefficients. CQCC is applied with a maximum frequency of 4 kHz. 34 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 35 | 36 | Results are shown in the ASVspoof 2021 Evaluation Plan. 37 | 38 | ## Contact information 39 | For any query, please contact organisers at lists.asvspoof.org 40 | 41 | -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/python/CQCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/CQCC -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/README.md -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/asvspoof2021_baseline.py -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/python/gmm.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/gmm.py -------------------------------------------------------------------------------- /DF/Baseline-CQCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-cqcc-asvspoof21-DF.txt' 6 | 7 | # configs 8 | features = 'cqcc' 9 | dict_file = 'gmm_cqcc_asvspoof21_la.pkl' # uses LA GMM in DF 10 | 11 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 12 | eval_folder = db_folder + 'LA/ASVspoof2021_DF_eval/flac/' 13 | eval_ndx = db_folder + 'LA/ASVspoof2021_DF_cm_protocols/ASVspoof2021.DF.cm.eval.trl.txt' 14 | 15 | audio_ext = '.flac' 16 | 17 | # run on ASVspoof 2021 evaluation set 18 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 19 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 20 | features_cached=True) 21 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/matlab/GMM: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/GMM -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/matlab/LFCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/matlab/LFCC -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # LFCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-ends: 9 | - high-frequency resolution linear frequency cepstral coefficients (LFCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### LFCC 16 | Matlab implementation of linear frequency cepstral coefficients. 17 | 18 | For further details on LFCC for antispoofing, refer to the following publication: 19 | 20 | - H. Tak, J. Patino, A. Nautsch, N. Evans, M. Todisco, "Spoofing Attack Detection using the Non-linear Fusion of Sub-band Classifiers" in Proc INTERSPEECH, 2020. 21 | - M. Sahidullah, T. Kinnunen, C. Hanilçi, "A Comparison of Features for Synthetic Speech Detection," in Proc INTERSPEECH, 2015. 22 | 23 | ### GMM 24 | VLFeat open source library that implements the GMMs. 25 | 26 | For further details, refer to: 27 | http://www.vlfeat.org/ 28 | 29 | ### LFCC_GMM_ASVspoof_2021_baseline.m 30 | This script implements the LFCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Deep Fake (DF) task. 31 | Front-ends include high-frequency resolution LFCC features, while back-end is based on GMMs. 32 | LFCC features use a 30 ms window with a 15 ms shift, 1024-point Fourier transform, 70-channel linear filterbank, from which 19 coefficients + 0th, with the static, delta and delta-delta coefficients. LFCC is applied with a maximum frequency of 4 kHz. 33 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 34 | 35 | Results are shown in the ASVspoof 2021 Evaluation Plan. 36 | 37 | ## Contact information 38 | For any query, please contact organisers at lists.asvspoof.org 39 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/python/LFCC_pipeline.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/LFCC_pipeline.py -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/README.md -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/asvspoof2021_baseline.py -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/python/gmm.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/gmm.py -------------------------------------------------------------------------------- /DF/Baseline-LFCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-lfcc-asvspoof21-DF.txt' 6 | 7 | # configs 8 | features = 'lfcc' 9 | dict_file = 'gmm_asvspoof21_la.pkl' # uses LA GMM in DF 10 | 11 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 12 | eval_folder = db_folder + 'DF/ASVspoof2021_DF_eval/flac/' 13 | eval_ndx = db_folder + 'DF/ASVspoof2021_DF_cm_protocols/ASVspoof2021.DF.cm.eval.trl.txt' 14 | 15 | audio_ext = '.flac' 16 | 17 | # run on ASVspoof 2021 evaluation set 18 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 19 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 20 | features_cached=True) 21 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/LICENSE -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/README.md: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/README.md -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/core_modules: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/core_modules -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/core_scripts: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/core_scripts -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/env.sh: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/env.sh -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/env.yml: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/env.yml -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/00_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download toy data package and pre-trained models 4 | echo "=== Downloading toy dataset ===" 5 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABc-QK2BvzEPj-s8nBwCkMna/temp/asvspoof2021/toy_example.tar.gz 6 | cd DATA 7 | wget -q ${SRC} 8 | cd .. 9 | 10 | echo "=== Downloading pre-trained models ===" 11 | if [ -d baseline_DF ]; 12 | then 13 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_DF_LFCC-LCNN.zip 14 | wget -q ${SRC} 15 | if [ -f pre_trained_DF_LFCC-LCNN.zip ]; 16 | then 17 | unzip pre_trained_DF_LFCC-LCNN.zip 18 | #mv pre_trained_DF_LFCC-LCNN.pt df_trained_network.pt 19 | rm pre_trained_DF_LFCC-LCNN.zip 20 | fi 21 | 22 | if [ ! -f df_trained_network.pt ]; 23 | then 24 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABg4OUDKFvFonI-HmIzT5qIa/temp/asvspoof2021/df_trained_network.pt 25 | wget -q ${SRC} 26 | fi 27 | mv df_trained_network.pt baseline_DF/__pretrained/trained_network.pt 28 | fi 29 | 30 | if [ -d baseline_LA ]; 31 | then 32 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_LA_LFCC-LCNN.zip 33 | wget -q ${SRC} 34 | if [ -f pre_trained_LA_LFCC-LCNN.zip ]; 35 | then 36 | unzip pre_trained_LA_LFCC-LCNN.zip 37 | #mv pre_trained_LA_LFCC-LCNN.pt la_trained_network.pt 38 | rm pre_trained_LA_LFCC-LCNN.zip 39 | fi 40 | 41 | if [ ! -f la_trained_network.pt ]; 42 | then 43 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AADWOs9cmLBzWuRPbh5m10YVa/temp/asvspoof2021/la_trained_network.pt 44 | wget -q ${SRC} 45 | fi 46 | mv la_trained_network.pt baseline_LA/__pretrained/trained_network.pt 47 | fi 48 | 49 | if [ -d baseline_PA ]; 50 | then 51 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_PA_LFCC-LCNN.zip 52 | wget -q ${SRC} 53 | if [ -f pre_trained_PA_LFCC-LCNN.zip ]; 54 | then 55 | unzip pre_trained_PA_LFCC-LCNN.zip 56 | #mv pre_trained_PA_LFCC-LCNN.pt pa_trained_network.pt 57 | rm pre_trained_PA_LFCC-LCNN.zip 58 | fi 59 | 60 | if [ ! -f pa_trained_network.pt ]; 61 | then 62 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AACOBr0ymqsMA0rKctMxkKaxa/temp/asvspoof2021/pa_trained_network.pt 63 | wget -q ${SRC} 64 | fi 65 | mv pa_trained_network.pt baseline_PA/__pretrained/trained_network.pt 66 | fi 67 | 68 | echo "Download done" 69 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/01_wrapper_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script to quickly evaluate a evaluation set 4 | # 5 | # 00_toy_example.sh requires configuration of config.py, 6 | # which further requires preparation of test.lst 7 | # and protocol.txt. 8 | # 9 | # It is convenient when doing numerious experiments 10 | # on the same data set but troublesome when evaluating 11 | # different evaluationg sets. 12 | # 13 | # This script shows one example of quick evaluation using 14 | # lfcc-lcnn-lstm-sig_toy_example/02_eval_alternative.sh 15 | # 16 | # It will use DATA/toy_example/eval 17 | # It will call the evaluat set toy_eval 18 | # It will use __pretrained/trained_network.pt as pre-trained model 19 | # 20 | # (See Doc of 02_eval_alternative.sh for more details) 21 | # 22 | # Note that we don't need a protocol or meta labels. 23 | # 24 | ######################## 25 | 26 | # Load python environment 27 | bash conda.sh 28 | 29 | # We will use DATA/toy_example/eval as example 30 | cd DATA 31 | tar -xzf toy_example.tar.gz 32 | cd .. 33 | 34 | # Go to the folder 35 | cd baseline_DF 36 | 37 | # Run evaluation using pretrained model 38 | # bash 02_eval_alternative.sh PATH_TO_WAV_DIR NAME_OF_DATA_SET TRAINED_MODEL 39 | # For details, please check 02_eval_alternative.sh 40 | bash 02_eval_alternative.sh $PWD/../DATA/toy_example/eval toy_eval __pretrained/trained_network.pt 41 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/02_toy_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for toy_example 4 | # This script will 5 | # 1. install pytorch env using conda 6 | # 2. untar toy data set 7 | # 3. run evaluation and training process 8 | # 9 | # If GPU memory is less than 16GB, please reduce 10 | # --batch-size in 00_train.sh 11 | ######################## 12 | RED='\033[0;32m' 13 | NC='\033[0m' 14 | 15 | echo -e "\n${RED}=======================================================${NC}" 16 | echo -e "${RED}Step1. install conda environment${NC}" 17 | 18 | # create conda environment 19 | bash conda.sh 20 | 21 | # untar the toy-example data 22 | echo -e "\n${RED}=======================================================${NC}" 23 | echo -e "${RED}Step2. untar toy data set${NC}" 24 | 25 | cd DATA 26 | tar -xzf toy_example.tar.gz 27 | cd .. 28 | 29 | echo -e "\n${RED}=======================================================${NC}" 30 | echo -e "${RED}Step3. run evaluation process (using pre-trained model)${NC}" 31 | # run scripts 32 | 33 | cd baseline_DF 34 | # evaluation using pre-trained model 35 | bash 01_eval.sh 36 | 37 | echo -e "\n${RED}=======================================================${NC}" 38 | echo -e "${RED}Step4. run training process (start with pre-trained model)${NC}" 39 | #training, with pre-trained model as initialization 40 | bash 00_train.sh 41 | 42 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/99_del.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -r DATA/* 3 | rm baseline_*/__pretrained/* 4 | rm baseline_*/log* 5 | rm -r baseline_*/__pycache__ 6 | rm baseline_*/epoch* 7 | rm baseline_*/asv* 8 | rm baseline_*/*.pt 9 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/DATA/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/DF/Baseline-LFCC-LCNN/project/DATA/.gitkeep -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/baseline_DF/00_train.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. $: bash 00_train.sh > /dev/null 2>&1 & 7 | # 3. please check log_train and log_err to monitor the training 8 | # process 9 | # 10 | # Note: 11 | # 1. The script by default uses the pre-trained model from ASVspoof2019 12 | # If you don't want to use it, just delete the option --trained-model 13 | # 2. For options, check $: python main.py --help 14 | ######################## 15 | 16 | log_train_name=log_train 17 | log_err_name=log_err 18 | pretrained_model=__pretrained/trained_network.pt 19 | 20 | echo -e "Training" 21 | echo -e "Please monitor the log trainig: $PWD/${log_train_name}.txt\n" 22 | source $PWD/../../env.sh 23 | python main.py --model-forward-with-file-name \ 24 | --num-workers 3 --epochs 100 \ 25 | --no-best-epochs 50 --batch-size 64 \ 26 | --sampler block_shuffle_by_length \ 27 | --lr-decay-factor 0.5 --lr-scheduler-type 1 \ 28 | --trained-model ${pretrained_model} \ 29 | --ignore-training-history-in-trained-model \ 30 | --lr 0.0003 --seed 1000 > ${log_train_name}.txt 2>${log_err_name}.txt 31 | echo -e "Training process finished" 32 | echo -e "Trainig log has been written to $PWD/${log_train_name}.txt" 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/baseline_DF/01_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. please specify the trained model 7 | # here, we use a pre-trained model from ASVspoof2019 8 | # 2. $: bash 01_eval.sh 9 | ######################## 10 | 11 | log_name=log_eval 12 | trained_model=__pretrained/trained_network.pt 13 | 14 | echo -e "Run evaluation" 15 | source $PWD/../../env.sh 16 | python main.py --inference --model-forward-with-file-name \ 17 | --trained-model ${trained_model}> ${log_name}.txt 2>${log_name}_err.txt 18 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 19 | echo -e "Process log has been written to $PWD/${log_name}.txt" 20 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 21 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/baseline_DF/02_eval_alternative.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for quick evaluation 4 | # 01_eval.sh requires configuration of config.py, 5 | # which further requires preparation of test.lst 6 | # and protocol.txt. 7 | # 8 | # It is convenient when doing numerious experiments 9 | # on the same data set but troublesome when evaluating 10 | # different evaluationg sets. 11 | # 12 | # This script assumes one model has been trained, 13 | # and it just needs the directory to the waveforms of 14 | # the evaluation set. It will automatically produce 15 | # the test.lst and config config_auto.py 16 | # 17 | # Usage: 18 | # bash 02_eval_alternative.sh 19 | # : abosolute path to the directory of eval set waveforms 20 | # : name of the evaluation set, any arbitary string 21 | # : path to the trained model file 22 | ######################## 23 | 24 | if [ "$#" -ne 3 ]; then 25 | echo -e "Invalid input arguments. Please check doc of the script, and use:" 26 | echo -e "bash 02_eval_alternative.sh " 27 | exit 28 | fi 29 | 30 | # path to the directory of waveforms 31 | eval_wav_dir=$1 32 | # name of the evaluation set (any string) 33 | eval_set_name=$2 34 | # path to the trained model 35 | trained_model=$3 36 | 37 | echo -e "Run evaluation" 38 | 39 | # step1. load python environment 40 | source $PWD/../../env.sh 41 | 42 | # step2. prepare test.lst 43 | ls ${eval_wav_dir} | xargs -I{} basename {} .wav | xargs -I{} basename {} .flac > ${eval_set_name}.lst 44 | 45 | # step3. export for config_auto.py 46 | export TEMP_DATA_NAME=${eval_set_name} 47 | export TEMP_DATA_DIR=${eval_wav_dir} 48 | 49 | # step4. run evaluation 50 | log_name=log_eval_${eval_set_name} 51 | python main.py \ 52 | --inference \ 53 | --model-forward-with-file-name \ 54 | --trained-model ${trained_model} \ 55 | --module-config config_auto > ${log_name}.txt 2>&1 56 | 57 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 58 | 59 | echo -e "Process log has been written to $PWD/${log_name}.txt" 60 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 61 | 62 | # step5. delete intermediate files 63 | # this script is created in step2 64 | rm ${eval_set_name}.lst 65 | # this is created by the python code (for convenience) 66 | rm ${eval_set_name}_utt_length.dic 67 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/baseline_DF/__pretrained/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/DF/Baseline-LFCC-LCNN/project/baseline_DF/__pretrained/.gitkeep -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/baseline_DF/config_auto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config.py 4 | 5 | This configuration file will read environment variables 6 | for configuration. it is used by 02_eval_alternative.sh 7 | 8 | 9 | """ 10 | import os 11 | 12 | __author__ = "Xin Wang" 13 | __email__ = "wangxin@nii.ac.jp" 14 | __copyright__ = "Copyright 2021, Xin Wang" 15 | 16 | ######################################################### 17 | ## Configuration for training stage 18 | ######################################################### 19 | 20 | # Name of datasets (any string you wish to use) 21 | # after data preparation, trn/val_set_name are used to save statistics 22 | # about the data sets 23 | trn_set_name = '' 24 | val_set_name = '' 25 | 26 | # File lists (text file, one data name per line, without name extension) 27 | # trin_file_list: list of files for training set 28 | trn_list = '' 29 | # val_file_list: list of files for validation set. It can be None 30 | val_list = '' 31 | 32 | # Directories for input features 33 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 34 | # we assume train and validation data are put in the same sub-directory 35 | # here, we only use waveform as input to the code 36 | input_dirs = [''] 37 | 38 | # Dimensions of input features 39 | # input_dims = [dimension_of_feature_1, dimension_of_feature_2, ...] 40 | # here, we only use waveform as input to the code, and the dimension 41 | # of waveform data is 1 42 | input_dims = [1] 43 | 44 | # File name extension for input features 45 | # input_exts = [name_extention_of_feature_1, ...] 46 | # here, we only use waveform, thus it is ".flac" 47 | input_exts = ['.flac'] 48 | 49 | # Temporal resolution for input features 50 | # input_reso = [reso_feature_1, reso_feature_2, ...] 51 | # this is used for other projects. 52 | # for waveform, we set it to 1 53 | input_reso = [1] 54 | 55 | # Whether input features should be z-normalized 56 | # input_norm = [normalize_feature_1, normalize_feature_2] 57 | # we don't z-normalize the waveform 58 | input_norm = [False] 59 | 60 | # This is for other projects, 61 | # we don't load target features for ASVspoof models using these config 62 | # we read target labels of ASVspoof trials in mode.py 63 | # but we need to fill in some placehoders 64 | output_dirs = [] 65 | output_dims = [1] 66 | output_exts = ['.bin'] 67 | output_reso = [1] 68 | output_norm = [False] 69 | 70 | # Waveform sampling rate 71 | # wav_samp_rate can be None if no waveform data is used 72 | # ASVspoof uses 16000 Hz 73 | wav_samp_rate = 16000 74 | 75 | # Truncating input sequences so that the maximum length = truncate_seq 76 | # When truncate_seq is larger, more GPU mem required 77 | # If you don't want truncating, please truncate_seq = None 78 | # For ASVspoof, we don't do truncate here 79 | truncate_seq = None 80 | 81 | # Minimum sequence length 82 | # If sequence length < minimum_len, this sequence is not used for training 83 | # minimum_len can be None 84 | # For ASVspoof, we don't set minimum length of input trial 85 | minimum_len = None 86 | 87 | 88 | # Optional argument 89 | # We will use this optional_argument to read protocol file 90 | # When evaluating on a eval set without protocol file, set this to [''] 91 | optional_argument = [''] 92 | 93 | ######################################################### 94 | ## Configuration for inference stage 95 | ######################################################### 96 | # similar options to training stage 97 | 98 | test_set_name = os.getenv('TEMP_DATA_NAME') 99 | 100 | # List of test set data 101 | # for convenience, you may directly load test_set list here 102 | test_list = test_set_name + '.lst' 103 | 104 | # Directories for input features 105 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 106 | # directory of the evaluation set waveform 107 | test_input_dirs = [os.getenv('TEMP_DATA_DIR')] 108 | 109 | # Directories for output features, which are [] 110 | test_output_dirs = [] 111 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/project/conda.sh: -------------------------------------------------------------------------------- 1 | conda env create -f ../env.yml 2 | -------------------------------------------------------------------------------- /DF/Baseline-LFCC-LCNN/sandbox: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/sandbox -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/LICENSE -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/README.md: -------------------------------------------------------------------------------- 1 | # RawNet2 ASVspoof 2021 baseline 2 | 3 | By Hemlata Tak, EURECOM, 2021 4 | 5 | ------ 6 | 7 | The code in this repository serves as one of the baselines of the ASVspoof 2021 challenge, using an end-to-end method that uses a model based on the RawNet2 topology as described [here](https://arxiv.org/abs/2011.01108). 8 | 9 | ## Installation 10 | First, clone the repository locally, create and activate a conda environment, and install the requirements : 11 | ``` 12 | $ git clone https://github.com/asvspoof-challenge/2021.git 13 | $ cd 2021/DF/Baseline-RawNet2/ 14 | $ conda create --name rawnet_anti_spoofing python=3.6.10 15 | $ conda activate rawnet_anti_spoofing 16 | $ conda install pytorch=1.4.0 -c pytorch 17 | $ pip install -r requirements.txt 18 | ``` 19 | 20 | ## Experiments 21 | 22 | ### Dataset 23 | Our model for the deepfake (DF) track is trained on the logical access (LA) train partition of the ASVspoof 2019 dataset, which can can be downloaded from [here](https://datashare.is.ed.ac.uk/handle/10283/3336). 24 | 25 | ### Training 26 | To train the model run: 27 | ``` 28 | python main.py --track=DF --loss=CCE --lr=0.0001 --batch_size=32 29 | ``` 30 | 31 | ### Testing 32 | 33 | To test your own model on the ASVspoof 2021 DF evaluation set: 34 | 35 | ``` 36 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/your_best_model.pth' --eval_output='eval_CM_scores.txt' 37 | ``` 38 | 39 | We also provide a pre-trained model which follows a Mel-scale distribution of the sinc filters at the input layer, which can be downloaded from [here](https://www.asvspoof.org/asvspoof2021/pre_trained_DF_RawNet2.zip). To use it you can run: 40 | ``` 41 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/pre_trained_DF_model.pth' --eval_output='pre_trained_eval_CM_scores.txt' 42 | ``` 43 | 44 | If you would like to compute scores on the development set of ASVspoof 2019 simply run: 45 | 46 | ``` 47 | python main.py --track=DF --loss=CCE --eval --model_path='/path/to/your/best_model.pth' --eval_output='dev_CM_scores.txt' 48 | ``` 49 | 50 | ## Contact 51 | For any query regarding this repository, please contact: 52 | - Hemlata Tak: tak[at]eurecom[dot]fr 53 | ## Citation 54 | If you use this code in your research please use the following citation: 55 | ```bibtex 56 | @INPROCEEDINGS{9414234, 57 | author={Tak, Hemlata and Patino, Jose and Todisco, Massimiliano and Nautsch, Andreas and Evans, Nicholas and Larcher, Anthony}, 58 | booktitle={IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)}, 59 | title={End-to-End anti-spoofing with RawNet2}, 60 | year={2021}, 61 | pages={6369-6373} 62 | } 63 | 64 | ``` 65 | -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/core_scripts: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/core_scripts -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/data_utils.py: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/data_utils.py -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/model.py: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/model.py -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/model_config_RawNet.yaml: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/model_config_RawNet.yaml -------------------------------------------------------------------------------- /DF/Baseline-RawNet2/requirements.txt: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/requirements.txt -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/.DS_Store -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/cqtCell2Sparse.m: -------------------------------------------------------------------------------- 1 | function cSparse = cqtCell2Sparse(c,M) 2 | 3 | bins = size(M,1)/2 - 1; 4 | spLen = M(bins+1); 5 | cSparse = zeros(bins,spLen); 6 | 7 | M = M(1:bins+1); 8 | step = 1; 9 | distinctHops = log2(M(bins+1)/M(2))+1; 10 | curNumCoef = M(bins+1); 11 | 12 | for ii=1:distinctHops 13 | idx = [(M == curNumCoef); false]; 14 | temp = cell2mat( c(idx).' ).'; 15 | cSparse(idx,1:step:end) = temp; 16 | step = step*2; 17 | curNumCoef = curNumCoef / 2; 18 | end 19 | 20 | cSparse = sparse(cSparse); 21 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/cqtFillSparse.m: -------------------------------------------------------------------------------- 1 | function c = cqtFillSparse(c,M,B) 2 | 3 | %Repeat coefficients in sparse matrix until the next valid coefficient. 4 | %For visualization this is an overkill since we could image each CQT bin 5 | %seperately, however, in some case this might come in handy. 6 | 7 | bins = size(c,1); 8 | M = M(1:bins); 9 | distinctHops = log2(M(bins)/M(2))+1; 10 | 11 | curNumCoef = M(end-1) / 2; 12 | step = 2; 13 | for ii=1:distinctHops -1 14 | idx = (M == curNumCoef); 15 | temp = c(idx,1:step:end); 16 | temp = repmat(temp,step,1); 17 | temp = reshape(temp(:), nnz(idx), []); 18 | c(idx,:) = temp; 19 | step = 2*step; 20 | curNumCoef = curNumCoef / 2; 21 | end 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/cqtSparse2Cell.m: -------------------------------------------------------------------------------- 1 | function cCell = cqtSparse2Cell(cSparse,M,cDC,cNyq) 2 | 3 | bins = size(M,1)/2 - 1; 4 | cCell = cell(1,bins+2); 5 | cCell{bins+2} = cNyq; 6 | 7 | M = M(1:bins+1); 8 | step = 1; 9 | cSparse = full(cSparse); 10 | distinctHops = log2(M(bins+1)/M(2))+1; 11 | curNumCoef = M(bins+1); 12 | 13 | for ii=1:distinctHops 14 | idx = (M == curNumCoef); 15 | temp = cSparse(idx,1:step:end).'; 16 | temp = num2cell(temp,1); 17 | cCell(idx) = temp; 18 | step = step*2; 19 | curNumCoef = curNumCoef / 2; 20 | end 21 | 22 | cCell{1} = cDC; -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/hp.m: -------------------------------------------------------------------------------- 1 | function b = hp(fs) 2 | 3 | % Equiripple Highpass filter designed using the FIRPM function. 4 | % All frequency values are in Hz. 5 | 6 | Fstop = 0.125; % Stopband Frequency 7 | Fpass = 0.25; % Passband Frequency 8 | Dstop = 0.001; % Stopband Attenuation 9 | Dpass = 0.057501127785; % Passband Ripple 10 | dens = 20; % Density Factor 11 | 12 | % Calculate the order from the parameters using FIRPMORD. 13 | [N, Fo, Ao, W] = firpmord([Fstop, Fpass]/(fs/2), [0 1], [Dstop, Dpass]); 14 | 15 | % Calculate the coefficients using the FIRPM function. 16 | b = firpm(N, Fo, Ao, W, {dens}); 17 | 18 | end -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/icqt.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/icqt.m -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsdual.m: -------------------------------------------------------------------------------- 1 | function gd = nsdual(g,shift,M) 2 | %NSDUAL Canonical dual NSG frame (for painless systems) 3 | % Usage: gd = nsdual(g,shift,M) 4 | % 5 | % Input parameters: 6 | % g : Cell array of window functions/filters 7 | % shift : Vector of time/frequency shifts 8 | % M : Number of frequency channels (vector/scalar) 9 | % Output parameters: 10 | % gd : Dual window functions 11 | % 12 | % Given a non-stationary Gabor frame specified by the windows g, shift 13 | % parameters shift, and channel numbers M, NSDUAL computes the 14 | % canonical dual frame windows/filters gd by inverting the diagonal of 15 | % the frame operator and applying the inverse to g. More explicitly, 16 | % 17 | % gd{n} = g{n} / ( sum M(l) |g{l}|^2 ), 18 | % l 19 | % 20 | % If g, shift, M specify a painless frame, i.e. 21 | % SUPP(G{N}) <= M(n)~forall~n and 22 | % 23 | % A <= sum ( M(n) |g{n}|^2 ) <= B, for some 0 < A <= B < infty 24 | % n 25 | % 26 | % the computation will result in the canonical dual frame. If g, 27 | % shift, M specify a frame, but the first condition is violated, the 28 | % result can be interpreted as a first approximation of the corresponding 29 | % canonical dual frame. 30 | % 31 | % Note, the time shifts corresponding to the dual window sequence is the 32 | % same as the original shift sequence and as such already given. 33 | % 34 | % If g, shift, M is a painless frame, the output can be used for 35 | % perfect reconstruction of a signal using the inverse nonstationary 36 | % Gabor transform NSIGT. 37 | % 38 | % See also: nsgt, nsigt, nsgt_real, nsigt_real, nsgtf, nsigtf 39 | % 40 | % References: 41 | % P. Balazs, M. Dörfler, F. Jaillet, N. Holighaus, and G. A. Velasco. 42 | % Theory, implementation and applications of nonstationary Gabor Frames. 43 | % J. Comput. Appl. Math., 236(6):1481-1496, 2011. 44 | % 45 | % 46 | % Url: http://nsg.sourceforge.net/doc/core_routines/nsdual.php 47 | 48 | % Copyright (C) 2013 Nicki Holighaus. 49 | % This file is part of NSGToolbox version 0.1.0 50 | % 51 | % This work is licensed under the Creative Commons 52 | % Attribution-NonCommercial-ShareAlike 3.0 Unported 53 | % License. To view a copy of this license, visit 54 | % http://creativecommons.org/licenses/by-nc-sa/3.0/ 55 | % or send a letter to 56 | % Creative Commons, 444 Castro Street, Suite 900, 57 | % Mountain View, California, 94041, USA. 58 | 59 | % Author: Nicki Holighaus, Gino Velasco 60 | % Date: 23.04.13 61 | 62 | % Check input arguments 63 | 64 | if nargin < 3 65 | for kk = 1:length(shift) 66 | M(kk) = length(g{kk}); M = M.'; 67 | end 68 | end 69 | 70 | if nargin < 2 71 | error('Not enough input arguments'); 72 | end 73 | 74 | if max(size(M)) == 1 75 | M = M(1)*ones(length(shift),1); 76 | end 77 | 78 | % Setup the necessary parameters 79 | N = length(shift); 80 | 81 | posit = cumsum(shift); 82 | Ls = posit(N); 83 | posit = posit-shift(1); 84 | 85 | diagonal=zeros(Ls,1); 86 | win_range = cell(N,1); 87 | 88 | % Construct the diagonal of the frame operator matrix explicitly 89 | 90 | for ii = 1:N 91 | Lg = length(g{ii}); 92 | 93 | win_range{ii} = mod(posit(ii)+(-floor(Lg/2):ceil(Lg/2)-1),Ls)+1; 94 | diagonal(win_range{ii}) = diagonal(win_range{ii}) + ... 95 | (fftshift(g{ii}).^2)*M(ii); 96 | end 97 | 98 | % Using the frame operator and the original window sequence, compute 99 | % the dual window sequence 100 | 101 | gd = g; 102 | 103 | for ii=1:N 104 | gd{ii} = ifftshift(fftshift(gd{ii})./diagonal(win_range{ii})); 105 | end 106 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsgcqwin.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsgcqwin.m -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsgtf_real.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsgtf_real.m -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsigtf_real.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/CQT_toolbox_2013/nsigtf_real.m -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/D18_1000001.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/CQCC/D18_1000001.wav -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/DEMO.m: -------------------------------------------------------------------------------- 1 | % Usage example of cqcc function 2 | % 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % Copyright (C) 2016 EURECOM, France. 5 | % 6 | % This work is licensed under the Creative Commons 7 | % Attribution-NonCommercial-ShareAlike 4.0 International 8 | % License. To view a copy of this license, visit 9 | % http://creativecommons.org/licenses/by-nc-sa/4.0/ 10 | % or send a letter to 11 | % Creative Commons, 444 Castro Street, Suite 900, 12 | % Mountain View, California, 94041, USA. 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | clear 16 | 17 | %% ADD CQT TOOLBOX TO THE PATH 18 | addpath('CQT_toolbox_2013'); 19 | 20 | %% INPUT SIGNAL 21 | [x,fs] = audioread('D18_1000001.wav'); % from ASVspoof2015 database 22 | 23 | %% PARAMETERS 24 | B = 96; 25 | fmax = fs/2; 26 | fmin = fmax/2^9; 27 | d = 16; 28 | cf = 19; 29 | ZsdD = 'ZsdD'; 30 | 31 | %% COMPUTE CQCC FEATURES 32 | [CQcc, LogP_absCQT, TimeVec, FreqVec, Ures_LogP_absCQT, Ures_FreqVec] = ... 33 | cqcc(x, fs, B, fmax, fmin, d, cf, ZsdD); 34 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/CQCC/README.txt: -------------------------------------------------------------------------------- 1 | CQCC FEATURES FOR SPOOFED SPEECH DETECTION 2 | 3 | Matlab implementation of constant Q cepstral coefficients successfully used for spoofed speech detection for speaker verification. 4 | 5 | Copyright (C) 2016 EURECOM, France. 6 | 7 | This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 8 | License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ 9 | 10 | For further details, refer to the following publication: 11 | 12 | Todisco, M., Delgado, H., Evans, N., A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients. ODYSSEY 2016, The Speaker and Language Recognition Workshop, June 21-24, 2016, Bilbao, Spain 13 | 14 | Contents of the package 15 | ======================= 16 | 17 | - CQT_toolbox_2013 18 | ------------------ 19 | This folder contains Matlab codes written by the authors of the following paper: 20 | 21 | Schörkhuber, C., Klapuri, N. Holighaus, and M. Döfler, "A Matlab Toolbox for Efficient Perfect Reconstruction Time-Frequency Transforms with Log-Frequency Resolution," AES 53rd International Conference on Semantic Audio, London, UK 22 | 23 | The toolbox can be downloaded from http://www.cs.tut.fi/sgn/arg/CQT/. This software is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/) 24 | 25 | - cqcc.m 26 | -------- 27 | Function which computes the Constant Q Cepstral Coefficients (CQCC) from a speech signal 28 | 29 | - D18_1000001.wav 30 | ----------------- 31 | Speech utterance extracted from the ASVspoof 2015 database. This file is provided as part of the demo. Please refer to the following paper: 32 | 33 | Wu, Z., Kinnunen, T., Evans, N., Yamagishi, J. (2015). Automatic Speaker Verification Spoofing and Countermeasures Challenge (ASVspoof 2015) Database, [dataset]. University of Edinburgh. The Centre for Speech Technology Research (CSTR). http://dx.doi.org/10.7488/ds/298 34 | 35 | The ASVspoof 2015 database is free for commercial and non-commercial use and is released under a Creative Commons Attribution License (CC-BY) (https://creativecommons.org/licenses/by/4.0/). 36 | 37 | - DEMO.m 38 | -------- 39 | This demo script demonstrates the use of the "cqcc.m" function. It loads the provided wave file "D18_1000001.wav" and calls the "cqcc.m" function with a set of pre-defined parameters. Those parameters were used succesfully for spoofed speech detection, delivering state-of-the-art results on the ASVspoof 2015 dataset in the following paper: 40 | 41 | Todisco, M., Delgado, H., Evans, N., A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients. ODYSSEY 2016, The Speaker and Language Recognition Workshop, June 21-24, 2016, Bilbao, Spain 42 | 43 | Contact information. 44 | ==================== 45 | 46 | For any query, please contact: 47 | 48 | - Massimiliano Todisco (todisco at eurecom.fr) 49 | - Hector Delgado (delgado at eurecom.fr) 50 | - Nicholas Evans (evans at eurecom.fr) 51 | 52 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/.DS_Store -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/compute_llk.m: -------------------------------------------------------------------------------- 1 | function llk = compute_llk(data, mu, sigma, w) 2 | % compute the posterior probability of mixtures for each frame 3 | post = lgmmprob(data, mu, sigma, w); 4 | llk = logsumexp(post, 1); 5 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/lgmmprob.m: -------------------------------------------------------------------------------- 1 | function logprob = lgmmprob(data, mu, sigma, w) 2 | % compute the log probability of observations given the GMM 3 | ndim = size(data, 1); 4 | C = sum(mu.*mu./sigma) + sum(log(sigma)); 5 | D = (1./sigma)' * (data .* data) - 2 * (mu./sigma)' * data + ndim * log(2 * pi); 6 | logprob = -0.5 * (bsxfun(@plus, C', D)); 7 | logprob = bsxfun(@plus, logprob, log(w)); -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/logsumexp.m: -------------------------------------------------------------------------------- 1 | function y = logsumexp(x, dim) 2 | % compute log(sum(exp(x),dim)) while avoiding numerical underflow 3 | xmax = max(x, [], dim); 4 | y = xmax + log(sum(exp(bsxfun(@minus, x, xmax)), dim)); 5 | ind = find(~isfinite(xmax)); 6 | if ~isempty(ind) 7 | y(ind) = xmax(ind); 8 | end -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexa64/libvl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexa64/libvl.so -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexa64/vl_gmm.mexa64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexa64/vl_gmm.mexa64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexglx/libvl.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexglx/libvl.so -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexglx/vl_gmm.mexglx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexglx/vl_gmm.mexglx -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci/libvl.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci/libvl.dylib -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci/vl_gmm.mexmaci: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci/vl_gmm.mexmaci -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci64/libvl.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci64/libvl.dylib -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci64/vl_gmm.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexmaci64/vl_gmm.mexmaci64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/msvcr100.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/msvcr100.dll -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/vl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/vl.dll -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/vl_gmm.mexw32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw32/vl_gmm.mexw32 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/msvcr100.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/msvcr100.dll -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl.dll -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_aib.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_aib.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_aibhist.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_aibhist.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_alldist.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_alldist.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_alldist2.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_alldist2.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_binsearch.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_binsearch.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_binsum.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_binsum.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_covdet.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_covdet.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_cummax.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_cummax.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_dsift.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_dsift.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_erfill.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_erfill.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_fisher.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_fisher.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_getpid.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_getpid.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_gmm.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_gmm.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hikmeans.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hikmeans.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hikmeanspush.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hikmeanspush.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hog.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_hog.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_homkermap.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_homkermap.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ihashfind.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ihashfind.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ihashsum.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ihashsum.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ikmeans.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ikmeans.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ikmeanspush.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ikmeanspush.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imdisttf.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imdisttf.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imintegral.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imintegral.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imsmooth.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imsmooth.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imwbackwardmx.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_imwbackwardmx.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_inthist.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_inthist.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_irodr.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_irodr.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kdtreebuild.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kdtreebuild.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kdtreequery.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kdtreequery.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kmeans.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_kmeans.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_lbp.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_lbp.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_liop.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_liop.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_localmax.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_localmax.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_mser.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_mser.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_quickshift.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_quickshift.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_rodr.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_rodr.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_sampleinthist.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_sampleinthist.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_sift.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_sift.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_siftdescriptor.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_siftdescriptor.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_simdctrl.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_simdctrl.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_slic.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_slic.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_svmtrain.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_svmtrain.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_threads.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_threads.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_tpsumx.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_tpsumx.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_twister.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_twister.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ubcmatch.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_ubcmatch.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_version.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_version.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_vlad.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/matlab/GMM/vlfeat/mexw64/vl_vlad.mexw64 -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Massimiliano Todisco, EURECOM 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # CQCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-end: 9 | - high-time resolution constant Q cepstral coefficients (CQCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### CQCC 16 | Matlab implementation of constant Q cepstral coefficients. 17 | 18 | For further details on CQCC, refer to the following publication: 19 | 20 | - M. Todisco, H. Delgado and N. Evans, "Constant Q cepstral coefficients: a spoofing countermeasure for automatic speaker verification", Computer, Speech and Language, vol. 45, pp. 516 –535, 2017. 21 | 22 | - M. Todisco, H. Delgado, N. Evans, "A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients," in Proc. ODYSSEY 2016, The Speaker and Language Recognition Workshop, 2016. 23 | 24 | ### GMM 25 | VLFeat open source library that implements the GMMs. 26 | 27 | For further details, refer to: 28 | http://www.vlfeat.org/ 29 | 30 | ### CQCC_GMM_ASVspoof_2021_baseline.m 31 | This script implements the CQCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Logical Access (LA) task. 32 | Front-ends include high-time resolution CQCC features, while back-end is based on GMMs. 33 | CQCC features use 12 bins per octave. Re-sampling is applied with a sampling period of 16 and the features dimension is set to 19 coefficients + 0th, with the static, delta and delta-delta coefficients. CQCC is applied with a maximum frequency of 4 kHz. 34 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 35 | 36 | Results are shown in the ASVspoof 2021 Evaluation Plan. 37 | 38 | ## Contact information 39 | For any query, please contact organisers at lists.asvspoof.org 40 | 41 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/cqtCell2Sparse.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | import scipy.sparse as sps 4 | 5 | def cqtCell2Sparse(c, M): 6 | 7 | bins = M.shape[1]/2 - 1 8 | spLen = M[bins+1-1] 9 | cSparse = np.zeros((bins,spLen)) 10 | 11 | M = M[:bins+1-1] 12 | 13 | step = 1 14 | 15 | distinctHops = math.log(M[bins+1-1]/M[2], 2)+1 16 | curNumCoef = M[bins+1-1] 17 | 18 | for ii in range(distinctHops): 19 | idx = [M == curNumCoef] + [false] 20 | 21 | temp = cell2mat(c[idx].T).T 22 | idx += list(range(0,len(cSparse), step)) 23 | cSparse[idx] = temp 24 | step = step*2 25 | curNumCoef = curNumCoef / 2 26 | 27 | cSparse = sparse(cSparse) # sparse return (index), value 28 | 29 | return cSparse 30 | 31 | 32 | def cell2mat(c): 33 | # print("c.length:", len(c)) 34 | c = np.stack(c) 35 | if c.ndim == 3: 36 | c = np.squeeze(c, axis=-1) 37 | c = c.T # cell2mat(c) 38 | return c 39 | 40 | def sparse(m): 41 | index_res = np.where(m>0) 42 | index_list = [index for index in index_res] 43 | value_list = [m[index[0]][index[1]] for index in index_res] 44 | return index_list, value_list -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/cqtFillSparse.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | 4 | 5 | def cqtFillSparse(c, M, B): 6 | 7 | # %Repeat coefficients in sparse matrix until the next valid coefficient. 8 | # %For visualization this is an overkill since we could image each CQT bin 9 | # %seperately, however, in some case this might come in handy. 10 | 11 | bins = c.shape[1] 12 | M = M[:bins] 13 | distinctHops = math.log(M[bins]/M[2-1], 2)+1 14 | 15 | curNumCoef = M[-1-1] / 2 16 | step = 2 17 | for ii in range(distinctHops -1): 18 | idx = [M == curNumCoef] 19 | idx += list(range(0, len(c), step)) 20 | temp = c[idx] 21 | temp = np.tile(temp, (step, 1)) 22 | temp = np.reshape(temp[:], ((idx!=0).sum(), [])) 23 | idx += list(range(len(c))) 24 | c[idx] = temp 25 | step = 2*step 26 | curNumCoef = curNumCoef / 2 27 | 28 | return c 29 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/cqtSparse2Cell.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | ''' 4 | 1. cell 5 | 2. full 6 | ''' 7 | 8 | def cqtSparse2Cell(cSparse,M,cDC,cNyq): 9 | 10 | bins = M.shape[0]/2 - 1 11 | # cell 12 | cCell = cell(1,bins+2) 13 | cCell{bins+2} = cNyq 14 | 15 | M = M[0:bins+1] 16 | step = 1 17 | # full 18 | cSparse = full(cSparse) 19 | distinctHops = np.log2(M[bins]/M[1])+1 20 | curNumCoef = M[bins] 21 | 22 | 23 | for ii in range(distinctHops): 24 | idx = (M == curNumCoef) 25 | # cSparse 26 | temp = cSparse(idx,1:step:end).T 27 | temp = num2cell(temp,1) 28 | cCell(idx) = temp 29 | step = step * 2 30 | curNumCoef = curNumCoef / 2 31 | 32 | cCell{1} = cDC 33 | 34 | return cCell 35 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/hp.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | ''' 4 | 1. firpmord 5 | 2. firpm 6 | ''' 7 | 8 | def hp(fs): 9 | 10 | Fstop = 0.125 11 | Fpass = 0.25 12 | Dstop = 0.001 13 | Dpass = 0.057501127785 14 | dens = 20 15 | 16 | # firpmord 17 | N, Fo, Ao, W = firpmord([Fstop, Fpass]/(fs/2), [0 1], [Dstop, Dpass]) 18 | 19 | # firpm 20 | b = firpm(N, Fo, Ao, W, {dens}) 21 | 22 | return b 23 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/icqt.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | ''' 4 | 1. cell 5 | 2. num2cell 6 | ''' 7 | 8 | def icqt(Xcq): 9 | 10 | Xcq.gd = {nsdual(Xcq.g,Xcq.shift,Xcq.M)} 11 | 12 | if Xcq.rast == 'piecewise': 13 | if Xcq.format == 'sparse': 14 | c = cqtSparse2Cell(Xcq.c,Xcq.M, Xcq.cDC, Xcq.cNyq) 15 | else: 16 | # cell 17 | c = cell(1,Xcq.shape[1]+2) 18 | c[1:-2] = Xcq.c[:] 19 | c[0] = {Xcq.cDC.T} 20 | c[-1] = {Xcq.cNyq} 21 | elif Xcq.rast == 'full': 22 | # cell 23 | c = cell(1,Xcq.shape[0]+2) 24 | # num2cell 25 | c[1:-2] = num2cell(Xcq.c,1) 26 | c[0] = {Xcq.cDC.T} 27 | c[-1] = {Xcq.cNyq.T} 28 | else: 29 | c = cell(1,Xcq.c.shape[1]+2) 30 | c[1:-2] = Xcq.c[:] 31 | c[0] = {Xcq.cDC} 32 | c[-1] = {Xcq.cNyq} 33 | 34 | x = nsigtf_real(c,Xcq.gd{1},Xcq.shift,Xcq.xlen, Xcq.phasemode) 35 | 36 | gd = Xcq.gd[0] 37 | 38 | return gd -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/nsdual.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | import scipy.fftpack 4 | 5 | 6 | def nsdual(*args): 7 | # %NSDUAL Canonical dual NSG frame (for painless systems) 8 | # % Usage: gd = nsdual(g,shift,M) 9 | # % 10 | # % Input parameters: 11 | # % g : Cell array of window functions/filters 12 | # % shift : Vector of time/frequency shifts 13 | # % M : Number of frequency channels (vector/scalar) 14 | # % Output parameters: 15 | # % gd : Dual window functions 16 | # % 17 | # % Given a non-stationary Gabor frame specified by the windows g, shift 18 | # % parameters shift, and channel numbers M, NSDUAL computes the 19 | # % canonical dual frame windows/filters gd by inverting the diagonal of 20 | # % the frame operator and applying the inverse to g. More explicitly, 21 | # % 22 | # % gd{n} = g{n} / ( sum M(l) |g{l}|^2 ), 23 | # % l 24 | # % 25 | # % If g, shift, M specify a painless frame, i.e. 26 | # % SUPP(G{N}) <= M(n)~forall~n and 27 | # % 28 | # % A <= sum ( M(n) |g{n}|^2 ) <= B, for some 0 < A <= B < infty 29 | # % n 30 | # % 31 | # % the computation will result in the canonical dual frame. If g, 32 | # % shift, M specify a frame, but the first condition is violated, the 33 | # % result can be interpreted as a first approximation of the corresponding 34 | # % canonical dual frame. 35 | # % 36 | # % Note, the time shifts corresponding to the dual window sequence is the 37 | # % same as the original shift sequence and as such already given. 38 | # % 39 | # % If g, shift, M is a painless frame, the output can be used for 40 | # % perfect reconstruction of a signal using the inverse nonstationary 41 | # % Gabor transform NSIGT. 42 | # % 43 | # % See also: nsgt, nsigt, nsgt_real, nsigt_real, nsgtf, nsigtf 44 | # % 45 | # % References: 46 | # % P. Balazs, M. Dörfler, F. Jaillet, N. Holighaus, and G. A. Velasco. 47 | # % Theory, implementation and applications of nonstationary Gabor Frames. 48 | # % J. Comput. Appl. Math., 236(6):1481-1496, 2011. 49 | # % 50 | # % 51 | # % Url: http://nsg.sourceforge.net/doc/core_routines/nsdual.php 52 | 53 | # % Copyright (C) 2013 Nicki Holighaus. 54 | # % This file is part of NSGToolbox version 0.1.0 55 | # % 56 | # % This work is licensed under the Creative Commons 57 | # % Attribution-NonCommercial-ShareAlike 3.0 Unported 58 | # % License. To view a copy of this license, visit 59 | # % http://creativecommons.org/licenses/by-nc-sa/3.0/ 60 | # % or send a letter to 61 | # % Creative Commons, 444 Castro Street, Suite 900, 62 | # % Mountain View, California, 94041, USA. 63 | 64 | # % Author: Nicki Holighaus, Gino Velasco 65 | # % Date: 23.04.13 66 | 67 | # Check input arguments 68 | nargin = len(args) 69 | assert nargin < 2, 'Not enough input arguments' 70 | 71 | g = args[0] # Cell array of window functions/filters 72 | shift = args[1] # Vector of time/frequency shifts 73 | 74 | if nargin < 3: 75 | for kk in range(len(shift)): 76 | M[kk] = len(g[kk]) 77 | M = M.T 78 | else: 79 | M = args[2] # Number of frequency channels (vector/scalar) 80 | 81 | if max(M.shape) == 1: 82 | M = M[0] * np.ones((len(shift),1)) 83 | 84 | # Setup the necessary parameters 85 | N = len(shift) 86 | 87 | posit = np.cumsum(shift) 88 | Ls = posit[N-1] 89 | posit = posit-shift[0] 90 | 91 | diagonal = np.zeros((Ls,1)) 92 | win_range = np.empty((N,1),dtype=object) # Create cell array 93 | 94 | # Construct the diagonal of the frame operator matrix explicitly 95 | 96 | for ii in range(N): 97 | Lg = len(g[ii]) 98 | win_range[ii] = (posit[ii]+[-math.floor(Lg/2):math.ceil(Lg/2)]) % Ls+1 99 | np.diag(win_range[ii]) = np.diag(win_range[ii]) + (np.fft.fftshift(g[ii])**2)*M[ii] 100 | end 101 | 102 | # Using the frame operator and the original window sequence, compute 103 | # the dual window sequence 104 | 105 | gd = g 106 | 107 | for ii in range(N): 108 | gd[ii] = np.fft.ifftshift(np.fft.fftshift(gd[ii]) / np.diag(win_range[ii])) 109 | 110 | return gd # Dual window functions 111 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/CQT_toolbox_2013/nsigtf_real.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def nsigtf_real(*args): 4 | 5 | nargin = len(args) 6 | 7 | if nargin < 4: 8 | raiseValueError('Not enough input arguments') 9 | 10 | # iscell 11 | if iscell(c) == 0: 12 | if np.ndims(c) == 2: 13 | N, chan_len = c.shape 14 | CH = 1 15 | # 16 | c = mat2cell(c.',chan_len,ones(1,N)).') 17 | else: 18 | N, chan_len, CH = c.shape 19 | ctemp = mat2cell(np.permute(c,[2,1,3]),chan_len,np.ones((1,N)),np.ones((1,CH))) 20 | c = np.permute(ctemp,[2,3,1]) 21 | else: 22 | CH, N = c.shape 23 | 24 | posit = np.cumsum(shift) 25 | NN = posit[-1] 26 | posit = posit - shift[1] 27 | 28 | fr = np.zeros((NN,CH)) 29 | 30 | for ii in range(N): 31 | Lg = len(g[ii]) 32 | win_range = (posit[ii]+(-np.floor(Lg/2):math.ceil(Lg/2)-1)) % NN + 1 33 | temp = np.fft(c[ii], [], 1) * len(c[ii]) 34 | 35 | if phasemode == 'global': 36 | fsNewBins = c[ii].shape[0] 37 | fkBins = posit[ii] 38 | displace = fkBins - np.floor(fkBins/fsNewBins) * fsNewBins 39 | temp = np.roll(temp, -displace) 40 | 41 | # 42 | temp = temp[] 43 | 44 | fr[win_range,:] = fr[win_Range,:] + temp * g[ii][Lg-np.floor(Lg/2)+1:Lg, 1:np.ceil(Lg/2)] 45 | 46 | nyqBin = np.floor(Ls/2) + 1 47 | 48 | # 49 | fr[nyqBin+1:end] = conj( fr(nyqBin - (~logical(mod(Ls,2))) : -1 : 2) ) 50 | 51 | fr = np.real(np.fft.ifft(fr)) 52 | 53 | return fr -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/README.txt: -------------------------------------------------------------------------------- 1 | CQCC FEATURES FOR SPOOFED SPEECH DETECTION 2 | 3 | Matlab implementation of constant Q cepstral coefficients successfully used for spoofed speech detection for speaker verification. 4 | 5 | Copyright (C) 2016 EURECOM, France. 6 | 7 | This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International 8 | License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ 9 | 10 | For further details, refer to the following publication: 11 | 12 | Todisco, M., Delgado, H., Evans, N., A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients. ODYSSEY 2016, The Speaker and Language Recognition Workshop, June 21-24, 2016, Bilbao, Spain 13 | 14 | Contents of the package 15 | ======================= 16 | 17 | - CQT_toolbox_2013 18 | ------------------ 19 | This folder contains Matlab codes written by the authors of the following paper: 20 | 21 | Schörkhuber, C., Klapuri, N. Holighaus, and M. Döfler, "A Matlab Toolbox for Efficient Perfect Reconstruction Time-Frequency Transforms with Log-Frequency Resolution," AES 53rd International Conference on Semantic Audio, London, UK 22 | 23 | The toolbox can be downloaded from http://www.cs.tut.fi/sgn/arg/CQT/. This software is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/) 24 | 25 | - cqcc.m 26 | -------- 27 | Function which computes the Constant Q Cepstral Coefficients (CQCC) from a speech signal 28 | 29 | - D18_1000001.wav 30 | ----------------- 31 | Speech utterance extracted from the ASVspoof 2015 database. This file is provided as part of the demo. Please refer to the following paper: 32 | 33 | Wu, Z., Kinnunen, T., Evans, N., Yamagishi, J. (2015). Automatic Speaker Verification Spoofing and Countermeasures Challenge (ASVspoof 2015) Database, [dataset]. University of Edinburgh. The Centre for Speech Technology Research (CSTR). http://dx.doi.org/10.7488/ds/298 34 | 35 | The ASVspoof 2015 database is free for commercial and non-commercial use and is released under a Creative Commons Attribution License (CC-BY) (https://creativecommons.org/licenses/by/4.0/). 36 | 37 | - DEMO.m 38 | -------- 39 | This demo script demonstrates the use of the "cqcc.m" function. It loads the provided wave file "D18_1000001.wav" and calls the "cqcc.m" function with a set of pre-defined parameters. Those parameters were used succesfully for spoofed speech detection, delivering state-of-the-art results on the ASVspoof 2015 dataset in the following paper: 40 | 41 | Todisco, M., Delgado, H., Evans, N., A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients. ODYSSEY 2016, The Speaker and Language Recognition Workshop, June 21-24, 2016, Bilbao, Spain 42 | 43 | Contact information. 44 | ==================== 45 | 46 | For any query, please contact: 47 | 48 | - Massimiliano Todisco (todisco at eurecom.fr) 49 | - Hector Delgado (delgado at eurecom.fr) 50 | - Nicholas Evans (evans at eurecom.fr) 51 | 52 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-CQCC-GMM/python/CQCC/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/cqcc_ori.py: -------------------------------------------------------------------------------- 1 | import librosa 2 | import numpy as np 3 | import scipy 4 | 5 | 6 | def cqt(sig, fs=16000, low_freq=10, high_freq=3000, b=48): 7 | """ 8 | Compute the constant Q-transform. 9 | - take the absolute value of the FFT 10 | - warp to a Mel frequency scale 11 | - take the DCT of the log-Mel-spectrum 12 | - return the first components 13 | Args: 14 | sig (array) : a mono audio signal (Nx1) from which to compute features. 15 | fs (int) : the sampling frequency of the signal we are working with. 16 | Default is 16000. 17 | low_freq (int) : lowest band edge of mel filters (Hz). 18 | Default is 10. 19 | high_freq (int) : highest band edge of mel filters (Hz). 20 | Default is 3000. 21 | b (int) : number of bins per octave. 22 | Default is 48. 23 | Returns: 24 | array including the Q-transform coefficients. 25 | """ 26 | 27 | # define lambda funcs for clarity 28 | def f(k): 29 | return low_freq * 2**((k - 1) / b) 30 | 31 | def w(N): 32 | return np.hamming(N) 33 | 34 | def nk(k): 35 | return np.ceil(Q * fs / f(k)) 36 | 37 | def t(Nk, k): 38 | return (1 / Nk) * w(Nk) * np.exp( 39 | 2 * np.pi * 1j * Q * np.arange(Nk) / Nk) 40 | 41 | # init vars 42 | Q = 1 / (2**(1 / b) - 1) 43 | K = int(np.ceil(b * np.log2(high_freq / low_freq))) 44 | print(K) 45 | nfft = int(2**np.ceil(np.log2(Q * fs / low_freq))) 46 | 47 | # define temporal kernal and sparse kernal variables 48 | S = [ 49 | scipy.sparse.coo_matrix(np.fft.fft(t(nk(k), k), nfft)) 50 | for k in range(K, 0, -1) 51 | ] 52 | S = scipy.sparse.vstack(S[::-1]).tocsc().transpose().conj() / nfft 53 | 54 | # compute the constant Q-transform 55 | xcq = (np.fft.fft(sig, nfft).reshape(1, nfft) * S)[0] 56 | return xcq 57 | 58 | 59 | def cqcc(x, fs, B, fmax, fmin, d, cf, ZsdD): 60 | 61 | 62 | # Step 1: cqt 63 | # xcq = cqt(x, fs, fmin, fmax, B) 64 | 65 | # xcq = librosa.feature.chroma_cqt(x, fs, fmin=fmin, bins_per_octave=B) 66 | 67 | absCQt = abs(xcq) 68 | 69 | print(absCQt.shape) 70 | 71 | 72 | 73 | 74 | # Step 2: power spectrum 75 | 76 | 77 | 78 | 79 | 80 | # Step 3: log power spectrum 81 | 82 | 83 | 84 | 85 | # Step 4: uniform resampling 86 | 87 | 88 | 89 | 90 | 91 | # Step 5: dct 92 | 93 | 94 | 95 | # Step 6: CQCC formula 96 | 97 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/CQCC/demo.py: -------------------------------------------------------------------------------- 1 | import librosa 2 | from cqcc import cqcc 3 | import matplotlib.pyplot as plt 4 | 5 | # filename = "./D18_1000001.wav" 6 | 7 | filename = "./source1.wav" 8 | 9 | # INPUT SIGNAL 10 | x,fs = librosa.load(filename, sr = 16000); # from ASVspoof2015 database 11 | x = x.reshape(x.shape[0], 1) # for one-channel signal 12 | 13 | print(x.shape) 14 | # fs: 16000 15 | # x: (64244,) 16 | 17 | # PARAMETERS 18 | B = 96 19 | fmax = fs/2 20 | fmin = fmax/2**9 21 | d = 16 22 | cf = 19 23 | ZsdD = 'ZsdD' 24 | 25 | # COMPUTE CQCC FEATURES 26 | CQcc, LogP_absCQT, TimeVec, FreqVec, Ures_LogP_absCQT, Ures_FreqVec, absCQT = cqcc(x, fs, B, fmax, fmin, d, cf, ZsdD) 27 | print("cqcc_feat:", CQcc.shape) # number of frames * number of cep 28 | print("cqcc_lpms:", LogP_absCQT.shape) 29 | #### visulization spectrum ##### 30 | plt.figure() 31 | plt.title('Log power magnitude spectrum of CQCC') 32 | # plt.ylabel('Log power magnitude') 33 | # plt.xlabel('Number of frames') 34 | plt.imshow(LogP_absCQT.T) 35 | 36 | # COMPUTE MFCC FEATURES 37 | from python_speech_features import mfcc 38 | from python_speech_features import logfbank 39 | import scipy.io.wavfile as wav 40 | 41 | (rate,sig) = wav.read(filename) 42 | mfcc_feat = mfcc(sig,rate) # number of frames * number of cep 43 | fbank_feat = logfbank(sig,rate) 44 | print("mfcc_feat:", mfcc_feat.shape) 45 | print("mfcc_lgms:", fbank_feat.shape) 46 | 47 | plt.figure() 48 | plt.title('Log Mel-filterbank energy features of MFCC') 49 | # plt.ylabel('Log power magnitude') 50 | # plt.xlabel('Number of frames') 51 | plt.imshow(fbank_feat.T) 52 | plt.show() 53 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | # CQCC-GMM ASVspoof 2021 baseline 2 | By Andreas Nautsch, EURECOM, 2021 3 |
4 | ## Run baseline 5 | To train a GMM: 6 | ```bash 7 | python asvspoof2021_baseline.py 8 | ``` 9 | 10 | To score files: 11 | ```bash 12 | python gmm_scoring_asvspoof21.py 13 | ``` 14 | 15 | ## Installation 16 | The use of miniconda/anaconda is recommended. One might like to create a specific environment for each project. Python 3.7 is used here. 17 | 18 | To install required packages, simply run on your terminal: 19 | ```bash 20 | pip install spafe librosa pandas matplotlib samplerate h5py 21 | ``` 22 | 23 | h5py is used to cache extracted features; data is compressed in a database (e.g., an lfcc.h5 file). 24 | Yet, at least 12 GB extra storage are to be expected. The caching of features can be easily deactivated. 25 | 26 | ## Runtime performance (poor) 27 | The CQCC library is not optimised for runtime speed. It takes a while (e.g., 3s per audio). The purpose of this code is to demonstrate only; there is no optimisation of spectral density estimation, among others. 28 | 29 | ## Shout out 30 | Thanks to Shentong Mo for converting our Matlab scripts and the two underlying toolboxes to Python! 31 | 32 | https://stonemo.github.io 33 | 34 | https://github.com/stoneMo/ASVspoof 35 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | from gmm import train_gmm 2 | from os.path import exists 3 | import pickle 4 | 5 | 6 | # configs - feature extraction e.g., LFCC or CQCC 7 | features = 'cqcc' 8 | 9 | # configs - GMM parameters 10 | ncomp = 512 11 | 12 | # GMM pickle file 13 | dict_file = 'gmm_LA_cqcc.pkl' 14 | dict_file_final = 'gmm_cqcc_asvspoof21_la.pkl' 15 | 16 | # configs - train & dev data - if you change these datasets 17 | db_folder = '' 18 | train_folders = [db_folder + 'LA/ASVspoof2019_LA_train/flac/'] # [db_folder + 'LA/ASVspoof2019_LA_train/flac/', db_folder + 'LA/ASVspoof2019_LA_dev/flac/'] 19 | train_keys = [db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.train.trn.txt'] # [db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.train.trn.txt', db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.dev.trn.txt'] 20 | 21 | audio_ext = '.flac' 22 | 23 | # train bona fide & spoof GMMs 24 | if not exists(dict_file): 25 | gmm_bona = train_gmm(data_label='bonafide', features=features, 26 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 27 | dict_file=dict_file, ncomp=ncomp, 28 | init_only=True) 29 | gmm_spoof = train_gmm(data_label='spoof', features=features, 30 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 31 | dict_file=dict_file, ncomp=ncomp, 32 | init_only=True) 33 | 34 | gmm_dict = dict() 35 | gmm_dict['bona'] = gmm_bona._get_parameters() 36 | gmm_dict['spoof'] = gmm_spoof._get_parameters() 37 | with open(dict_file, "wb") as tf: 38 | pickle.dump(gmm_dict, tf) 39 | 40 | 41 | gmm_dict = dict() 42 | with open(dict_file + '_bonafide_init_partial.pkl', "rb") as tf: 43 | gmm_dict['bona'] = pickle.load(tf) 44 | 45 | with open(dict_file + '_spoof_init_partial.pkl', "rb") as tf: 46 | gmm_dict['spoof'] = pickle.load(tf) 47 | 48 | with open(dict_file_final, "wb") as f: 49 | pickle.dump(gmm_dict, f) 50 | 51 | -------------------------------------------------------------------------------- /LA/Baseline-CQCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-cqcc-asvspoof21-LA.txt' 6 | 7 | # configs 8 | features = 'cqcc' 9 | dict_file = 'gmm_cqcc_asvspoof21_la.pkl' 10 | 11 | <<<<<<< HEAD 12 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 13 | ======= 14 | db_folder = '' # put your database root path here 15 | >>>>>>> c8f7e744ef95f4df5d225292fe3f902ed32ca6f1 16 | eval_folder = db_folder + 'LA/ASVspoof2021_LA_eval/flac/' 17 | eval_ndx = db_folder + 'LA/ASVspoof2021_LA_cm_protocols/ASVspoof2021.LA.cm.eval.trl.txt' 18 | 19 | audio_ext = '.flac' 20 | 21 | # run on ASVspoof 2021 evaluation set 22 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 23 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 24 | features_cached=True) 25 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/matlab/GMM: -------------------------------------------------------------------------------- 1 | ../../Baseline-CQCC-GMM/matlab/GMM -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/matlab/LFCC/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-GMM/matlab/LFCC/.DS_Store -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/matlab/LFCC/lfcc_bp.m: -------------------------------------------------------------------------------- 1 | function [stat,delta,double_delta]=lfcc_bp(speech,Fs,Window_Length,NFFT,No_Filter,No_coeff,low_freq,high_freq) 2 | % Function for computing LFCC features 3 | % Usage: [stat,delta,double_delta]=extract_lfcc(file_path,Fs,Window_Length,No_Filter) 4 | % 5 | % Input: file_path=Path of the speech file 6 | % Fs=Sampling frequency in Hz 7 | % Window_Length=Window length in ms 8 | % NFFT=No of FFT bins 9 | % No_Filter=No of filter 10 | % low_freq=minimum frequency for LFCC processing 11 | % high_freq=maximum frequency for LFCC processing 12 | % 13 | % Output: stat=Static LFCC (Size: NxNo_Filter where N is the number of frames) 14 | % delta=Delta LFCC (Size: NxNo_Filter where N is the number of frames) 15 | % double_delta=Double Delta LFCC (Size: NxNo_Filter where N is the number of frames) 16 | % 17 | % Written by Md Sahidullah at School of Computing, University of 18 | % Eastern Finland (email: sahid@cs.uef.fi) 19 | % 20 | % Implementation details are available in the following paper: 21 | % M. Sahidullah, T. Kinnunen, C. Hanilçi, ”A comparison of features 22 | % for synthetic speech detection”, Proc. Interspeech 2015, 23 | % pp. 2087--2091, Dresden, Germany, September 2015. 24 | 25 | %---------------------------FRAMING & WINDOWING---------------------------- 26 | frame_length_inSample=(Fs/1000)*Window_Length; 27 | framedspeech=buffer(speech,frame_length_inSample,frame_length_inSample/2,'nodelay')'; 28 | w=hamming(frame_length_inSample); 29 | y_framed=framedspeech.*repmat(w',size(framedspeech,1),1); 30 | %-------------------------------------------------------------------------- 31 | f=(Fs/2)*linspace(0,1,NFFT/2+1); 32 | filbandwidthsf=linspace(low_freq,high_freq,No_Filter+2); 33 | fr_all=(abs(fft(y_framed',NFFT))).^2; 34 | 35 | [~,closestIndex_low_freq] = min(abs(f-low_freq)); 36 | [~,closestIndex_high_freq] = min(abs(f-high_freq)); 37 | fa_all=fr_all(closestIndex_low_freq:closestIndex_high_freq,:)'; 38 | filterbank=zeros(size(fa_all,2),No_Filter); 39 | f = f(closestIndex_low_freq:closestIndex_high_freq); 40 | 41 | for i=1:No_Filter 42 | filterbank(:,i)=trimf(f,[filbandwidthsf(i),filbandwidthsf(i+1),... 43 | filbandwidthsf(i+2)]); 44 | end 45 | filbanksum=fa_all*filterbank(1:end,:); 46 | %-------------------------Calculate Static Cepstral------------------------ 47 | t=dct(log10(filbanksum'+eps)); 48 | t=(t(1:No_coeff,:)); 49 | stat=t'; 50 | delta=Deltas(stat',1)'; 51 | double_delta=Deltas(delta',1)'; 52 | %-------------------------------------------------------------------------- 53 | 54 | end 55 | 56 | function D = Deltas(x,hlen) 57 | 58 | % Delta and acceleration coefficients 59 | % 60 | % Reference: 61 | % Young S.J., Evermann G., Gales M.J.F., Kershaw D., Liu X., Moore G., Odell J., Ollason D., 62 | % Povey D., Valtchev V. and Woodland P., The HTK Book (for HTK Version 3.4) December 2006. 63 | 64 | win = hlen:-1:-hlen; 65 | xx = [repmat(x(:,1),1,hlen),x,repmat(x(:,end),1,hlen)]; 66 | D = filter(win, 1, xx, [], 2); 67 | D = D(:,hlen*2+1:end); 68 | D = D./(2*sum((1:hlen).^2)); 69 | end -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/matlab/LICENSE: -------------------------------------------------------------------------------- 1 | ../../Baseline-CQCC-GMM/matlab/LICENSE -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # LFCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-ends: 9 | - high-frequency resolution linear frequency cepstral coefficients (LFCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### LFCC 16 | Matlab implementation of linear frequency cepstral coefficients. 17 | 18 | For further details on LFCC for antispoofing, refer to the following publication: 19 | 20 | - H. Tak, J. Patino, A. Nautsch, N. Evans, M. Todisco, "Spoofing Attack Detection using the Non-linear Fusion of Sub-band Classifiers" in Proc INTERSPEECH, 2020. 21 | - M. Sahidullah, T. Kinnunen, C. Hanilçi, "A Comparison of Features for Synthetic Speech Detection," in Proc INTERSPEECH, 2015. 22 | 23 | ### GMM 24 | VLFeat open source library that implements the GMMs. 25 | 26 | For further details, refer to: 27 | http://www.vlfeat.org/ 28 | 29 | ### LFCC_GMM_ASVspoof_2021_baseline.m 30 | This script implements the LFCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Logical Access (LA) task. 31 | Front-ends include high-frequency resolution LFCC features, while back-end is based on GMMs. 32 | LFCC features use a 30 ms window with a 15 ms shift, 1024-point Fourier transform, 70-channel linear filterbank, from which 19 coefficients + 0th, with the static, delta and delta-delta coefficients. LFCC is applied with a maximum frequency of 4 kHz. 33 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 34 | 35 | Results are shown in the ASVspoof 2021 Evaluation Plan. 36 | 37 | ## Contact information 38 | For any query, please contact organisers at lists.asvspoof.org 39 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | # LFCC-GMM ASVspoof 2021 baseline 2 | By Andreas Nautsch, EURECOM, 2021 3 |
4 | 5 | ## Run baseline 6 | To train a GMM: 7 | ```bash 8 | python asvspoof2021_baseline.py 9 | ``` 10 | 11 | To score files: 12 | ```bash 13 | python gmm_scoring_asvspoof21.py 14 | ``` 15 | 16 | ## Installation 17 | The use of miniconda/anaconda is recommended. One might like to create a specific environment for each project. Python 3.7 is used here. 18 | 19 | To install required packages, simply run on your terminal: 20 | ```bash 21 | pip install spafe librosa pandas matplotlib samplerate h5py 22 | ``` 23 | 24 | h5py is used to cache extracted features; data is compressed in a database (e.g., an lfcc.h5 file). 25 | Yet, at least 12 GB extra storage are to be expected. The caching of features can be easily deactivated. 26 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | from gmm import train_gmm 2 | from os.path import exists 3 | import pickle 4 | 5 | 6 | # configs - feature extraction e.g., LFCC or CQCC 7 | features = 'lfcc' 8 | 9 | # configs - GMM parameters 10 | ncomp = 512 11 | 12 | # GMM pickle file 13 | dict_file = 'gmm_LA_lfcc.pkl' 14 | dict_file_final = 'gmm_lfcc_asvspoof21_la.pkl' 15 | 16 | # configs - train & dev data - if you change these datasets 17 | db_folder = '/path/to/ASVspoof_root/' 18 | train_folders = [db_folder + 'LA/ASVspoof2019_LA_train/flac/'] # [db_folder + 'LA/ASVspoof2019_LA_train/flac/', db_folder + 'LA/ASVspoof2019_LA_dev/flac/'] 19 | train_keys = [db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.train.trn.txt'] # [db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.train.trn.txt', db_folder + 'LA/ASVspoof2019_LA_cm_protocols/ASVspoof2019.LA.cm.dev.trn.txt'] 20 | 21 | audio_ext = '.flac' 22 | 23 | # train bona fide & spoof GMMs 24 | if not exists(dict_file): 25 | gmm_bona = train_gmm(data_label='bonafide', features=features, 26 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 27 | dict_file=dict_file, ncomp=ncomp, 28 | init_only=True) 29 | gmm_spoof = train_gmm(data_label='spoof', features=features, 30 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 31 | dict_file=dict_file, ncomp=ncomp, 32 | init_only=True) 33 | 34 | gmm_dict = dict() 35 | gmm_dict['bona'] = gmm_bona._get_parameters() 36 | gmm_dict['spoof'] = gmm_spoof._get_parameters() 37 | with open(dict_file, "wb") as tf: 38 | pickle.dump(gmm_dict, tf) 39 | 40 | 41 | gmm_dict = dict() 42 | with open(dict_file + '_bonafide_init_partial.pkl', "rb") as tf: 43 | gmm_dict['bona'] = pickle.load(tf) 44 | 45 | with open(dict_file + '_spoof_init_partial.pkl', "rb") as tf: 46 | gmm_dict['spoof'] = pickle.load(tf) 47 | 48 | with open(dict_file_final, "wb") as f: 49 | pickle.dump(gmm_dict, f) 50 | 51 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-lfcc-asvspoof21-LA.txt' 6 | 7 | # configs 8 | features = 'lfcc' 9 | dict_file = 'gmm_lfcc_asvspoof21_la.pkl' 10 | 11 | <<<<<<< HEAD 12 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 13 | ======= 14 | db_folder = '' # put your database root path here 15 | >>>>>>> c8f7e744ef95f4df5d225292fe3f902ed32ca6f1 16 | eval_folder = db_folder + 'LA/ASVspoof2021_LA_eval/flac/' 17 | eval_ndx = db_folder + 'LA/ASVspoof2021_LA_cm_protocols/ASVspoof2021.LA.cm.eval.trl.txt' 18 | 19 | audio_ext = '.flac' 20 | 21 | # run on ASVspoof 2021 evaluation set 22 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 23 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 24 | features_cached=True) 25 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Xin Wang, National Institute of Informatics 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_modules/grad_rev.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | grad_rev.py 4 | 5 | Definition of gradient reverse layer 6 | 7 | Copied from https://cyberagent.ai/blog/research/11863/ 8 | """ 9 | from __future__ import absolute_import 10 | from __future__ import print_function 11 | 12 | import sys 13 | import torch 14 | import torch.nn as torch_nn 15 | import torch.nn.functional as torch_nn_func 16 | 17 | __author__ = "Xin Wang" 18 | __email__ = "wangxin@nii.ac.jp" 19 | __copyright__ = "Copyright 2020, Xin Wang" 20 | 21 | # 22 | class GradientReversalFunction(torch.autograd.Function): 23 | """ https://cyberagent.ai/blog/research/11863/ 24 | """ 25 | @staticmethod 26 | def forward(ctx, x, scale): 27 | ctx.save_for_backward(scale) 28 | return x 29 | 30 | @staticmethod 31 | def backward(ctx, grad): 32 | scale, = ctx.saved_tensors 33 | return scale * -grad, None 34 | 35 | class GradientReversal(torch_nn.Module): 36 | """ https://cyberagent.ai/blog/research/11863/ 37 | """ 38 | def __init__(self, scale: float): 39 | super(GradientReversal, self).__init__() 40 | self.scale = torch.tensor(scale) 41 | 42 | def forward(self, x): 43 | return GradientReversalFunction.apply(x, self.scale) 44 | 45 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/core_scripts/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/config_parse/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/core_scripts/config_parse/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/config_parse/config_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config_parse 4 | 5 | Configuration parser 6 | 7 | """ 8 | from __future__ import absolute_import 9 | 10 | import os 11 | import sys 12 | import configparser 13 | 14 | import core_scripts.other_tools.list_tools as nii_list_tools 15 | import core_scripts.other_tools.display as nii_display 16 | 17 | __author__ = "Xin Wang" 18 | __email__ = "wangxin@nii.ac.jp" 19 | __copyright__ = "Copyright 2020, Xin Wang" 20 | 21 | 22 | class ConfigParse: 23 | """ ConfigParse 24 | class to parse input configuration file 25 | 26 | 27 | """ 28 | def __init__(self, config_path): 29 | """ initialization 30 | """ 31 | # get configuration path 32 | self.m_config_path = None 33 | if os.path.isfile(config_path): 34 | self.m_config_path = config_path 35 | else: 36 | nii_display.f_die("Cannot find %s" % (config_path), 'error') 37 | 38 | # path configuration file 39 | self.m_config = self.f_parse() 40 | if self.m_config is None: 41 | nii_display.f_die("Fail to parse %s" % (config_path), 'error') 42 | 43 | # done 44 | return 45 | 46 | def f_parse(self): 47 | """ f_parse 48 | parse the configuration file 49 | """ 50 | if self.m_config_path is not None: 51 | tmp_config = configparser.ConfigParser() 52 | tmp_config.read(self.m_config_path) 53 | return tmp_config 54 | else: 55 | nii_display.f_print("No config file provided", 'error') 56 | return None 57 | 58 | def f_retrieve(self, keyword, section_name=None, config_type=None): 59 | """ f_retrieve(self, keyword, section_name=None, config_type=None) 60 | retrieve the keyword from config file 61 | 62 | Return: 63 | value: string, int, float 64 | 65 | Parameters: 66 | keyword: 'keyword' to be retrieved 67 | section: which section is this keyword in the config. 68 | None will search all the config sections and 69 | return the first 70 | config_type: which can be 'int', 'float', or None. 71 | None will return the value as a string 72 | """ 73 | tmp_value = None 74 | if section_name is None: 75 | # if section is not given, search all the sections 76 | for section_name in self.m_config.sections(): 77 | tmp_value = self.f_retrieve(keyword, section_name, \ 78 | config_type) 79 | if tmp_value is not None: 80 | break 81 | elif section_name in self.m_config.sections() or \ 82 | section_name == 'DEFAULT': 83 | tmp_sec = self.m_config[section_name] 84 | # search a specific section 85 | if config_type == 'int': 86 | tmp_value = tmp_sec.getint(keyword, fallback=None) 87 | elif config_type == 'float': 88 | tmp_value = tmp_sec.getfloat(keyword, fallback=None) 89 | elif config_type == 'bool': 90 | tmp_value = tmp_sec.getboolean(keyword, fallback=None) 91 | else: 92 | tmp_value = tmp_sec.get(keyword, fallback=None) 93 | else: 94 | nii_display.f_die("Unknown section %s" % (section_name)) 95 | return tmp_value 96 | 97 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/core_scripts/data_io/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config.py 4 | 5 | Configurations for data_io 6 | 7 | """ 8 | from __future__ import absolute_import 9 | 10 | import os 11 | import sys 12 | import numpy as np 13 | import torch 14 | import torch.utils.data 15 | 16 | __author__ = "Xin Wang" 17 | __email__ = "wangxin@nii.ac.jp" 18 | __copyright__ = "Copyright 2020, Xin Wang" 19 | 20 | # --------------------------- 21 | # Numerical configuration 22 | # --------------------------- 23 | # data type for host 24 | h_dtype = np.float32 25 | # data type string format for numpy 26 | h_dtype_str = ' [3,1,2, 6,5,4] if block size =3 8 | """ 9 | 10 | from __future__ import absolute_import 11 | 12 | import os 13 | import sys 14 | import numpy as np 15 | 16 | import torch 17 | import torch.utils.data 18 | import torch.utils.data.sampler as torch_sampler 19 | 20 | import core_scripts.math_tools.random_tools as nii_rand_tk 21 | import core_scripts.other_tools.display as nii_warn 22 | 23 | __author__ = "Xin Wang" 24 | __email__ = "wangxin@nii.ac.jp" 25 | __copyright__ = "Copyright 2021, Xin Wang" 26 | 27 | # name of the sampler 28 | g_str_sampler_bsbl = 'block_shuffle_by_length' 29 | 30 | ############################################### 31 | # Sampler definition 32 | ############################################### 33 | 34 | class SamplerBlockShuffleByLen(torch_sampler.Sampler): 35 | """ Sampler with block shuffle based on sequence length 36 | e.g., data length [1, 2, 3, 4, 5, 6] -> [3,1,2, 6,5,4] if block size =3 37 | """ 38 | def __init__(self, buf_dataseq_length, batch_size): 39 | """ SamplerBlockShuffleByLength(buf_dataseq_length, batch_size) 40 | args 41 | ---- 42 | buf_dataseq_length: list or np.array of int, 43 | length of each data in a dataset 44 | batch_size: int, batch_size 45 | """ 46 | if batch_size == 1: 47 | mes = "Sampler block shuffle by length requires batch-size>1" 48 | nii_warn.f_die(mes) 49 | 50 | # hyper-parameter, just let block_size = batch_size * 3 51 | self.m_block_size = batch_size * 4 52 | # idx sorted based on sequence length 53 | self.m_idx = np.argsort(buf_dataseq_length) 54 | return 55 | 56 | def __iter__(self): 57 | """ Return a iterator to be iterated. 58 | """ 59 | tmp_list = list(self.m_idx.copy()) 60 | 61 | # shuffle within each block 62 | # e.g., [1,2,3,4,5,6], block_size=3 -> [3,1,2,5,4,6] 63 | nii_rand_tk.f_shuffle_in_block_inplace(tmp_list, self.m_block_size) 64 | 65 | # shuffle blocks 66 | # e.g., [3,1,2,5,4,6], block_size=3 -> [5,4,6,3,1,2] 67 | nii_rand_tk.f_shuffle_blocks_inplace(tmp_list, self.m_block_size) 68 | 69 | # return a iterator, list is iterable but not a iterator 70 | # https://www.programiz.com/python-programming/iterator 71 | return iter(tmp_list) 72 | 73 | 74 | def __len__(self): 75 | """ Sampler requires __len__ 76 | https://pytorch.org/docs/stable/data.html#torch.utils.data.Sampler 77 | """ 78 | return len(self.m_idx) 79 | 80 | if __name__ == "__main__": 81 | print("Definition of customized_sampler") 82 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/seq_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | seq_info 4 | 5 | A class to log the information for one sample. 6 | This data sequence could be one segment within a long utterance 7 | 8 | """ 9 | from __future__ import absolute_import 10 | 11 | import os 12 | import sys 13 | 14 | __author__ = "Xin Wang" 15 | __email__ = "wangxin@nii.ac.jp" 16 | __copyright__ = "Copyright 2020, Xin Wang" 17 | 18 | 19 | class SeqInfo(): 20 | """ Definition of sequence information 21 | Save the information about one utterance (which may be a trunck from 22 | the original data utterance) 23 | """ 24 | def __init__(self, 25 | length = 0, 26 | seq_name = '', 27 | seg_idx = 0, 28 | start_pos = 0, 29 | info_id = 0): 30 | """ 31 | Args: 32 | length: length this utterance segment 33 | seq_name: name of the utterance 34 | seg_idx: idx of this segment in the original utterance 35 | start_pos: from which step does this segment start in the 36 | original utterance 37 | info_id: idx of this seq segment in training set 38 | """ 39 | self.length = int(length) 40 | self.seq_name = seq_name 41 | self.seg_idx = seg_idx 42 | self.start_pos = int(start_pos) 43 | self.info_id = info_id 44 | 45 | 46 | def print_to_dic(self): 47 | """ 48 | Print to dictionary format in order to dump 49 | """ 50 | return {"length": self.length, 51 | "seq_name": self.seq_name, 52 | "seg_idx": self.seg_idx, 53 | "start_pos": self.start_pos, 54 | "info_id": self.info_id} 55 | 56 | def load_from_dic(self, dic): 57 | """ 58 | Load seq informaiton from dictionary 59 | """ 60 | try: 61 | self.length = dic["length"] 62 | self.seq_name = dic["seq_name"] 63 | self.seg_idx = dic["seg_idx"] 64 | self.start_pos = dic["start_pos"] 65 | self.info_id = dic["info_id"] 66 | except KeyError: 67 | nii_warn.f_die("Seq infor %s invalid" % str(dic)) 68 | 69 | def print_to_str(self): 70 | """ 71 | Print infor to str 72 | """ 73 | temp = "{:d},{},{:d},{:d},{:d}".format(self.info_id, \ 74 | self.seq_name, \ 75 | self.seg_idx, \ 76 | self.length, \ 77 | self.start_pos) 78 | return temp 79 | 80 | def parse_from_str(self, input_str): 81 | """ 82 | Parse a input string (which should be generated from print_to_str) 83 | """ 84 | temp = input_str.split(',') 85 | self.seq_name = temp[1] 86 | try: 87 | self.info_id = int(temp[0]) 88 | self.seg_idx = int(temp[2]) 89 | self.length = int(temp[3]) 90 | self.start_pos = int(temp[4]) 91 | except ValueError: 92 | nii_warn.f_die("Seq infor cannot parse {}".format(input_str)) 93 | return 94 | 95 | def seq_length(self): 96 | return self.length 97 | 98 | def seq_tag(self): 99 | return self.seq_name 100 | 101 | def seq_start_pos(self): 102 | return self.start_pos 103 | 104 | ############ 105 | ### Util to parse the output from print_to_str 106 | ############ 107 | 108 | def parse_length(input_str): 109 | return int(input_str.split(',')[3]) 110 | 111 | def parse_filename(input_str): 112 | return input_str.split(',')[1] 113 | 114 | 115 | if __name__ == "__main__": 116 | print("Definition of seq_info class") 117 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/text_process/text_io.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Simple converted to convert text string into indices 4 | Used for text-to-speech synthesis 5 | 6 | Based on https://github.com/fatchord/WaveRNN 7 | """ 8 | 9 | import os 10 | import sys 11 | import re 12 | import numpy as np 13 | 14 | from core_scripts.other_tools import display as nii_warn 15 | from core_scripts.data_io.text_process import toolkit_all 16 | from core_scripts.data_io.text_process import toolkit_en 17 | from core_scripts.other_tools import str_tools as nii_str_tk 18 | from core_scripts.data_io import conf as nii_dconf 19 | 20 | __author__ = "Xin Wang" 21 | __email__ = "wangxin@nii.ac.jp" 22 | __copyright__ = "Copyright 2021, Xin Wang" 23 | 24 | def text2code(text, flag_lang='EN'): 25 | """ Convert text string into code indices 26 | 27 | input 28 | ----- 29 | text: string 30 | flag_lang: string, 'EN': English 31 | 32 | output 33 | ------ 34 | code_seq: list of integers 35 | """ 36 | code_seq = [] 37 | 38 | # parse the curly bracket 39 | text_trunks = toolkit_all.parse_curly_bracket(text) 40 | 41 | # parse 42 | if flag_lang == 'EN': 43 | # English text 44 | for text_trunk in text_trunks: 45 | code_seq += toolkit_en.text2code(text_trunk) 46 | else: 47 | # unsupporte languages 48 | nii_warn.f_die("Error: text2code cannot handle {:s}".format(flag_lang)) 49 | 50 | # convert to numpy format 51 | code_seq = np.array(code_seq, dtype=nii_dconf.h_dtype) 52 | 53 | return code_seq 54 | 55 | def code2text(codes, flag_lang='EN'): 56 | """ Convert text string into code indices 57 | 58 | input 59 | ----- 60 | code_seq: numpy arrays of integers 61 | flag_lang: string, 'EN': English 62 | 63 | output 64 | ------ 65 | text: string 66 | """ 67 | # convert numpy array backto indices 68 | codes_tmp = [int(x) for x in codes] 69 | 70 | output_text = '' 71 | if flag_lang == 'EN': 72 | output_text = toolkit_en.code2text(codes_tmp) 73 | else: 74 | nii_warn.f_die("Error: code2text cannot handle {:s}".format(flag_lang)) 75 | return output_text 76 | 77 | def symbol_num(flag_lang='EN'): 78 | """ Return the number of symbols defined for one language 79 | 80 | input 81 | ----- 82 | flag_lange: string, 'EN': English 83 | 84 | output 85 | ------ 86 | integer 87 | """ 88 | if flag_lang == 'EN': 89 | return toolkit_en.symbol_num() 90 | else: 91 | nii_warn.f_die("Error: symbol_num cannot handle {:s}".format(flag_lang)) 92 | return 0 93 | 94 | def textloader(file_path, flag_lang='EN'): 95 | """ Load text and return the sybmol sequences 96 | input 97 | ----- 98 | file_path: string, absolute path to the text file 99 | flag_lang: string, 'EN' by default, the language option to process text 100 | 101 | output 102 | ------ 103 | output: np.array of shape (L), where L is the number of chars 104 | """ 105 | # load lines and chop '\n', join into one line 106 | text_buffer = [nii_str_tk.string_chop(x) for x in open(file_path, 'r')] 107 | text_buffer = ' '.join(text_buffer) 108 | 109 | # convert to indices 110 | return text2code(text_buffer, flag_lang) 111 | 112 | 113 | if __name__ == "__main__": 114 | print("Definition of text2code tools") 115 | text = 'hello we are {AY2 AY2} the same 123' 116 | indices = text2code(text) 117 | text2 = code2text(indices) 118 | print(text) 119 | print(indices) 120 | print(text2) 121 | 122 | print(code2text(textloader('./tmp.txt'))) 123 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/text_process/tmp.txt: -------------------------------------------------------------------------------- 1 | This is a test file. 2 | That will happen in one day. 3 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/data_io/text_process/toolkit_all.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Simple text processer for all languages 4 | 5 | Based on https://github.com/fatchord/WaveRNN 6 | """ 7 | 8 | import os 9 | import sys 10 | import re 11 | 12 | __author__ = "Xin Wang" 13 | __email__ = "wangxin@nii.ac.jp" 14 | __copyright__ = "Copyright 2021, Xin Wang" 15 | 16 | ##### 17 | ## Parse the curly bracket 18 | ##### 19 | 20 | # from https://github.com/fatchord/WaveRNN 21 | _curly_re = re.compile(r'(.*?)\{(.+?)\}(.*)') 22 | 23 | # symbol to indicate phonemic annotation 24 | _curly_symbol = '{' 25 | 26 | def parse_curly_bracket(text): 27 | """ Prase the text based on curly brackets 28 | Inspired by https://github.com/fatchord/WaveRNN: when input text 29 | is mixed with raw text and phonemic annotation, the {} pair indicates 30 | the phonemic part 31 | 32 | input 33 | ----- 34 | text: str 35 | 36 | output 37 | ------ 38 | text_list: list of str 39 | 40 | For example, 'text {AH II} test' -> ['text ', 'AH II', ' test'] 41 | """ 42 | text_list = [] 43 | text_tmp = text 44 | 45 | while len(text_tmp): 46 | re_matched = _curly_re.match(text_tmp) 47 | 48 | if re_matched: 49 | # e.g., 'text {AH II} test' 50 | # group(1), group(2) -> ['text ', 'AH II'] 51 | text_list.append(re_matched.group(1)) 52 | text_list.append(_curly_symbol + re_matched.group(2)) 53 | # group(3) -> ' test' 54 | text_tmp = re_matched.group(3) 55 | else: 56 | text_list.append(text_tmp) 57 | break 58 | return text_list 59 | 60 | 61 | if __name__ == "__main__": 62 | print("Definition of text processing tools for all languages") 63 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/math_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/core_scripts/math_tools/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/op_manager/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config.py 4 | 5 | Default configurations for optimizer 6 | 7 | Note: these default configs only apply when input argument 8 | doesn't specify the parameters 9 | 10 | """ 11 | from __future__ import absolute_import 12 | 13 | import os 14 | import sys 15 | 16 | __author__ = "Xin Wang" 17 | __email__ = "wangxin@nii.ac.jp" 18 | __copyright__ = "Copyright 2020, Xin Wang" 19 | 20 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/op_manager/lr_scheduler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | op_manager 4 | 5 | A simple wrapper to create lr scheduler 6 | 7 | """ 8 | from __future__ import absolute_import 9 | 10 | import os 11 | import sys 12 | import numpy as np 13 | import torch 14 | import torch.optim as torch_optim 15 | import torch.optim.lr_scheduler as torch_optim_steplr 16 | 17 | import core_scripts.other_tools.display as nii_warn 18 | 19 | __author__ = "Xin Wang" 20 | __email__ = "wangxin@nii.ac.jp" 21 | __copyright__ = "Copyright 2020, Xin Wang" 22 | 23 | 24 | 25 | class LRScheduler(): 26 | """ Wrapper over different types of learning rate Scheduler 27 | 28 | """ 29 | def __init__(self, optimizer, args): 30 | 31 | # learning rate decay 32 | self.lr_decay = args.lr_decay_factor 33 | 34 | # lr scheduler type 35 | # please check arg_parse.py for the number ID 36 | self.lr_scheduler_type = args.lr_scheduler_type 37 | 38 | # patentience for ReduceLROnPlateau 39 | self.lr_patience = 5 40 | 41 | # step size for stepLR 42 | self.lr_stepLR_size = 10 43 | 44 | if self.lr_decay > 0: 45 | if self.lr_scheduler_type == 1: 46 | # StepLR 47 | self.lr_scheduler = torch.optim.lr_scheduler.StepLR( 48 | optimizer=optimizer, step_size=self.lr_stepLR_size, 49 | gamma=self.lr_decay) 50 | else: 51 | # by default, ReduceLROnPlateau 52 | if args.no_best_epochs < 0: 53 | self.lr_patience = 5 54 | nii_warn.f_print("--no-best-epochs is set to 5 ") 55 | nii_warn.f_print("for learning rate decaying") 56 | 57 | self.lr_scheduler = torch_optim_steplr.ReduceLROnPlateau( 58 | optimizer=optimizer, factor=self.lr_decay, 59 | patience=self.lr_patience) 60 | 61 | self.flag = True 62 | else: 63 | self.lr_scheduler = None 64 | self.flag =False 65 | return 66 | 67 | def f_valid(self): 68 | """ Whether this LR scheduler is valid 69 | """ 70 | return self.flag 71 | 72 | def f_print_info(self): 73 | """ Print information about the LR scheduler 74 | """ 75 | if not self.flag: 76 | mes = "" 77 | else: 78 | if self.lr_scheduler_type == 1: 79 | mes = "\n LR scheduler, StepLR [gamma %f, step %d]" % ( 80 | self.lr_decay, self.lr_stepLR_size) 81 | else: 82 | mes = "\n LR scheduler, ReduceLROnPlateau " 83 | mes += "[decay %f, patience %d]" % ( 84 | self.lr_decay, self.lr_patience) 85 | return mes 86 | 87 | def f_last_lr(self): 88 | """ Return the last lr 89 | """ 90 | if self.f_valid(): 91 | if hasattr(self.lr_scheduler, "get_last_lr"): 92 | return self.lr_scheduler.get_last_lr() 93 | else: 94 | return self.lr_scheduler._last_lr 95 | else: 96 | return [] 97 | 98 | def f_load_state_dict(self, state): 99 | if self.f_valid(): 100 | self.lr_scheduler.load_state_dict(state) 101 | return 102 | 103 | def f_state_dict(self): 104 | if self.f_valid(): 105 | return self.lr_scheduler.state_dict() 106 | else: 107 | return None 108 | 109 | def f_step(self, loss_val): 110 | if self.f_valid(): 111 | if self.lr_scheduler_type == 1: 112 | self.lr_scheduler.step() 113 | else: 114 | self.lr_scheduler.step(loss_val) 115 | return 116 | 117 | def f_allow_early_stopping(self): 118 | if self.f_valid(): 119 | if self.lr_scheduler_type == 1: 120 | return True 121 | else: 122 | # ReduceLROnPlateau no need to use early stopping 123 | return False 124 | else: 125 | return True 126 | 127 | 128 | if __name__ == "__main__": 129 | print("Definition of lr_scheduler") 130 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/op_manager/op_display_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | op_display_tools 4 | 5 | Functions to print/display the training/inference information 6 | 7 | """ 8 | from __future__ import print_function 9 | import os 10 | import sys 11 | import numpy as np 12 | 13 | import core_scripts.other_tools.display as nii_display 14 | 15 | __author__ = "Xin Wang" 16 | __email__ = "wangxin@nii.ac.jp" 17 | __copyright__ = "Copyright 2020, Xin Wang" 18 | 19 | 20 | def print_gen_info(seq_name, time): 21 | """ Print the information during inference 22 | """ 23 | mes = "Generating {}, time: {:.3f}s".format(seq_name, time) 24 | nii_display.f_print_message(mes) 25 | return mes + '\n' 26 | 27 | def _print_loss(loss_array): 28 | mes = "" 29 | if loss_array.shape[0] == 1: 30 | mes += "%12.4f " % (loss_array[0]) 31 | else: 32 | mes = [] 33 | for data in loss_array: 34 | mes.append('%6.2f' % (data)) 35 | mes = ' '.join(mes) 36 | mes += "| " 37 | return mes 38 | 39 | def print_train_info(epoch, time_tr, loss_tr, time_val, 40 | loss_val, isbest, lr_info): 41 | """ Print the information during training 42 | """ 43 | mes = "{:>7d} | ".format(epoch) 44 | mes = mes + "{:>12.1f} | ".format(time_tr + time_val) 45 | mes += _print_loss(loss_tr) 46 | mes += _print_loss(loss_val) 47 | #mes = mes + "{:>12.4f} | ".format(loss_tr) 48 | #mes = mes + "{:>12.4f} | ".format(loss_val) 49 | if isbest: 50 | mes = mes + "{:>5s}".format("yes") 51 | else: 52 | mes = mes + "{:>5s}".format("no") 53 | if lr_info: 54 | mes = mes + lr_info 55 | nii_display.f_print_message(mes, flush=True) 56 | return mes + '\n' 57 | 58 | def print_log_head(): 59 | """ Print the head information 60 | """ 61 | nii_display.f_print_message("{:->62s}".format("")) 62 | mes = "{:>7s} | ".format("Epoch") 63 | mes = mes + "{:>12s} | ".format("Duration(s)") 64 | mes = mes + "{:>12s} | ".format("Train loss") 65 | mes = mes + "{:>12s} | ".format("Dev loss") 66 | mes = mes + "{:>5s}".format("Best") 67 | nii_display.f_print_message(mes) 68 | nii_display.f_print_message("{:->62s}".format(""), flush=True) 69 | return mes + '\n' 70 | 71 | def print_log_tail(): 72 | """ Print the tail line 73 | """ 74 | nii_display.f_print_message("{:->62s}".format("")) 75 | return 76 | 77 | 78 | if __name__ == "__main__": 79 | print("Op_display_tools") 80 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/op_manager/op_manager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | op_manager 4 | 5 | A simple wrapper to create optimizer 6 | 7 | """ 8 | from __future__ import absolute_import 9 | 10 | import os 11 | import sys 12 | import numpy as np 13 | import torch 14 | import torch.optim as torch_optim 15 | import torch.optim.lr_scheduler as torch_optim_steplr 16 | 17 | 18 | import core_scripts.other_tools.list_tools as nii_list_tools 19 | import core_scripts.other_tools.display as nii_warn 20 | import core_scripts.other_tools.str_tools as nii_str_tk 21 | import core_scripts.op_manager.conf as nii_op_config 22 | import core_scripts.op_manager.op_process_monitor as nii_op_monitor 23 | import core_scripts.op_manager.lr_scheduler as nii_lr_scheduler 24 | 25 | __author__ = "Xin Wang" 26 | __email__ = "wangxin@nii.ac.jp" 27 | __copyright__ = "Copyright 2020, Xin Wang" 28 | 29 | 30 | class OptimizerWrapper(): 31 | """ Wrapper over optimizer 32 | """ 33 | def __init__(self, model, args): 34 | """ Initialize an optimizer over model.parameters() 35 | """ 36 | # check valildity of model 37 | if not hasattr(model, "parameters"): 38 | nii_warn.f_print("model is not torch.nn", "error") 39 | nii_warn.f_die("Error in creating OptimizerWrapper") 40 | 41 | # set optimizer type 42 | self.op_flag = args.optimizer 43 | self.lr = args.lr 44 | self.l2_penalty = args.l2_penalty 45 | 46 | # grad clip norm is directly added in nn_manager 47 | self.grad_clip_norm = args.grad_clip_norm 48 | 49 | # create optimizer 50 | if self.op_flag == "Adam": 51 | if self.l2_penalty > 0: 52 | self.optimizer = torch_optim.Adam(model.parameters(), 53 | lr=self.lr, 54 | weight_decay=self.l2_penalty) 55 | else: 56 | self.optimizer = torch_optim.Adam(model.parameters(), 57 | lr=self.lr) 58 | 59 | else: 60 | nii_warn.f_print("%s not availabel" % (self.op_flag), 61 | "error") 62 | nii_warn.f_die("Please change optimizer") 63 | 64 | # number of epochs 65 | self.epochs = args.epochs 66 | self.no_best_epochs = args.no_best_epochs 67 | 68 | # lr scheduler 69 | self.lr_scheduler = nii_lr_scheduler.LRScheduler(self.optimizer, args) 70 | return 71 | 72 | def print_info(self): 73 | """ print message of optimizer 74 | """ 75 | mes = "Optimizer:\n Type: {} ".format(self.op_flag) 76 | mes += "\n Learing rate: {:2.6f}".format(self.lr) 77 | mes += "\n Epochs: {:d}".format(self.epochs) 78 | mes += "\n No-best-epochs: {:d}".format(self.no_best_epochs) 79 | if self.lr_scheduler.f_valid(): 80 | mes += self.lr_scheduler.f_print_info() 81 | if self.l2_penalty > 0: 82 | mes += "\n With weight penalty {:f}".format(self.l2_penalty) 83 | if self.grad_clip_norm > 0: 84 | mes += "\n With grad clip norm {:f}".format(self.grad_clip_norm) 85 | nii_warn.f_print_message(mes) 86 | 87 | def get_epoch_num(self): 88 | return self.epochs 89 | 90 | def get_no_best_epoch_num(self): 91 | return self.no_best_epochs 92 | 93 | def get_lr_info(self): 94 | 95 | if self.lr_scheduler.f_valid(): 96 | # no way to look into the updated lr rather than using _last_lr 97 | tmp = '' 98 | for updated_lr in self.lr_scheduler.f_last_lr(): 99 | if np.abs(self.lr - updated_lr) > 0.0000001: 100 | tmp += "{:.2e} ".format(updated_lr) 101 | if tmp: 102 | tmp = " LR -> " + tmp 103 | return tmp 104 | else: 105 | return None 106 | 107 | if __name__ == "__main__": 108 | print("Optimizer Wrapper") 109 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/other_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/core_scripts/other_tools/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/other_tools/display.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | dispaly.py 4 | 5 | Tools to display the commands or warnings 6 | 7 | """ 8 | from __future__ import absolute_import 9 | from __future__ import print_function 10 | 11 | import os 12 | import sys 13 | import datetime 14 | 15 | __author__ = "Xin Wang" 16 | __email__ = "wangxin@nii.ac.jp" 17 | __copyright__ = "Copyright 2020, Xin Wang" 18 | 19 | 20 | class DisplayColors: 21 | HEADER = '\033[95m' 22 | OKBLUE = '\033[94m' 23 | OKGREEN = '\033[92m' 24 | WARNING = '\033[91m' 25 | FAIL = '\033[91m' 26 | ENDC = '\033[0m' 27 | BOLD = '\033[1m' 28 | UNDERLINE = '\033[4m' 29 | 30 | def f_print(message, opt='ok', end='\n', flush=False): 31 | """ f_print(message, opt) 32 | Print message with specific style 33 | 34 | Args: 35 | message: str 36 | opt: str, "warning", "highlight", "ok", "error" 37 | """ 38 | if opt == 'warning': 39 | print(DisplayColors.WARNING + str(message) + DisplayColors.ENDC, 40 | flush = flush, end = end) 41 | elif opt == 'highlight': 42 | print(DisplayColors.OKGREEN + str(message) + DisplayColors.ENDC, 43 | flush = flush, end = end) 44 | elif opt == 'ok': 45 | print(DisplayColors.OKBLUE + str(message) + DisplayColors.ENDC, 46 | flush = flush, end = end) 47 | elif opt == 'error': 48 | print(DisplayColors.FAIL + str(message) + DisplayColors.ENDC, 49 | flush = flush, end = end) 50 | else: 51 | print(message, flush=flush, end=end) 52 | return 53 | 54 | def f_print_w_date(message, level='h'): 55 | """ f_print_w_date(message, level) 56 | 57 | Print message with date shown 58 | 59 | Args: 60 | message: a string 61 | level: which can be 'h' (high-level), 'm' (middle-level), 'l' (low-level) 62 | """ 63 | if level == 'h': 64 | message = '--- ' + str(message) + ' ' \ 65 | + str(datetime.datetime.now()) + ' ---' 66 | tmp = ''.join(['-' for x in range(len(message))]) 67 | f_print(tmp) 68 | f_print(message) 69 | f_print(tmp) 70 | elif level == 'm': 71 | f_print('---' + str(message) + ' ' \ 72 | + str(datetime.datetime.now().time()) + '---') 73 | else: 74 | f_print(str(message) + ' ' + str(datetime.datetime.now().time())) 75 | sys.stdout.flush() 76 | return 77 | 78 | def f_die(message): 79 | """ f_die(message) 80 | Print message in "error" mode and exit program with sys.exit(1) 81 | """ 82 | f_print("Error: " + message, 'error') 83 | sys.exit(1) 84 | 85 | 86 | def f_eprint(*args, **kwargs): 87 | """ f_eprint(*args, **kwargs) 88 | Print 89 | """ 90 | print(*args, file=sys.stderr, **kwargs) 91 | 92 | def f_print_message(message, flush=False, end='\n'): 93 | f_print(message, 'normal', flush=flush, end=end) 94 | 95 | if __name__ == "__main__": 96 | pass 97 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/other_tools/random_name_mgn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Random name manager 4 | 5 | Used for produce protocols 6 | """ 7 | from __future__ import absolute_import 8 | 9 | import os 10 | import sys 11 | from core_scripts.other_tools import list_tools 12 | from core_scripts.data_io import io_tools 13 | 14 | __author__ = "Xin Wang" 15 | __email__ = "wangxin@nii.ac.jp" 16 | __copyright__ = "Copyright 2021, Xin Wang" 17 | 18 | def list_loader(list_file): 19 | """ output_list = list_loader(list_file) 20 | Load a text file as a list of string. This function will use __cache to save 21 | the loaded list 22 | 23 | Args: 24 | list_file: str, path to the input text file 25 | Return: 26 | output_list: list, 27 | 28 | Note, a __cache will be created along list_file 29 | """ 30 | cache_dir = os.path.join(os.path.dirname(list_file), '__cache') 31 | return io_tools.wrapper_data_load_with_cache( 32 | list_file, list_tools.read_list_from_text, cache_dir) 33 | 34 | class RandomNameMgn: 35 | """ Class to manage the list of random file names 36 | """ 37 | def __init__(self, file_random_name_list, verbose=False): 38 | """ RandomNameMgn(file_random_name_list, verbose=False) 39 | Create a random name manager 40 | 41 | Args: 42 | file_random_name_list: str, path to the text file of random names. 43 | verbose: bool, default False, print information during initialziation 44 | """ 45 | if verbose: 46 | print("Loading random name tables") 47 | 48 | ## For unused random name list 49 | # load entries in the list 50 | self.unused_entries = list_loader(file_random_name_list) 51 | # prepare dictionary 52 | self.mapper = {x : None for x in self.unused_entries} 53 | # reverse dictionary 54 | self.mapper_rev = {} 55 | 56 | # print some informaiton 57 | if verbose: 58 | self.print_info() 59 | 60 | self.verbose = verbose 61 | # done 62 | return 63 | 64 | def print_info(self): 65 | mes = "Number of unused random file names: {:d}".format( 66 | len(self.unused_entries)) 67 | print(mes) 68 | return 69 | 70 | def retrieve_rand_name(self, filename): 71 | """ rand_name = retrieve_rand_name(filename) 72 | 73 | filename: str, input, input file name 74 | rand_name: str, output, the random file name 75 | """ 76 | if filename in self.mapper_rev: 77 | return self.mapper_rev[filename] 78 | else: 79 | rand_name = self.unused_entries.pop() 80 | self.mapper[rand_name] = filename 81 | self.mapper_rev[filename]= rand_name 82 | return rand_name 83 | 84 | def save_unused_name(self, save_file): 85 | """ save_unused_name(save_file) 86 | 87 | save_file: str, input, the path to save random names that 88 | have NOT been used 89 | """ 90 | with open(save_file, 'w') as file_ptr: 91 | for entry in self.unused_entries: 92 | file_ptr.write(entry+'\n') 93 | 94 | if self.verbose: 95 | self.print_info() 96 | print("Save unused random names to {:s}".format(save_file)) 97 | return 98 | 99 | def retrieve_filename(self, random_name): 100 | if random_name in self.mapper: 101 | return self.mapper[random_name] 102 | else: 103 | print("Random name {:s} has not been logged".format(random_name)) 104 | sys.exit(1) 105 | 106 | if __name__ == "__main__": 107 | print("") 108 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/other_tools/script_model_para.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A simple wrapper to show parameter of the model 4 | 5 | Usage: 6 | # go to the model directory, then 7 | $: python script_model_para.py 8 | 9 | We assume model.py and config.py are available in the project directory. 10 | 11 | """ 12 | 13 | from __future__ import print_function 14 | import os 15 | import sys 16 | import numpy as np 17 | import torch 18 | import torch.nn as nn 19 | import torch.nn.functional as F 20 | import importlib 21 | 22 | __author__ = "Xin Wang" 23 | __email__ = "wangxin@nii.ac.jp" 24 | __copyright__ = "Copyright 2020, Xin Wang" 25 | 26 | 27 | def f_model_show(pt_model): 28 | """ 29 | f_model_show(pt_model) 30 | Args: pt_model, a Pytorch model 31 | 32 | Print the informaiton of the model 33 | """ 34 | #f_model_check(pt_model) 35 | 36 | print(pt_model) 37 | num = sum(p.numel() for p in pt_model.parameters() if p.requires_grad) 38 | print("Parameter number: {:d}".format(num)) 39 | for name, p in pt_model.named_parameters(): 40 | if p.requires_grad: 41 | print("Layer: {:s}\tPara. num: {:<10d} ({:02.1f}%)\tShape: {:s}"\ 42 | .format(name, p.numel(), p.numel()*100.0/num, str(p.shape))) 43 | return 44 | 45 | 46 | if __name__ == "__main__": 47 | 48 | sys.path.insert(0, os.getcwd()) 49 | 50 | if len(sys.argv) == 3: 51 | prj_model = importlib.import_module(sys.argv[1]) 52 | prj_conf = importlib.import_module(sys.argv[2]) 53 | else: 54 | print("By default, load model.py and config.py") 55 | prj_model = importlib.import_module("model") 56 | prj_conf = importlib.import_module("config") 57 | 58 | input_dims = sum(prj_conf.input_dims) 59 | output_dims = sum(prj_conf.output_dims) 60 | 61 | model = prj_model.Model(input_dims, output_dims, None) 62 | f_model_show(model) 63 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/other_tools/str_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | str_tools 4 | 5 | tools to process string 6 | """ 7 | from __future__ import absolute_import 8 | 9 | import os 10 | import sys 11 | 12 | __author__ = "Xin Wang" 13 | __email__ = "wangxin@nii.ac.jp" 14 | __copyright__ = "Copyright 2020, Xin Wang" 15 | 16 | 17 | def f_realpath(f_dir, f_name, f_ext): 18 | """ file_path = f_realpath(f_dir, f_name, f_ext) 19 | Args: 20 | f_dir: string, directory 21 | f_name: string, file name 22 | f_ext: string, file name extension 23 | 24 | Return: 25 | file_path: realpath 26 | """ 27 | file_path = os.path.join(f_dir, f_name) 28 | if f_ext.startswith(os.extsep): 29 | file_path = file_path + f_ext 30 | else: 31 | file_path = file_path + os.extsep + f_ext 32 | return file_path 33 | 34 | def string_chop(InStr): 35 | """ output = string_chop(InStr) 36 | Chop the ending '\r' and '\n' from input string 37 | 38 | Args: 39 | InStr: str, the input string 40 | 41 | Return: 42 | output: str 43 | 44 | '\r' corresponds to '0x0d' or 13, 45 | '\n' corresponds to '0x0a' or 10 46 | """ 47 | if len(InStr) >= 2 and ord(InStr[-1]) == 10 and ord(InStr[-2]) == 13: 48 | return InStr[:-2] 49 | elif len(InStr) >= 1 and ord(InStr[-1]) == 10: 50 | return InStr[:-1] 51 | else: 52 | return InStr 53 | 54 | if __name__ == "__main__": 55 | print("string tools") 56 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/core_scripts/startup_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | startup_config 4 | 5 | Startup configuration utilities 6 | 7 | """ 8 | from __future__ import absolute_import 9 | 10 | import os 11 | import sys 12 | import torch 13 | import importlib 14 | import random 15 | import numpy as np 16 | 17 | __author__ = "Xin Wang" 18 | __email__ = "wangxin@nii.ac.jp" 19 | __copyright__ = "Copyright 2020, Xin Wang" 20 | 21 | 22 | def set_random_seed(random_seed, args=None): 23 | """ set_random_seed(random_seed, args=None) 24 | 25 | Set the random_seed for numpy, python, and cudnn 26 | 27 | input 28 | ----- 29 | random_seed: integer random seed 30 | args: argue parser 31 | """ 32 | 33 | # initialization 34 | torch.manual_seed(random_seed) 35 | random.seed(random_seed) 36 | np.random.seed(random_seed) 37 | os.environ['PYTHONHASHSEED'] = str(random_seed) 38 | 39 | #For torch.backends.cudnn.deterministic 40 | #Note: this default configuration may result in RuntimeError 41 | #see https://pytorch.org/docs/stable/notes/randomness.html 42 | if args is None: 43 | cudnn_deterministic = True 44 | cudnn_benchmark = False 45 | else: 46 | cudnn_deterministic = args.cudnn_deterministic_toggle 47 | cudnn_benchmark = args.cudnn_benchmark_toggle 48 | 49 | if not cudnn_deterministic: 50 | print("cudnn_deterministic set to False") 51 | if cudnn_benchmark: 52 | print("cudnn_benchmark set to True") 53 | 54 | if torch.cuda.is_available(): 55 | torch.cuda.manual_seed_all(random_seed) 56 | torch.backends.cudnn.deterministic = cudnn_deterministic 57 | torch.backends.cudnn.benchmark = cudnn_benchmark 58 | return 59 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # if necessary, load conda environment 3 | eval "$(conda shell.bash hook)" 4 | conda activate pytorch-asvspoof2021 5 | 6 | # when running in ./projects/*/*, add this top directory 7 | # to python path 8 | export PYTHONPATH=$PWD/../../:$PYTHONPATH 9 | 10 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/env.yml: -------------------------------------------------------------------------------- 1 | name: pytorch-asvspoof2021 2 | channels: 3 | - defaults 4 | - pytorch 5 | - conda-forge 6 | - anaconda 7 | dependencies: 8 | - python=3.8 9 | - pytorch::pytorch=1.6 10 | - cudatoolkit=9.2 11 | - pytorch::torchvision=0.7.0 12 | - pytorch::torchaudio=0.6.0 13 | - scipy=1.4.1 14 | - numpy=1.18.1 15 | - conda-forge::libsndfile=1.0.31 16 | - conda-forge::pysoundfile 17 | - numba=0.48.0 18 | - librosa=0.8.0 19 | - mir_eval=0.6 20 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/00_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download toy data package and pre-trained models 4 | echo "=== Downloading toy dataset ===" 5 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABc-QK2BvzEPj-s8nBwCkMna/temp/asvspoof2021/toy_example.tar.gz 6 | cd DATA 7 | wget -q ${SRC} 8 | cd .. 9 | 10 | echo "=== Downloading pre-trained models ===" 11 | if [ -d baseline_DF ]; 12 | then 13 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_DF_LFCC-LCNN.zip 14 | wget -q ${SRC} 15 | if [ -f pre_trained_DF_LFCC-LCNN.zip ]; 16 | then 17 | unzip pre_trained_DF_LFCC-LCNN.zip 18 | #mv pre_trained_DF_LFCC-LCNN.pt df_trained_network.pt 19 | rm pre_trained_DF_LFCC-LCNN.zip 20 | fi 21 | 22 | if [ ! -f df_trained_network.pt ]; 23 | then 24 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABg4OUDKFvFonI-HmIzT5qIa/temp/asvspoof2021/df_trained_network.pt 25 | wget -q ${SRC} 26 | fi 27 | mv df_trained_network.pt baseline_DF/__pretrained/trained_network.pt 28 | fi 29 | 30 | if [ -d baseline_LA ]; 31 | then 32 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_LA_LFCC-LCNN.zip 33 | wget -q ${SRC} 34 | if [ -f pre_trained_LA_LFCC-LCNN.zip ]; 35 | then 36 | unzip pre_trained_LA_LFCC-LCNN.zip 37 | #mv pre_trained_LA_LFCC-LCNN.pt la_trained_network.pt 38 | rm pre_trained_LA_LFCC-LCNN.zip 39 | fi 40 | 41 | if [ ! -f la_trained_network.pt ]; 42 | then 43 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AADWOs9cmLBzWuRPbh5m10YVa/temp/asvspoof2021/la_trained_network.pt 44 | wget -q ${SRC} 45 | fi 46 | mv la_trained_network.pt baseline_LA/__pretrained/trained_network.pt 47 | fi 48 | 49 | if [ -d baseline_PA ]; 50 | then 51 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_PA_LFCC-LCNN.zip 52 | wget -q ${SRC} 53 | if [ -f pre_trained_PA_LFCC-LCNN.zip ]; 54 | then 55 | unzip pre_trained_PA_LFCC-LCNN.zip 56 | #mv pre_trained_PA_LFCC-LCNN.pt pa_trained_network.pt 57 | rm pre_trained_PA_LFCC-LCNN.zip 58 | fi 59 | 60 | if [ ! -f pa_trained_network.pt ]; 61 | then 62 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AACOBr0ymqsMA0rKctMxkKaxa/temp/asvspoof2021/pa_trained_network.pt 63 | wget -q ${SRC} 64 | fi 65 | mv pa_trained_network.pt baseline_PA/__pretrained/trained_network.pt 66 | fi 67 | 68 | echo "Download done" 69 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/01_wrapper_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script to quickly evaluate a evaluation set 4 | # 5 | # 00_toy_example.sh requires configuration of config.py, 6 | # which further requires preparation of test.lst 7 | # and protocol.txt. 8 | # 9 | # It is convenient when doing numerious experiments 10 | # on the same data set but troublesome when evaluating 11 | # different evaluationg sets. 12 | # 13 | # This script shows one example of quick evaluation using 14 | # lfcc-lcnn-lstm-sig_toy_example/02_eval_alternative.sh 15 | # 16 | # It will use DATA/toy_example/eval 17 | # It will call the evaluat set toy_eval 18 | # It will use __pretrained/trained_network.pt as pre-trained model 19 | # 20 | # (See Doc of 02_eval_alternative.sh for more details) 21 | # 22 | # Note that we don't need a protocol or meta labels. 23 | # 24 | ######################## 25 | 26 | # Load python environment 27 | bash conda.sh 28 | 29 | # We will use DATA/toy_example/eval as example 30 | cd DATA 31 | tar -xzf toy_example.tar.gz 32 | cd .. 33 | 34 | # Go to the folder 35 | cd baseline_LA 36 | 37 | # Run evaluation using pretrained model 38 | # bash 02_eval_alternative.sh PATH_TO_WAV_DIR NAME_OF_DATA_SET TRAINED_MODEL 39 | # For details, please check 02_eval_alternative.sh 40 | bash 02_eval_alternative.sh $PWD/../DATA/toy_example/eval toy_eval __pretrained/trained_network.pt 41 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/02_toy_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for toy_example 4 | # This script will 5 | # 1. install pytorch env using conda 6 | # 2. untar toy data set 7 | # 3. run evaluation and training process 8 | # 9 | # If GPU memory is less than 16GB, please reduce 10 | # --batch-size in 00_train.sh 11 | ######################## 12 | RED='\033[0;32m' 13 | NC='\033[0m' 14 | 15 | echo -e "\n${RED}=======================================================${NC}" 16 | echo -e "${RED}Step1. install conda environment${NC}" 17 | 18 | # create conda environment 19 | bash conda.sh 20 | 21 | # untar the toy-example data 22 | echo -e "\n${RED}=======================================================${NC}" 23 | echo -e "${RED}Step2. untar toy data set${NC}" 24 | 25 | cd DATA 26 | tar -xzf toy_example.tar.gz 27 | cd .. 28 | 29 | echo -e "\n${RED}=======================================================${NC}" 30 | echo -e "${RED}Step3. run evaluation process (using pre-trained model)${NC}" 31 | # run scripts 32 | 33 | cd baseline_LA 34 | # evaluation using pre-trained model 35 | bash 01_eval.sh 36 | 37 | echo -e "\n${RED}=======================================================${NC}" 38 | echo -e "${RED}Step4. run training process (start with pre-trained model)${NC}" 39 | #training, with pre-trained model as initialization 40 | bash 00_train.sh 41 | 42 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/99_del.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -r DATA/* 3 | rm baseline_*/__pretrained/* 4 | rm baseline_*/log* 5 | rm -r baseline_*/__pycache__ 6 | rm baseline_*/epoch* 7 | rm baseline_*/asv* 8 | rm baseline_*/*.pt 9 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/DATA/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/project/DATA/.gitkeep -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/baseline_LA/00_train.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. $: bash 00_train.sh > /dev/null 2>&1 & 7 | # 3. please check log_train and log_err to monitor the training 8 | # process 9 | # 10 | # Note: 11 | # 1. The script by default uses the pre-trained model from ASVspoof2019 12 | # If you don't want to use it, just delete the option --trained-model 13 | # 2. For options, check $: python main.py --help 14 | ######################## 15 | 16 | log_train_name=log_train 17 | log_err_name=log_err 18 | pretrained_model=__pretrained/trained_network.pt 19 | 20 | echo -e "Training" 21 | echo -e "Please monitor the log trainig: $PWD/${log_train_name}.txt\n" 22 | source $PWD/../../env.sh 23 | python main.py --model-forward-with-file-name \ 24 | --num-workers 3 --epochs 100 \ 25 | --no-best-epochs 50 --batch-size 64 \ 26 | --sampler block_shuffle_by_length \ 27 | --lr-decay-factor 0.5 --lr-scheduler-type 1 \ 28 | --trained-model ${pretrained_model} \ 29 | --ignore-training-history-in-trained-model \ 30 | --lr 0.0003 --seed 1000 > ${log_train_name}.txt 2>${log_err_name}.txt 31 | echo -e "Training process finished" 32 | echo -e "Trainig log has been written to $PWD/${log_train_name}.txt" 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/baseline_LA/01_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. please specify the trained model 7 | # here, we use a pre-trained model from ASVspoof2019 8 | # 2. $: bash 01_eval.sh 9 | ######################## 10 | 11 | log_name=log_eval 12 | trained_model=__pretrained/trained_network.pt 13 | 14 | echo -e "Run evaluation" 15 | source $PWD/../../env.sh 16 | python main.py --inference --model-forward-with-file-name \ 17 | --trained-model ${trained_model}> ${log_name}.txt 2>${log_name}_err.txt 18 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 19 | echo -e "Process log has been written to $PWD/${log_name}.txt" 20 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 21 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/baseline_LA/02_eval_alternative.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for quick evaluation 4 | # 01_eval.sh requires configuration of config.py, 5 | # which further requires preparation of test.lst 6 | # and protocol.txt. 7 | # 8 | # It is convenient when doing numerious experiments 9 | # on the same data set but troublesome when evaluating 10 | # different evaluationg sets. 11 | # 12 | # This script assumes one model has been trained, 13 | # and it just needs the directory to the waveforms of 14 | # the evaluation set. It will automatically produce 15 | # the test.lst and config config_auto.py 16 | # 17 | # Usage: 18 | # bash 02_eval_alternative.sh 19 | # : abosolute path to the directory of eval set waveforms 20 | # : name of the evaluation set, any arbitary string 21 | # : path to the trained model file 22 | ######################## 23 | 24 | if [ "$#" -ne 3 ]; then 25 | echo -e "Invalid input arguments. Please check doc of the script, and use:" 26 | echo -e "bash 02_eval_alternative.sh " 27 | exit 28 | fi 29 | 30 | # path to the directory of waveforms 31 | eval_wav_dir=$1 32 | # name of the evaluation set (any string) 33 | eval_set_name=$2 34 | # path to the trained model 35 | trained_model=$3 36 | 37 | echo -e "Run evaluation" 38 | 39 | # step1. load python environment 40 | source $PWD/../../env.sh 41 | 42 | # step2. prepare test.lst 43 | ls ${eval_wav_dir} | xargs -I{} basename {} .wav | xargs -I{} basename {} .flac > ${eval_set_name}.lst 44 | 45 | # step3. export for config_auto.py 46 | export TEMP_DATA_NAME=${eval_set_name} 47 | export TEMP_DATA_DIR=${eval_wav_dir} 48 | 49 | # step4. run evaluation 50 | log_name=log_eval_${eval_set_name} 51 | python main.py \ 52 | --inference \ 53 | --model-forward-with-file-name \ 54 | --trained-model ${trained_model} \ 55 | --module-config config_auto > ${log_name}.txt 2>&1 56 | 57 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 58 | 59 | echo -e "Process log has been written to $PWD/${log_name}.txt" 60 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 61 | 62 | # step5. delete intermediate files 63 | # this script is created in step2 64 | rm ${eval_set_name}.lst 65 | # this is created by the python code (for convenience) 66 | rm ${eval_set_name}_utt_length.dic 67 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/baseline_LA/__pretrained/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/project/baseline_LA/__pretrained/.gitkeep -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/baseline_LA/config_auto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config.py 4 | 5 | This configuration file will read environment variables 6 | for configuration. it is used by 02_eval_alternative.sh 7 | 8 | 9 | """ 10 | import os 11 | 12 | __author__ = "Xin Wang" 13 | __email__ = "wangxin@nii.ac.jp" 14 | __copyright__ = "Copyright 2021, Xin Wang" 15 | 16 | ######################################################### 17 | ## Configuration for training stage 18 | ######################################################### 19 | 20 | # Name of datasets (any string you wish to use) 21 | # after data preparation, trn/val_set_name are used to save statistics 22 | # about the data sets 23 | trn_set_name = '' 24 | val_set_name = '' 25 | 26 | # File lists (text file, one data name per line, without name extension) 27 | # trin_file_list: list of files for training set 28 | trn_list = '' 29 | # val_file_list: list of files for validation set. It can be None 30 | val_list = '' 31 | 32 | # Directories for input features 33 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 34 | # we assume train and validation data are put in the same sub-directory 35 | # here, we only use waveform as input to the code 36 | input_dirs = [''] 37 | 38 | # Dimensions of input features 39 | # input_dims = [dimension_of_feature_1, dimension_of_feature_2, ...] 40 | # here, we only use waveform as input to the code, and the dimension 41 | # of waveform data is 1 42 | input_dims = [1] 43 | 44 | # File name extension for input features 45 | # input_exts = [name_extention_of_feature_1, ...] 46 | # here, we only use waveform, thus it is ".flac" 47 | input_exts = ['.flac'] 48 | 49 | # Temporal resolution for input features 50 | # input_reso = [reso_feature_1, reso_feature_2, ...] 51 | # this is used for other projects. 52 | # for waveform, we set it to 1 53 | input_reso = [1] 54 | 55 | # Whether input features should be z-normalized 56 | # input_norm = [normalize_feature_1, normalize_feature_2] 57 | # we don't z-normalize the waveform 58 | input_norm = [False] 59 | 60 | # This is for other projects, 61 | # we don't load target features for ASVspoof models using these config 62 | # we read target labels of ASVspoof trials in mode.py 63 | # but we need to fill in some placehoders 64 | output_dirs = [] 65 | output_dims = [1] 66 | output_exts = ['.bin'] 67 | output_reso = [1] 68 | output_norm = [False] 69 | 70 | # Waveform sampling rate 71 | # wav_samp_rate can be None if no waveform data is used 72 | # ASVspoof uses 16000 Hz 73 | wav_samp_rate = 16000 74 | 75 | # Truncating input sequences so that the maximum length = truncate_seq 76 | # When truncate_seq is larger, more GPU mem required 77 | # If you don't want truncating, please truncate_seq = None 78 | # For ASVspoof, we don't do truncate here 79 | truncate_seq = None 80 | 81 | # Minimum sequence length 82 | # If sequence length < minimum_len, this sequence is not used for training 83 | # minimum_len can be None 84 | # For ASVspoof, we don't set minimum length of input trial 85 | minimum_len = None 86 | 87 | 88 | # Optional argument 89 | # We will use this optional_argument to read protocol file 90 | # When evaluating on a eval set without protocol file, set this to [''] 91 | optional_argument = [''] 92 | 93 | ######################################################### 94 | ## Configuration for inference stage 95 | ######################################################### 96 | # similar options to training stage 97 | 98 | test_set_name = os.getenv('TEMP_DATA_NAME') 99 | 100 | # List of test set data 101 | # for convenience, you may directly load test_set list here 102 | test_list = test_set_name + '.lst' 103 | 104 | # Directories for input features 105 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 106 | # directory of the evaluation set waveform 107 | test_input_dirs = [os.getenv('TEMP_DATA_DIR')] 108 | 109 | # Directories for output features, which are [] 110 | test_output_dirs = [] 111 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/project/conda.sh: -------------------------------------------------------------------------------- 1 | conda env create -f ../env.yml 2 | -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/sandbox/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/LA/Baseline-LFCC-LCNN/sandbox/__init__.py -------------------------------------------------------------------------------- /LA/Baseline-LFCC-LCNN/sandbox/eval_music.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Functions for evaluation - music data 4 | 5 | This is just wrappers around MIR_eval http://craffel.github.io/mir_eval/ 6 | 7 | """ 8 | from __future__ import print_function 9 | import os 10 | import sys 11 | import numpy as np 12 | 13 | try: 14 | import mir_eval 15 | except ModuleNotFoundError: 16 | print("Please install mir_eval: http://craffel.github.io/mir_eval/") 17 | print("Anaconda: https://anaconda.org/conda-forge/mir_eval") 18 | print("Pip: https://pypi.org/project/mir_eval/") 19 | sys.exit(1) 20 | 21 | __author__ = "Xin Wang" 22 | __email__ = "wangxin@nii.ac.jp" 23 | __copyright__ = "Copyright 2020, Xin Wang" 24 | 25 | 26 | ############### 27 | # Functions to evaluation melody accuracy 28 | 29 | def eva_music(est_f0, ref_f0, resolution=0.012, tolerence=50): 30 | """ Evaluating estimated F0 using mir_eval metrics. 31 | 32 | Parameters 33 | ---------- 34 | est_f0 : np.array, in shape (N) 35 | estimated F0 (Hz) 36 | ref_f0 : np.array, in shape (N) 37 | reference F0 (Hz) 38 | resolution : float (s) 39 | corresponding to frame-shift of the F0 40 | tolerence : int 41 | tolerence for cent evaluation 42 | 43 | Returns 44 | ------- 45 | rpa : float 46 | raw pitch accuracy 47 | rca : float 48 | raw chroma accuracy 49 | """ 50 | 51 | # generate time sequences 52 | def _time_seq(f0_seq, reso): 53 | time_seq = np.arange(f0_seq.shape[0]) * reso 54 | return time_seq 55 | 56 | est_time = _time_seq(est_f0, resolution) 57 | ref_time = _time_seq(ref_f0, resolution) 58 | 59 | # format change 60 | (ref_v, ref_c, est_v, est_c) = mir_eval.melody.to_cent_voicing( 61 | ref_time, ref_f0, est_time, est_f0) 62 | 63 | # evaluation 64 | rpa = mir_eval.melody.raw_pitch_accuracy(ref_v, ref_c, est_v, est_c) 65 | rca = mir_eval.melody.raw_chroma_accuracy(ref_v, ref_c, est_v, est_c) 66 | 67 | return rpa, rca 68 | -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 eurecom-asp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/README.md: -------------------------------------------------------------------------------- 1 | # RawNet2 ASVspoof 2021 baseline 2 | 3 | By Hemlata Tak, EURECOM, 2021 4 | 5 | ------ 6 | 7 | The code in this repository serves as one of the baselines of the ASVspoof 2021 challenge, using an end-to-end method that uses a model based on the RawNet2 topology as described [here](https://arxiv.org/abs/2011.01108). 8 | 9 | ## Installation 10 | First, clone the repository locally, create and activate a conda environment, and install the requirements : 11 | ``` 12 | $ git clone https://github.com/asvspoof-challenge/2021.git 13 | $ cd 2021/LA/Baseline-RawNet2/ 14 | $ conda create --name rawnet_anti_spoofing python=3.6.10 15 | $ conda activate rawnet_anti_spoofing 16 | $ conda install pytorch=1.4.0 -c pytorch 17 | $ pip install -r requirements.txt 18 | ``` 19 | 20 | ## Experiments 21 | 22 | ### Dataset 23 | Our model for the deepfake (DF) track is trained on the logical access (LA) train partition of the ASVspoof 2019 dataset, which can can be downloaded from [here](https://datashare.is.ed.ac.uk/handle/10283/3336). 24 | 25 | ### Training 26 | To train the model run: 27 | ``` 28 | python main.py --track=DF --loss=CCE --lr=0.0001 --batch_size=32 29 | ``` 30 | 31 | ### Testing 32 | 33 | To test your own model on the ASVspoof 2021 DF evaluation set: 34 | 35 | ``` 36 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/your_best_model.pth' --eval_output='eval_CM_scores.txt' 37 | ``` 38 | 39 | We also provide a pre-trained model which follows a Mel-scale distribution of the sinc filters at the input layer, which can be downloaded from [here](https://www.asvspoof.org/asvspoof2021/pre_trained_DF_RawNet2.zip). To use it you can run: 40 | ``` 41 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/pre_trained_DF_model.pth' --eval_output='pre_trained_eval_CM_scores.txt' 42 | ``` 43 | 44 | If you would like to compute scores on the development set of ASVspoof 2019 simply run: 45 | 46 | ``` 47 | python main.py --track=DF --loss=CCE --eval --model_path='/path/to/your/best_model.pth' --eval_output='dev_CM_scores.txt' 48 | ``` 49 | 50 | ## Contact 51 | For any query regarding this repository, please contact: 52 | - Hemlata Tak: tak[at]eurecom[dot]fr 53 | ## Citation 54 | If you use this code in your research please use the following citation: 55 | ```bibtex 56 | @INPROCEEDINGS{9414234, 57 | author={Tak, Hemlata and Patino, Jose and Todisco, Massimiliano and Nautsch, Andreas and Evans, Nicholas and Larcher, Anthony}, 58 | booktitle={IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)}, 59 | title={End-to-End anti-spoofing with RawNet2}, 60 | year={2021}, 61 | pages={6369-6373} 62 | } 63 | 64 | ``` 65 | -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/core_scripts: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/core_scripts -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/data_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import torch 4 | import torch.nn as nn 5 | from torch import Tensor 6 | import librosa 7 | from torch.utils.data import Dataset 8 | 9 | 10 | ___author__ = "Hemlata Tak" 11 | __email__ = "tak@eurecom.fr" 12 | 13 | 14 | def genSpoof_list( dir_meta,is_train=False,is_eval=False): 15 | 16 | d_meta = {} 17 | file_list=[] 18 | with open(dir_meta, 'r') as f: 19 | l_meta = f.readlines() 20 | 21 | if (is_train): 22 | for line in l_meta: 23 | _, key,_,_,label = line.strip().split(' ') 24 | file_list.append(key) 25 | d_meta[key] = 1 if label == 'bonafide' else 0 26 | return d_meta,file_list 27 | 28 | elif(is_eval): 29 | for line in l_meta: 30 | key= line.strip() 31 | file_list.append(key) 32 | return file_list 33 | else: 34 | for line in l_meta: 35 | _, key,_,_,label = line.strip().split(' ') 36 | file_list.append(key) 37 | d_meta[key] = 1 if label == 'bonafide' else 0 38 | return d_meta,file_list 39 | 40 | 41 | 42 | def pad(x, max_len=64600): 43 | x_len = x.shape[0] 44 | if x_len >= max_len: 45 | return x[:max_len] 46 | # need to pad 47 | num_repeats = int(max_len / x_len)+1 48 | padded_x = np.tile(x, (1, num_repeats))[:, :max_len][0] 49 | return padded_x 50 | 51 | 52 | class Dataset_ASVspoof2019_train(Dataset): 53 | def __init__(self, list_IDs, labels, base_dir): 54 | '''self.list_IDs : list of strings (each string: utt key), 55 | self.labels : dictionary (key: utt key, value: label integer)''' 56 | 57 | self.list_IDs = list_IDs 58 | self.labels = labels 59 | self.base_dir = base_dir 60 | 61 | 62 | def __len__(self): 63 | return len(self.list_IDs) 64 | 65 | 66 | def __getitem__(self, index): 67 | self.cut=64600 # take ~4 sec audio (64600 samples) 68 | key = self.list_IDs[index] 69 | X,fs = librosa.load(self.base_dir+'flac/'+key+'.flac', sr=16000) 70 | X_pad= pad(X,self.cut) 71 | x_inp= Tensor(X_pad) 72 | y = self.labels[key] 73 | return x_inp, y 74 | 75 | 76 | class Dataset_ASVspoof2021_eval(Dataset): 77 | def __init__(self, list_IDs, base_dir): 78 | '''self.list_IDs : list of strings (each string: utt key), 79 | ''' 80 | 81 | self.list_IDs = list_IDs 82 | self.base_dir = base_dir 83 | 84 | 85 | def __len__(self): 86 | return len(self.list_IDs) 87 | 88 | 89 | def __getitem__(self, index): 90 | self.cut=64600 # take ~4 sec audio (64600 samples) 91 | key = self.list_IDs[index] 92 | X, fs = librosa.load(self.base_dir+'flac/'+key+'.flac', sr=16000) 93 | X_pad = pad(X,self.cut) 94 | x_inp = Tensor(X_pad) 95 | return x_inp,key 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/model_config_RawNet.yaml: -------------------------------------------------------------------------------- 1 | optimizer: Adam 2 | amsgrad: 1 #for adam optim 3 | 4 | 5 | 6 | #model-related 7 | model: 8 | nb_samp: 64600 9 | first_conv: 1024 # no. of filter coefficients 10 | in_channels: 1 11 | filts: [20, [20, 20], [20, 128], [128, 128]] # no. of filters channel in residual blocks 12 | blocks: [2, 4] 13 | nb_fc_node: 1024 14 | gru_node: 1024 15 | nb_gru_layer: 3 16 | nb_classes: 2 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LA/Baseline-RawNet2/requirements.txt: -------------------------------------------------------------------------------- 1 | #cuda==10.1 2 | numba==0.48 3 | numpy==1.17.0 4 | librosa==0.7.2 5 | pyyaml==5.3.1 6 | tensorboardX==2.1 -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/matlab/CQCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/CQCC -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/matlab/GMM: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/GMM -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/matlab/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/LICENSE -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # CQCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-end: 9 | - high-time resolution constant Q cepstral coefficients (CQCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### CQCC 16 | Matlab implementation of constant Q cepstral coefficients. 17 | 18 | For further details on CQCC, refer to the following publication: 19 | 20 | - M. Todisco, H. Delgado and N. Evans, "Constant Q cepstral coefficients: a spoofing countermeasure for automatic speaker verification", Computer, Speech and Language, vol. 45, pp. 516 –535, 2017. 21 | 22 | - M. Todisco, H. Delgado, N. Evans, "A new feature for automatic speaker verification anti-spoofing: Constant Q cepstral coefficients," in Proc. ODYSSEY 2016, The Speaker and Language Recognition Workshop, 2016. 23 | 24 | ### GMM 25 | VLFeat open source library that implements the GMMs. 26 | 27 | For further details, refer to: 28 | http://www.vlfeat.org/ 29 | 30 | ### CQCC_GMM_ASVspoof_2021_baseline.m 31 | This script implements the CQCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Physical Access (PA) task. 32 | Front-ends include high-time resolution CQCC features, while back-end is based on GMMs. 33 | CQCC features use 12 bins per octave. Re-sampling is applied with a sampling period of 16 and the features dimension is set to 19 coefficients + 0th, with the static, delta and delta-delta coefficients. CQCC is applied with a maximum frequency of 8 kHz. 34 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 35 | 36 | Results are shown in the ASVspoof 2021 Evaluation Plan. 37 | 38 | ## Contact information 39 | For any query, please contact organisers at lists.asvspoof.org 40 | 41 | -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/python/CQCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/CQCC -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/README.md -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | from gmm import train_gmm 2 | from os.path import exists 3 | import pickle 4 | 5 | 6 | # configs - feature extraction e.g., LFCC or CQCC 7 | features = 'cqcc' 8 | 9 | # configs - GMM parameters 10 | ncomp = 512 11 | 12 | # GMM pickle file 13 | dict_file = 'gmm_PA_cqcc.pkl' 14 | dict_file_final = 'gmm_cqcc_asvspoof21_pa.pkl' 15 | 16 | # configs - train & dev data - if you change these datasets 17 | db_folder = '' 18 | train_folders = [db_folder + 'LA/ASVspoof2019_PA_train/flac/'] # [db_folder + 'PA/ASVspoof2019_PA_train/flac/', db_folder + 'PA/ASVspoof2019_PA_dev/flac/'] 19 | train_keys = [db_folder + 'LA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.train.trn.txt'] # [db_folder + 'PA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.train.trn.txt', db_folder + 'PA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.dev.trn.txt'] 20 | 21 | audio_ext = '.flac' 22 | 23 | # train bona fide & spoof GMMs 24 | if not exists(dict_file): 25 | gmm_bona = train_gmm(data_label='bonafide', features=features, 26 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 27 | dict_file=dict_file, ncomp=ncomp, 28 | init_only=True) 29 | gmm_spoof = train_gmm(data_label='spoof', features=features, 30 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 31 | dict_file=dict_file, ncomp=ncomp, 32 | init_only=True) 33 | 34 | gmm_dict = dict() 35 | gmm_dict['bona'] = gmm_bona._get_parameters() 36 | gmm_dict['spoof'] = gmm_spoof._get_parameters() 37 | with open(dict_file, "wb") as tf: 38 | pickle.dump(gmm_dict, tf) 39 | 40 | 41 | gmm_dict = dict() 42 | with open(dict_file + '_bonafide_init_partial.pkl', "rb") as tf: 43 | gmm_dict['bona'] = pickle.load(tf) 44 | 45 | with open(dict_file + '_spoof_init_partial.pkl', "rb") as tf: 46 | gmm_dict['spoof'] = pickle.load(tf) 47 | 48 | with open(dict_file_final, "wb") as f: 49 | pickle.dump(gmm_dict, f) 50 | 51 | -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/python/gmm.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/python/gmm.py -------------------------------------------------------------------------------- /PA/Baseline-CQCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-cqcc-asvspoof21-PA.txt' 6 | 7 | # configs 8 | features = 'cqcc' 9 | dict_file = 'gmm_cqcc_asvspoof21_pa.pkl' 10 | 11 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 12 | eval_folder = db_folder + 'PA/ASVspoof2021_PA_eval/flac/' 13 | eval_ndx = db_folder + 'PA/ASVspoof2021_PA_cm_protocols/ASVspoof2021.PA.cm.eval.trl.txt' 14 | 15 | audio_ext = '.flac' 16 | 17 | # run on ASVspoof 2021 evaluation set 18 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 19 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 20 | features_cached=True) 21 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/matlab/GMM: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/GMM -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/matlab/LFCC: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/matlab/LFCC -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/matlab/LICENSE: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-CQCC-GMM/matlab/LICENSE -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/matlab/README.md: -------------------------------------------------------------------------------- 1 | # LFCC-GMM ASVspoof 2021 baseline 2 | 3 | By Massimiliano Todisco, EURECOM, 2021 4 | 5 | ------ 6 | 7 | Matlab implementation of spoofing detection baseline system based on: 8 | - front-ends: 9 | - high-frequency resolution linear frequency cepstral coefficients (LFCCs) 10 | - back-end: 11 | - Gaussian Mixture Models (GMMs) 12 | 13 | ## Contents of the package 14 | 15 | ### LFCC 16 | Matlab implementation of linear frequency cepstral coefficients. 17 | 18 | For further details on LFCC for antispoofing, refer to the following publication: 19 | 20 | - H. Tak, J. Patino, A. Nautsch, N. Evans, M. Todisco, "Spoofing Attack Detection using the Non-linear Fusion of Sub-band Classifiers" in Proc INTERSPEECH, 2020. 21 | - M. Sahidullah, T. Kinnunen, C. Hanilçi, "A Comparison of Features for Synthetic Speech Detection," in Proc INTERSPEECH, 2015. 22 | 23 | ### GMM 24 | VLFeat open source library that implements the GMMs. 25 | 26 | For further details, refer to: 27 | http://www.vlfeat.org/ 28 | 29 | ### LFCC_GMM_ASVspoof_2021_baseline.m 30 | This script implements the LFCC-GMM baseline countermeasure system for ASVspoof 2021 Challenge for the Physical Access (PA) task. 31 | Front-ends include hig-frequency resolution LFCC features, while back-end is based on GMMs. 32 | LFCC features use a 30 ms window with a 15 ms shift, 1024-point Fourier transform, 70-channel linear filterbank, from which 19 coefficients + 0th, with the static, delta and delta-delta coefficients. LFCC is applied with a maximum frequency of 8 kHz. 33 | 2-class GMMs are trained on the genuine and spoofed speech utterances of the training dataset, respectively. We use 512-component models, trained with an expectation-maximisation (EM) algorithm with random initialisation. The score is computed as the log-likelihood ratio for the test utterance given the natural and the spoofed speech models. 34 | 35 | Results are shown in the ASVspoof 2021 Evaluation Plan. 36 | 37 | ## Contact information 38 | For any query, please contact organisers at lists.asvspoof.org 39 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/python/LFCC_pipeline.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/LFCC_pipeline.py -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/python/README.md: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/README.md -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/python/asvspoof2021_baseline.py: -------------------------------------------------------------------------------- 1 | from gmm import train_gmm 2 | from os.path import exists 3 | import pickle 4 | 5 | 6 | # configs - feature extraction e.g., LFCC or CQCC 7 | features = 'lfcc' 8 | 9 | # configs - GMM parameters 10 | ncomp = 512 11 | 12 | # GMM pickle file 13 | dict_file = 'gmm_PA_lfcc.pkl' 14 | dict_file_final = 'gmm_lfcc_asvspoof21_pa.pkl' 15 | 16 | # configs - train & dev data - if you change these datasets 17 | db_folder = '/path/to/ASVspoof_root/' 18 | train_folders = [db_folder + 'PA/ASVspoof2019_PA_train/flac/'] # [db_folder + 'PA/ASVspoof2019_PA_train/flac/', db_folder + 'PA/ASVspoof2019_PA_dev/flac/'] 19 | train_keys = [db_folder + 'PA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.train.trn.txt'] # [db_folder + 'PA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.train.trn.txt', db_folder + 'PA/ASVspoof2019_PA_cm_protocols/ASVspoof2019.PA.cm.dev.trn.txt'] 20 | 21 | audio_ext = '.flac' 22 | 23 | # train bona fide & spoof GMMs 24 | if not exists(dict_file): 25 | gmm_bona = train_gmm(data_label='bonafide', features=features, 26 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 27 | dict_file=dict_file, ncomp=ncomp, 28 | init_only=True) 29 | gmm_spoof = train_gmm(data_label='spoof', features=features, 30 | train_keys=train_keys, train_folders=train_folders, audio_ext=audio_ext, 31 | dict_file=dict_file, ncomp=ncomp, 32 | init_only=True) 33 | 34 | gmm_dict = dict() 35 | gmm_dict['bona'] = gmm_bona._get_parameters() 36 | gmm_dict['spoof'] = gmm_spoof._get_parameters() 37 | with open(dict_file, "wb") as tf: 38 | pickle.dump(gmm_dict, tf) 39 | 40 | 41 | gmm_dict = dict() 42 | with open(dict_file + '_bonafide_init_partial.pkl', "rb") as tf: 43 | gmm_dict['bona'] = pickle.load(tf) 44 | 45 | with open(dict_file + '_spoof_init_partial.pkl', "rb") as tf: 46 | gmm_dict['spoof'] = pickle.load(tf) 47 | 48 | with open(dict_file_final, "wb") as f: 49 | pickle.dump(gmm_dict, f) 50 | 51 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/python/gmm.py: -------------------------------------------------------------------------------- 1 | ../../../LA/Baseline-LFCC-GMM/python/gmm.py -------------------------------------------------------------------------------- /PA/Baseline-LFCC-GMM/python/gmm_scoring_asvspoof21.py: -------------------------------------------------------------------------------- 1 | from gmm import scoring 2 | 3 | 4 | # scores file to write 5 | scores_file = 'scores-lfcc-asvspoof21-PA.txt' 6 | 7 | # configs 8 | features = 'lfcc' 9 | dict_file = 'gmm_lfcc_asvspoof21_pa.pkl' 10 | 11 | db_folder = '/path/to/ASVspoof_root/' # put your database root path here 12 | eval_folder = db_folder + 'PA/ASVspoof2021_PA_eval/flac/' 13 | eval_ndx = db_folder + 'PA/ASVspoof2021_PA_cm_protocols/ASVspoof2021.PA.cm.eval.trl.txt' 14 | 15 | audio_ext = '.flac' 16 | 17 | # run on ASVspoof 2021 evaluation set 18 | scoring(scores_file=scores_file, dict_file=dict_file, features=features, 19 | eval_ndx=eval_ndx, eval_folder=eval_folder, audio_ext=audio_ext, 20 | features_cached=True) 21 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/LICENSE -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/README.md: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/README.md -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/core_modules: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/core_modules -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/core_scripts: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/core_scripts -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/env.sh: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/env.sh -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/env.yml: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/env.yml -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/00_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Download toy data package and pre-trained models 4 | echo "=== Downloading toy dataset ===" 5 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABc-QK2BvzEPj-s8nBwCkMna/temp/asvspoof2021/toy_example.tar.gz 6 | cd DATA 7 | wget -q ${SRC} 8 | cd .. 9 | 10 | echo "=== Downloading pre-trained models ===" 11 | if [ -d baseline_DF ]; 12 | then 13 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_DF_LFCC-LCNN.zip 14 | wget -q ${SRC} 15 | if [ -f pre_trained_DF_LFCC-LCNN.zip ]; 16 | then 17 | unzip pre_trained_DF_LFCC-LCNN.zip 18 | #mv pre_trained_DF_LFCC-LCNN.pt df_trained_network.pt 19 | rm pre_trained_DF_LFCC-LCNN.zip 20 | fi 21 | 22 | if [ ! -f df_trained_network.pt ]; 23 | then 24 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AABg4OUDKFvFonI-HmIzT5qIa/temp/asvspoof2021/df_trained_network.pt 25 | wget -q ${SRC} 26 | fi 27 | mv df_trained_network.pt baseline_DF/__pretrained/trained_network.pt 28 | fi 29 | 30 | if [ -d baseline_LA ]; 31 | then 32 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_LA_LFCC-LCNN.zip 33 | wget -q ${SRC} 34 | if [ -f pre_trained_LA_LFCC-LCNN.zip ]; 35 | then 36 | unzip pre_trained_LA_LFCC-LCNN.zip 37 | #mv pre_trained_LA_LFCC-LCNN.pt la_trained_network.pt 38 | rm pre_trained_LA_LFCC-LCNN.zip 39 | fi 40 | 41 | if [ ! -f la_trained_network.pt ]; 42 | then 43 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AADWOs9cmLBzWuRPbh5m10YVa/temp/asvspoof2021/la_trained_network.pt 44 | wget -q ${SRC} 45 | fi 46 | mv la_trained_network.pt baseline_LA/__pretrained/trained_network.pt 47 | fi 48 | 49 | if [ -d baseline_PA ]; 50 | then 51 | SRC=https://www.asvspoof.org/asvspoof2021/pre_trained_PA_LFCC-LCNN.zip 52 | wget -q ${SRC} 53 | if [ -f pre_trained_PA_LFCC-LCNN.zip ]; 54 | then 55 | unzip pre_trained_PA_LFCC-LCNN.zip 56 | #mv pre_trained_PA_LFCC-LCNN.pt pa_trained_network.pt 57 | rm pre_trained_PA_LFCC-LCNN.zip 58 | fi 59 | 60 | if [ ! -f pa_trained_network.pt ]; 61 | then 62 | SRC=https://www.dropbox.com/sh/gf3zp00qvdp3row/AACOBr0ymqsMA0rKctMxkKaxa/temp/asvspoof2021/pa_trained_network.pt 63 | wget -q ${SRC} 64 | fi 65 | mv pa_trained_network.pt baseline_PA/__pretrained/trained_network.pt 66 | fi 67 | 68 | echo "Download done" 69 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/01_wrapper_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script to quickly evaluate a evaluation set 4 | # 5 | # 00_toy_example.sh requires configuration of config.py, 6 | # which further requires preparation of test.lst 7 | # and protocol.txt. 8 | # 9 | # It is convenient when doing numerious experiments 10 | # on the same data set but troublesome when evaluating 11 | # different evaluationg sets. 12 | # 13 | # This script shows one example of quick evaluation using 14 | # lfcc-lcnn-lstm-sig_toy_example/02_eval_alternative.sh 15 | # 16 | # It will use DATA/toy_example/eval 17 | # It will call the evaluat set toy_eval 18 | # It will use __pretrained/trained_network.pt as pre-trained model 19 | # 20 | # (See Doc of 02_eval_alternative.sh for more details) 21 | # 22 | # Note that we don't need a protocol or meta labels. 23 | # 24 | ######################## 25 | 26 | # Load python environment 27 | bash conda.sh 28 | 29 | # We will use DATA/toy_example/eval as example 30 | cd DATA 31 | tar -xzf toy_example.tar.gz 32 | cd .. 33 | 34 | # Go to the folder 35 | cd baseline_PA 36 | 37 | # Run evaluation using pretrained model 38 | # bash 02_eval_alternative.sh PATH_TO_WAV_DIR NAME_OF_DATA_SET TRAINED_MODEL 39 | # For details, please check 02_eval_alternative.sh 40 | bash 02_eval_alternative.sh $PWD/../DATA/toy_example/eval toy_eval __pretrained/trained_network.pt 41 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/02_toy_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for toy_example 4 | # This script will 5 | # 1. install pytorch env using conda 6 | # 2. untar toy data set 7 | # 3. run evaluation and training process 8 | # 9 | # If GPU memory is less than 16GB, please reduce 10 | # --batch-size in 00_train.sh 11 | ######################## 12 | RED='\033[0;32m' 13 | NC='\033[0m' 14 | 15 | echo -e "\n${RED}=======================================================${NC}" 16 | echo -e "${RED}Step1. install conda environment${NC}" 17 | 18 | # create conda environment 19 | bash conda.sh 20 | 21 | # untar the toy-example data 22 | echo -e "\n${RED}=======================================================${NC}" 23 | echo -e "${RED}Step2. untar toy data set${NC}" 24 | 25 | cd DATA 26 | tar -xzf toy_example.tar.gz 27 | cd .. 28 | 29 | echo -e "\n${RED}=======================================================${NC}" 30 | echo -e "${RED}Step3. run evaluation process (using pre-trained model)${NC}" 31 | # run scripts 32 | 33 | cd baseline_PA 34 | # evaluation using pre-trained model 35 | bash 01_eval.sh 36 | 37 | echo -e "\n${RED}=======================================================${NC}" 38 | echo -e "${RED}Step4. run training process (start with pre-trained model)${NC}" 39 | #training, with pre-trained model as initialization 40 | bash 00_train.sh 41 | 42 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/99_del.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -r DATA/* 3 | rm baseline_*/__pretrained/* 4 | rm baseline_*/log* 5 | rm -r baseline_*/__pycache__ 6 | rm baseline_*/epoch* 7 | rm baseline_*/asv* 8 | rm baseline_*/*.pt 9 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/DATA/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/PA/Baseline-LFCC-LCNN/project/DATA/.gitkeep -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/baseline_PA/00_train.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. $: bash 00_train.sh > /dev/null 2>&1 & 7 | # 3. please check log_train and log_err to monitor the training 8 | # process 9 | # 10 | # Note: 11 | # 1. The script by default uses the pre-trained model from ASVspoof2019 12 | # If you don't want to use it, just delete the option --trained-model 13 | # 2. For options, check $: python main.py --help 14 | ######################## 15 | 16 | log_train_name=log_train 17 | log_err_name=log_err 18 | pretrained_model=__pretrained/trained_network.pt 19 | 20 | echo -e "Training" 21 | echo -e "Please monitor the log trainig: $PWD/${log_train_name}.txt\n" 22 | source $PWD/../../env.sh 23 | python main.py --model-forward-with-file-name \ 24 | --num-workers 3 --epochs 100 \ 25 | --no-best-epochs 50 --batch-size 64 \ 26 | --sampler block_shuffle_by_length \ 27 | --lr-decay-factor 0.5 --lr-scheduler-type 1 \ 28 | --trained-model ${pretrained_model} \ 29 | --ignore-training-history-in-trained-model \ 30 | --lr 0.0003 --seed 1000 > ${log_train_name}.txt 2>${log_err_name}.txt 31 | echo -e "Training process finished" 32 | echo -e "Trainig log has been written to $PWD/${log_train_name}.txt" 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/baseline_PA/01_eval.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for evaluation 4 | # Usage: 5 | # 1. please check that config.py has been properly configured 6 | # 2. please specify the trained model 7 | # here, we use a pre-trained model from ASVspoof2019 8 | # 2. $: bash 01_eval.sh 9 | ######################## 10 | 11 | log_name=log_eval 12 | trained_model=__pretrained/trained_network.pt 13 | 14 | echo -e "Run evaluation" 15 | source $PWD/../../env.sh 16 | python main.py --inference --model-forward-with-file-name \ 17 | --trained-model ${trained_model}> ${log_name}.txt 2>${log_name}_err.txt 18 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 19 | echo -e "Process log has been written to $PWD/${log_name}.txt" 20 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 21 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/baseline_PA/02_eval_alternative.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################## 3 | # Script for quick evaluation 4 | # 01_eval.sh requires configuration of config.py, 5 | # which further requires preparation of test.lst 6 | # and protocol.txt. 7 | # 8 | # It is convenient when doing numerious experiments 9 | # on the same data set but troublesome when evaluating 10 | # different evaluationg sets. 11 | # 12 | # This script assumes one model has been trained, 13 | # and it just needs the directory to the waveforms of 14 | # the evaluation set. It will automatically produce 15 | # the test.lst and config config_auto.py 16 | # 17 | # Usage: 18 | # bash 02_eval_alternative.sh 19 | # : abosolute path to the directory of eval set waveforms 20 | # : name of the evaluation set, any arbitary string 21 | # : path to the trained model file 22 | ######################## 23 | 24 | if [ "$#" -ne 3 ]; then 25 | echo -e "Invalid input arguments. Please check doc of the script, and use:" 26 | echo -e "bash 02_eval_alternative.sh " 27 | exit 28 | fi 29 | 30 | # path to the directory of waveforms 31 | eval_wav_dir=$1 32 | # name of the evaluation set (any string) 33 | eval_set_name=$2 34 | # path to the trained model 35 | trained_model=$3 36 | 37 | echo -e "Run evaluation" 38 | 39 | # step1. load python environment 40 | source $PWD/../../env.sh 41 | 42 | # step2. prepare test.lst 43 | ls ${eval_wav_dir} | xargs -I{} basename {} .wav | xargs -I{} basename {} .flac > ${eval_set_name}.lst 44 | 45 | # step3. export for config_auto.py 46 | export TEMP_DATA_NAME=${eval_set_name} 47 | export TEMP_DATA_DIR=${eval_wav_dir} 48 | 49 | # step4. run evaluation 50 | log_name=log_eval_${eval_set_name} 51 | python main.py \ 52 | --inference \ 53 | --model-forward-with-file-name \ 54 | --trained-model ${trained_model} \ 55 | --module-config config_auto > ${log_name}.txt 2>&1 56 | 57 | cat ${log_name}.txt | grep "Output," | awk '{print $2" "$4}' | sed 's:,::g' > ${log_name}_score.txt 58 | 59 | echo -e "Process log has been written to $PWD/${log_name}.txt" 60 | echo -e "Score has been written to $PWD/${log_name}_score.txt" 61 | 62 | # step5. delete intermediate files 63 | # this script is created in step2 64 | rm ${eval_set_name}.lst 65 | # this is created by the python code (for convenience) 66 | rm ${eval_set_name}_utt_length.dic 67 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/baseline_PA/__pretrained/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asvspoof-challenge/2021/9b33f5eca887bd3bf629e3fb79428cd9bb7ac972/PA/Baseline-LFCC-LCNN/project/baseline_PA/__pretrained/.gitkeep -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/baseline_PA/config_auto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | config.py 4 | 5 | This configuration file will read environment variables 6 | for configuration. it is used by 02_eval_alternative.sh 7 | 8 | 9 | """ 10 | import os 11 | 12 | __author__ = "Xin Wang" 13 | __email__ = "wangxin@nii.ac.jp" 14 | __copyright__ = "Copyright 2021, Xin Wang" 15 | 16 | ######################################################### 17 | ## Configuration for training stage 18 | ######################################################### 19 | 20 | # Name of datasets (any string you wish to use) 21 | # after data preparation, trn/val_set_name are used to save statistics 22 | # about the data sets 23 | trn_set_name = '' 24 | val_set_name = '' 25 | 26 | # File lists (text file, one data name per line, without name extension) 27 | # trin_file_list: list of files for training set 28 | trn_list = '' 29 | # val_file_list: list of files for validation set. It can be None 30 | val_list = '' 31 | 32 | # Directories for input features 33 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 34 | # we assume train and validation data are put in the same sub-directory 35 | # here, we only use waveform as input to the code 36 | input_dirs = [''] 37 | 38 | # Dimensions of input features 39 | # input_dims = [dimension_of_feature_1, dimension_of_feature_2, ...] 40 | # here, we only use waveform as input to the code, and the dimension 41 | # of waveform data is 1 42 | input_dims = [1] 43 | 44 | # File name extension for input features 45 | # input_exts = [name_extention_of_feature_1, ...] 46 | # here, we only use waveform, thus it is ".flac" 47 | input_exts = ['.flac'] 48 | 49 | # Temporal resolution for input features 50 | # input_reso = [reso_feature_1, reso_feature_2, ...] 51 | # this is used for other projects. 52 | # for waveform, we set it to 1 53 | input_reso = [1] 54 | 55 | # Whether input features should be z-normalized 56 | # input_norm = [normalize_feature_1, normalize_feature_2] 57 | # we don't z-normalize the waveform 58 | input_norm = [False] 59 | 60 | # This is for other projects, 61 | # we don't load target features for ASVspoof models using these config 62 | # we read target labels of ASVspoof trials in mode.py 63 | # but we need to fill in some placehoders 64 | output_dirs = [] 65 | output_dims = [1] 66 | output_exts = ['.bin'] 67 | output_reso = [1] 68 | output_norm = [False] 69 | 70 | # Waveform sampling rate 71 | # wav_samp_rate can be None if no waveform data is used 72 | # ASVspoof uses 16000 Hz 73 | wav_samp_rate = 16000 74 | 75 | # Truncating input sequences so that the maximum length = truncate_seq 76 | # When truncate_seq is larger, more GPU mem required 77 | # If you don't want truncating, please truncate_seq = None 78 | # For ASVspoof, we don't do truncate here 79 | truncate_seq = None 80 | 81 | # Minimum sequence length 82 | # If sequence length < minimum_len, this sequence is not used for training 83 | # minimum_len can be None 84 | # For ASVspoof, we don't set minimum length of input trial 85 | minimum_len = None 86 | 87 | 88 | # Optional argument 89 | # We will use this optional_argument to read protocol file 90 | # When evaluating on a eval set without protocol file, set this to [''] 91 | optional_argument = [''] 92 | 93 | ######################################################### 94 | ## Configuration for inference stage 95 | ######################################################### 96 | # similar options to training stage 97 | 98 | test_set_name = os.getenv('TEMP_DATA_NAME') 99 | 100 | # List of test set data 101 | # for convenience, you may directly load test_set list here 102 | test_list = test_set_name + '.lst' 103 | 104 | # Directories for input features 105 | # input_dirs = [path_of_feature_1, path_of_feature_2, ..., ] 106 | # directory of the evaluation set waveform 107 | test_input_dirs = [os.getenv('TEMP_DATA_DIR')] 108 | 109 | # Directories for output features, which are [] 110 | test_output_dirs = [] 111 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/project/conda.sh: -------------------------------------------------------------------------------- 1 | conda env create -f ../env.yml 2 | -------------------------------------------------------------------------------- /PA/Baseline-LFCC-LCNN/sandbox: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-LFCC-LCNN/sandbox -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/LICENSE: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/LICENSE -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/README.md: -------------------------------------------------------------------------------- 1 | # RawNet2 ASVspoof 2021 baseline 2 | 3 | By Hemlata Tak, EURECOM, 2021 4 | 5 | ------ 6 | 7 | The code in this repository serves as one of the baselines of the ASVspoof 2021 challenge, using an end-to-end method that uses a model based on the RawNet2 topology as described [here](https://arxiv.org/abs/2011.01108). 8 | 9 | ## Installation 10 | First, clone the repository locally, create and activate a conda environment, and install the requirements : 11 | ``` 12 | $ git clone https://github.com/asvspoof-challenge/2021.git 13 | $ cd 2021/PA/Baseline-RawNet2/ 14 | $ conda create --name rawnet_anti_spoofing python=3.6.10 15 | $ conda activate rawnet_anti_spoofing 16 | $ conda install pytorch=1.4.0 -c pytorch 17 | $ pip install -r requirements.txt 18 | ``` 19 | 20 | ## Experiments 21 | 22 | ### Dataset 23 | Our model for the deepfake (DF) track is trained on the logical access (LA) train partition of the ASVspoof 2019 dataset, which can can be downloaded from [here](https://datashare.is.ed.ac.uk/handle/10283/3336). 24 | 25 | ### Training 26 | To train the model run: 27 | ``` 28 | python main.py --track=DF --loss=CCE --lr=0.0001 --batch_size=32 29 | ``` 30 | 31 | ### Testing 32 | 33 | To test your own model on the ASVspoof 2021 DF evaluation set: 34 | 35 | ``` 36 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/your_best_model.pth' --eval_output='eval_CM_scores.txt' 37 | ``` 38 | 39 | We also provide a pre-trained model which follows a Mel-scale distribution of the sinc filters at the input layer, which can be downloaded from [here](https://www.asvspoof.org/asvspoof2021/pre_trained_DF_RawNet2.zip). To use it you can run: 40 | ``` 41 | python main.py --track=DF --loss=CCE --is_eval --eval --model_path='/path/to/your/pre_trained_DF_model.pth' --eval_output='pre_trained_eval_CM_scores.txt' 42 | ``` 43 | 44 | If you would like to compute scores on the development set of ASVspoof 2019 simply run: 45 | 46 | ``` 47 | python main.py --track=DF --loss=CCE --eval --model_path='/path/to/your/best_model.pth' --eval_output='dev_CM_scores.txt' 48 | ``` 49 | 50 | ## Contact 51 | For any query regarding this repository, please contact: 52 | - Hemlata Tak: tak[at]eurecom[dot]fr 53 | ## Citation 54 | If you use this code in your research please use the following citation: 55 | ```bibtex 56 | @INPROCEEDINGS{9414234, 57 | author={Tak, Hemlata and Patino, Jose and Todisco, Massimiliano and Nautsch, Andreas and Evans, Nicholas and Larcher, Anthony}, 58 | booktitle={IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)}, 59 | title={End-to-End anti-spoofing with RawNet2}, 60 | year={2021}, 61 | pages={6369-6373} 62 | } 63 | 64 | ``` 65 | -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/core_scripts: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/core_scripts -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/data_utils.py: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/data_utils.py -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/model.py: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/model.py -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/model_config_RawNet.yaml: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/model_config_RawNet.yaml -------------------------------------------------------------------------------- /PA/Baseline-RawNet2/requirements.txt: -------------------------------------------------------------------------------- 1 | ../../LA/Baseline-RawNet2/requirements.txt -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/DF/package-stage-1/README.txt: -------------------------------------------------------------------------------- 1 | This is the script to compute pooled EER for ASVspoof2021 DF scenario. 2 | 3 | Dependency: 4 | Python3, Numpy, pandas 5 | 6 | Usage: 7 | 1. download and untar the ground-truth label files 8 | $: download.sh 9 | The downloaded directory will be named as ./keys 10 | 11 | 2. run python script 12 | $: python PATH_TO_SCORE_FILE PATH_TO_GROUDTRUTH_DIR phase 13 | 14 | -PATH_TO_SCORE_FILE: path to the score file 15 | -PATH_TO_GROUNDTRUTH_DIR: path to the directory from step1 16 | Please use ./keys 17 | -phase: either progress, eval, or hidden_track 18 | 19 | Example: 20 | $: python evaluate.py score.txt ./keys eval 21 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/DF/package-stage-1/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script only works for Mac and Linux. 4 | # If curl or wget is not available, please download the file manually 5 | 6 | URLLINK=https://www.asvspoof.org/resources/DF-keys-stage-1.tar.gz 7 | PACKNAME=DF-keys-stage-1.tar.gz 8 | 9 | if command -v wget &> /dev/null 10 | then 11 | TOOL="wget -q --show-progress" 12 | ${TOOL} ${URLLINK} 13 | elif command -v curl &> /dev/null 14 | then 15 | TOOL="curl -L -O -J" 16 | ${TOOL} ${URLLINK} 17 | else 18 | echo "Could not find a tool to download files" 19 | echo "Please manully download the file from ${URLLINK}" 20 | echo "Then please untar it. You should get a folder called ./keys" 21 | exit 22 | fi 23 | 24 | if [ ! -e "${PACKNAME}" ]; 25 | then 26 | echo "Could not automatically download the file" 27 | echo "Please manully download the file from ${URLLINK}" 28 | echo "Then please untar it. You should get a folder called ./keys" 29 | exit 30 | else 31 | tar -xzvf ${PACKNAME} 32 | fi 33 | 34 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/DF/package-stage-1/evaluate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Script to compute pooled EER for ASVspoof2021 DF. 4 | 5 | Usage: 6 | $: python PATH_TO_SCORE_FILE PATH_TO_GROUDTRUTH_DIR phase 7 | 8 | -PATH_TO_SCORE_FILE: path to the score file 9 | -PATH_TO_GROUNDTRUTH_DIR: path to the directory that has the CM protocol. 10 | Please follow README, download the key files, and use ./keys 11 | -phase: either progress, eval, or hidden_track 12 | 13 | Example: 14 | $: python evaluate.py score.txt ./keys eval 15 | """ 16 | import sys, os.path 17 | import numpy as np 18 | import pandas 19 | import eval_metrics as em 20 | from glob import glob 21 | 22 | if len(sys.argv) != 4: 23 | print("CHECK: invalid input arguments. Please read the instruction below:") 24 | print(__doc__) 25 | exit(1) 26 | 27 | submit_file = sys.argv[1] 28 | truth_dir = sys.argv[2] 29 | phase = sys.argv[3] 30 | 31 | cm_key_file = os.path.join(truth_dir, 'CM/trial_metadata.txt') 32 | 33 | 34 | def eval_to_score_file(score_file, cm_key_file): 35 | 36 | cm_data = pandas.read_csv(cm_key_file, sep=' ', header=None) 37 | submission_scores = pandas.read_csv(score_file, sep=' ', header=None, skipinitialspace=True) 38 | if len(submission_scores) != len(cm_data): 39 | print('CHECK: submission has %d of %d expected trials.' % (len(submission_scores), len(cm_data))) 40 | exit(1) 41 | 42 | if len(submission_scores.columns) > 2: 43 | print('CHECK: submission has more columns (%d) than expected (2). Check for leading/ending blank spaces.' % len(submission_scores.columns)) 44 | exit(1) 45 | 46 | cm_scores = submission_scores.merge(cm_data[cm_data[7] == phase], left_on=0, right_on=1, how='inner') # check here for progress vs eval set 47 | bona_cm = cm_scores[cm_scores[5] == 'bonafide']['1_x'].values 48 | spoof_cm = cm_scores[cm_scores[5] == 'spoof']['1_x'].values 49 | eer_cm = em.compute_eer(bona_cm, spoof_cm)[0] 50 | out_data = "eer: %.2f\n" % (100*eer_cm) 51 | print(out_data) 52 | return eer_cm 53 | 54 | if __name__ == "__main__": 55 | 56 | if not os.path.isfile(submit_file): 57 | print("%s doesn't exist" % (submit_file)) 58 | exit(1) 59 | 60 | if not os.path.isdir(truth_dir): 61 | print("%s doesn't exist" % (truth_dir)) 62 | exit(1) 63 | 64 | if phase != 'progress' and phase != 'eval' and phase != 'hidden_track': 65 | print("phase must be either progress, eval, or hidden_track") 66 | exit(1) 67 | 68 | _ = eval_to_score_file(submit_file, cm_key_file) 69 | 70 | 71 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/LA/package-stage-1/README.txt: -------------------------------------------------------------------------------- 1 | This is the script to compute pooled EER and min-tDCF for ASVspoof2021 LA scenario. 2 | 3 | Dependency: 4 | Python3, Numpy, pandas 5 | 6 | Usage: 7 | 1. download and untar the ground-truth label files 8 | $: download.sh 9 | The downloaded directory will be named as ./keys 10 | 11 | 2. run python script 12 | $: python PATH_TO_SCORE_FILE PATH_TO_GROUDTRUTH_DIR phase 13 | 14 | -PATH_TO_SCORE_FILE: path to the score file 15 | -PATH_TO_GROUNDTRUTH_DIR: path to the directory from step1 16 | Please use ./keys 17 | -phase: either progress, eval, or hidden_track 18 | 19 | Example: 20 | $: python evaluate.py score.txt ./keys eval 21 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/LA/package-stage-1/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script only works for Mac and Linux. 4 | # If curl or wget is not available, please download the file manually 5 | 6 | URLLINK=https://www.asvspoof.org/resources/LA-keys-stage-1.tar.gz 7 | PACKNAME=LA-keys-stage-1.tar.gz 8 | 9 | if command -v wget &> /dev/null 10 | then 11 | TOOL="wget -q --show-progress" 12 | ${TOOL} ${URLLINK} 13 | elif command -v curl &> /dev/null 14 | then 15 | TOOL="curl -L -O -J" 16 | ${TOOL} ${URLLINK} 17 | else 18 | echo "Could not find a tool to download files" 19 | echo "Please manully download the file from ${URLLINK}" 20 | echo "Then please untar it. You should get a folder called ./keys" 21 | exit 22 | fi 23 | 24 | if [ ! -e "${PACKNAME}" ]; 25 | then 26 | echo "Could not automatically download the file" 27 | echo "Please manully download the file from ${URLLINK}" 28 | echo "Then please untar it. You should get a folder called ./keys" 29 | exit 30 | else 31 | tar -xzvf ${PACKNAME} 32 | fi 33 | 34 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/PA/package-stage-1/README.txt: -------------------------------------------------------------------------------- 1 | This is script to compute pooled EER and min tDCF for ASVspoof2021 PA scenario. 2 | 3 | Dependency: 4 | Python3, Numpy, pandas 5 | 6 | Usage: 7 | 1. download and untar the ground-truth label files 8 | $: download.sh 9 | The downloaded directory will be named as ./keys 10 | 11 | 2. run python script 12 | $: python PATH_TO_SCORE_FILE PATH_TO_GROUDTRUTH_DIR phase 13 | 14 | -PATH_TO_SCORE_FILE: path to the score file 15 | -PATH_TO_GROUNDTRUTH_DIR: path to the directory from step1 16 | Please use ./keys 17 | -phase: either progress, eval, hidden_track_1, or hidden_track_2 18 | 19 | Example: 20 | $: python evaluate.py score.txt ./keys eval 21 | -------------------------------------------------------------------------------- /eval-package/archived-package-stage-1/PA/package-stage-1/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script only works for Mac and Linux. 4 | # If curl or wget is not available, please download the file manually 5 | 6 | URLLINK=https://www.asvspoof.org/resources/PA-keys-stage-1.tar.gz 7 | PACKNAME=PA-keys-stage-1.tar.gz 8 | 9 | if command -v wget &> /dev/null 10 | then 11 | TOOL="wget -q --show-progress" 12 | ${TOOL} ${URLLINK} 13 | elif command -v curl &> /dev/null 14 | then 15 | TOOL="curl -L -O -J" 16 | ${TOOL} ${URLLINK} 17 | else 18 | echo "Could not find a tool to download files" 19 | echo "Please manully download the file from ${URLLINK}" 20 | echo "Then please untar it. You should get a folder called ./keys" 21 | exit 22 | fi 23 | 24 | if [ ! -e "${PACKNAME}" ]; 25 | then 26 | echo "Could not automatically download the file" 27 | echo "Please manully download the file from ${URLLINK}" 28 | echo "Then please untar it. You should get a folder called ./keys" 29 | exit 30 | else 31 | tar -xzvf ${PACKNAME} 32 | fi 33 | 34 | -------------------------------------------------------------------------------- /eval-package/download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This bash script only works for Linux Ubuntu. 3 | # If script does not work, please download the file manually 4 | 5 | URLLINKS=(https://www.asvspoof.org/asvspoof2021/LA-keys-full.tar.gz 6 | https://www.asvspoof.org/asvspoof2021/PA-keys-full.tar.gz 7 | https://www.asvspoof.org/asvspoof2021/DF-keys-full.tar.gz) 8 | 9 | MD5SUMVALS=(f052cc2ed276745afa3b5198665d3b26 10 | a639ea472cf4fb564a62fbc7383c24cf 11 | dabbc5628de4fcef53036c99ac7ab93a) 12 | 13 | if command -v wget &> /dev/null 14 | then 15 | TOOL="wget -q --show-progress" 16 | else 17 | echo "Cannot find a tool to download the file. Please manually download it" 18 | for URLLINK in ${URLLINKS} 19 | do 20 | echo ${URLLINK} 21 | done 22 | exit 23 | fi 24 | 25 | if command -v md5sum &> /dev/null 26 | then 27 | MD5TOOL="md5sum" 28 | else 29 | MD5TOOL="" 30 | fi 31 | 32 | 33 | # download 34 | for idx in 0 1 2 35 | do 36 | URLLINK=${URLLINKS[${idx}]} 37 | MD5VAL=${MD5SUMVALS[${idx}]} 38 | 39 | PACKNAME=$(basename ${URLLINK}) 40 | 41 | echo "Download ${URLLINK}" 42 | ${TOOL} ${URLLINK} 43 | 44 | while [ ! -e "${PACKNAME}" ]; 45 | do 46 | echo "File server is busy. Re-try to download ${URLLINK}" 47 | ${TOOL} ${URLLINK} 48 | sleep 0.5 49 | done 50 | 51 | if [ ! -e "${PACKNAME}" ]; 52 | then 53 | echo "Failed to download the file." 54 | echo "Please manully download ${URLLINK}." 55 | echo "File server may be busy." 56 | echo "Please try multiple times" 57 | exit 58 | else 59 | if [ -z "$MD5TOOL" ]; 60 | then 61 | echo "Cannot a find a tool for checksum." 62 | echo "checksum of ${PACKNAME} should be ${MD5VAL}" 63 | tar -xzf ${PACKNAME} 64 | else 65 | md5sum=$(${MD5TOOL} ${PACKNAME} | cut -d ' ' -f 1) 66 | if [ "${md5sum}" == "${MD5VAL}" ]; 67 | then 68 | tar -xzf ${PACKNAME} 69 | else 70 | echo "Downloaded file seems to be damaged" 71 | echo "Please contact with the organizers" 72 | fi 73 | fi 74 | fi 75 | done 76 | -------------------------------------------------------------------------------- /eval-package/pd_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Pandas dataFrame tool 4 | """ 5 | 6 | from __future__ import absolute_import 7 | from __future__ import print_function 8 | 9 | import os 10 | import sys 11 | import pandas 12 | 13 | __author__ = "ASVspoof consortium" 14 | __copyright__ = "Copyright 2022, ASVspoof consortium" 15 | 16 | 17 | def load_protocol(protocol_file, names, sep=' ', index_col=None): 18 | """ pd_protocol = load_protocol(protocol_file, names, sep=' ', index_col=None) 19 | 20 | input 21 | ----- 22 | protocol_file str, path to the protocol file 23 | names list of str, name of the data Series in dataFrame 24 | sep str, separator, by default ' ' 25 | index_col str, name of the index column, by default None 26 | 27 | output 28 | ------ 29 | pd_protocol pandas dataFrame 30 | """ 31 | pd_protocol = pandas.read_csv(protocol_file, sep=' ', names=names, 32 | index_col = index_col, skipinitialspace=True) 33 | return pd_protocol 34 | 35 | 36 | 37 | def load_score(score_file, names, sep=' ', index_col=None): 38 | """ pd_score = load_score(score_file, names, sep=' ', index_col=None) 39 | 40 | input 41 | ----- 42 | score_file str, path to the score file 43 | names list of str, name of the data Series in dataFrame 44 | sep str, separator, by default ' ' 45 | index_col str, name of the index column, by default None 46 | 47 | output 48 | ------ 49 | pd_protocol pandas dataFrame 50 | """ 51 | pd_score = pandas.read_csv(score_file, sep=sep, names=names, 52 | index_col=index_col, skipinitialspace=True) 53 | return pd_score 54 | 55 | 56 | def join_protocol_score(pd_protocol, pd_score): 57 | """ pd_final = join_protocol_score(pd_protocol, pd_score) 58 | 59 | input 60 | ----- 61 | pd_protocol dataFrame, protocol dataframe 62 | pd_score dataFrame, score dataframe 63 | 64 | output 65 | ------ 66 | pd_final dataFrame, joint dataFrame from pd_protocol and pd_score 67 | """ 68 | pd_final = pandas.concat([pd_protocol, pd_score], axis=1, join="inner") 69 | if len(pd_protocol) != len(pd_score) or len(pd_protocol) != len(pd_final): 70 | print("Error: protocol and score seem to mismatch. Please check!") 71 | print("Protocol file has {:d} entries".format(len(pd_protocol))) 72 | print("Score file has {:d} entries".format(len(pd_score))) 73 | print("Number of common entries is {:d}".format(len(pd_final))) 74 | print("\nIs the score file incomplete?") 75 | print("Has you selected the correct track?") 76 | sys.exit(1) 77 | return pd_final 78 | 79 | 80 | if __name__ == "__main__": 81 | print("pd_tools") 82 | --------------------------------------------------------------------------------