{"id":20165472,"url":"https://github.com/tabahi/formantfeatures","last_synced_at":"2025-09-14T19:14:54.485Z","repository":{"id":57431921,"uuid":"248129334","full_name":"tabahi/formantfeatures","owner":"tabahi","description":"Extract frequency, power, width and dissonance of formants from wav files","archived":false,"fork":false,"pushed_at":"2022-06-03T23:48:20.000Z","size":350,"stargazers_count":25,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T00:53:31.151Z","etag":null,"topics":["audio-features","audio-processing","dissonance","emotion-recognition","extract-frequency","formants-features","phoneme-prediction","speech-feature-extraction","speech-recognition","wav"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tabahi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-18T03:26:23.000Z","updated_at":"2024-08-20T23:23:37.000Z","dependencies_parsed_at":"2022-09-02T11:01:41.411Z","dependency_job_id":null,"html_url":"https://github.com/tabahi/formantfeatures","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2Fformantfeatures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2Fformantfeatures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2Fformantfeatures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2Fformantfeatures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tabahi","download_url":"https://codeload.github.com/tabahi/formantfeatures/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137995,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-features","audio-processing","dissonance","emotion-recognition","extract-frequency","formants-features","phoneme-prediction","speech-feature-extraction","speech-recognition","wav"],"created_at":"2024-11-14T00:37:55.789Z","updated_at":"2025-04-10T00:53:35.968Z","avatar_url":"https://github.com/tabahi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Formant characteristic features extraction\n\nExtract frequency, power, width and dissonance of formants from a WAV file. These formant features can be used for speech recognition or music analysis.\n\n## Dependencies\n\n+ Python 3.7 or later\n+ Numpy 1.16 or later\n+ [Scipy v1.3.1](https://scipy.org/install.html)\n+ [H5py v2.9.0](https://pypi.org/project/h5py/)\n+ [Numba (v0.45.1)](https://numba.pydata.org/numba-doc/dev/user/installing.html)\n+ [Wavio v0.0.4](https://pypi.org/project/wavio/)\n\n\u003e Install : `pip install formantfeatures`\n\n\n---------\n\n## Get formant characteristics from a single file\n\n`Extract_wav_file_formants`\n--------------------------------\n\n```python\nimport formantfeatures as ff\n\nformants_features, frame_count, signal_length, trimmed_length = ff.Extract_wav_file_formants(wav_file_path, window_length, window_step, emphasize_ratio, norm=0, f0_min=f0_min, f0_max=f0_max, max_frames=max_frames, formants=max_formants)\n```\n\n### Parameters\n\n\n\u003e`wav_file_path`: string, Path of the input wav audio file.\n\n\u003e`window_length`: float, optional (default=0.025). Frame window size in seconds.\n\n\u003e`window_step`: float, optional (default=0.010). Frame window step size in seconds.\n\n\u003e`emphasize_ratio`: float, optional (default=0.7). Amplitude increasing factor for pre-emphasis of higher frequencies (high frequencies * emphasize_ratio = balanced amplitude as low frequencies).\n\n\u003e `norm`: int, optional, (default=0), Enable or disable normalization of Mel-filters;\n\n\u003e`f0_min`: int, optional, (default=30), Hertz.\n\n\u003e`f0_max`: int, optional, (default=4000), Hertz.\n    \n\u003e`max_frames`: int, optional (default=400). Cut off size for the number of frames per clip. It is used to standardize the size of clips during processing. If clip size is shorter than that then rest of the frames will be filled with zeros. \n    \n\u003e`formants`: int, optional (default=3). Number of formants to extract.\n\n\u003e`formant_decay`: float, optional (default=0.5). Decay constant to exponentially decrease feature values by their formant amplitude ranks.\n\n### Returns\n\n\nreturns `frames_features, frame_count, signal_length, trimmed_length`\n\n\u003e`frames_features`: array-like, `np.array((max_frames, num_of_features*formants), dtype=np.uint16)`. If `formant=3` then `formants_features` is a numpy array of shape=(12xframes) comprising of 12 features for each 0.025s frame of the WAV file. Frame size can be adjusted, recommended size is 0.025s. \nThe 12 features are frequency, power, width and dissonance of top 3 formants are at indices of numpy array as:\n\n\nIndices | Description\n------------ | -------------\n`frames_features[frame, 0]`| frequency of formant 0\n`frames_features[frame, 1]`| power of formant 0\n`frames_features[frame, 2]`| width of formant 0\n`frames_features[frame, 3]`| dissonance of formant 0\n`frames_features[frame, 4]`| frequency of formant 1\n`frames_features[frame, 5]`| power of formant 1\n`frames_features[frame, 6]`| width of formant 1\n`frames_features[frame, 7]`| dissonance of formant 1\n`frames_features[frame, 8]`| frequency of formant 2\n`frames_features[frame, 9]`| power of formant 2\n`frames_features[frame, 10]`| width of formant 2\n`frames_features[frame, 11]`| dissonance of formant 2\n\n\n\u003e`frame_count`: int, number of filled frames (out of max_frames). It is the number of non-zero frames starting from index 0.\n\n\u003e`signal_length`: float, signal length in seconds. Silence at the begining and end of the input signal is trimmed before processing.\n\n\u003e`trimmed_length`: float, trimmed length in seconds, silence at the begining and end of the input signal is trimmed before processing;\n\n:: Note: Frequency is not on Hertz or Mel scale. Instead, a disproportionate scaling is applied to all features that results in completely different scales. An example of conversion back to Hz can be seen in `FormantsHDFread.py` line 89.\n\n## Example\nAn example code is given in file `example.py`.\nThis example extracts 12 formant features for each frame of test wav file ('test_1.wav' has 383 frames of 25ms window at 10ms stride). On line 27 we have:\n\n\n\nThe `formants_features` array of size (500, 12) is returned by the function `formantfeatures.Extract_wav_file_formants` in which 500 is the maximum number of frames but only `frame_count` number of frames are used.\n\nThen we calculate mean of frequency, power, width and dissonance of first 3 formant across 383 frames.\n\n12 formant features of each individual frame can be accessed as: `formants_features[i, j]`, where `i` is the frame number out of total `frame_count` (383 in this example), and `j` is the feature index out of total 12 features (0 for 1st formant frequency).\n\nTo calculate the mean of first fomant frequency across all used frames (383 frames are used out of max 500):\n```python\nfirt_formant_freq_mean = np.mean(formants_features[0:frame_count, 0])\n# where 0:frame_count gives the range of used frames out of total 500 frames. The '0' is the index of 1st formant frequency in features' list.\n\n# Similarly, the power (index is '1'):\nfirt_formant_power_mean = np.mean(formants_features[0:frame_count, 1])\n\n# For frequency of 2nd formant (index is '4' see the list of indices given above)\nsecond_formant_freq_mean = np.mean(formants_features[0:frame_count, 4])\n\n# To get features of individual frames (without mean):\nfirst_freq_of_frame_50 = formants_features[50, 0]  #frequency of 1st formant of frame 50\nfirst_width_of_frame_50 = formants_features[50, 3]  #width of 1st formant of frame 50\n```\n\nOutput of `example.py`:\n```\nformants_features max_frames: 500  features count: 12 frame_count 383\nFormant 0 Mean freq: 1174.3315926892951\nFormant 0 Mean power: 448.1566579634465\nFormant 0 Mean width: 46.30548302872063\nFormant 0 Mean dissonance: 5.169712793733681\nFormant 1 Mean freq: 579.9373368146214\nFormant 1 Mean power: 188.7859007832898\nFormant 1 Mean width: 12.459530026109661\nFormant 1 Mean dissonance: 2.2323759791122715\nFormant 2 Mean freq: 268.45430809399477\nFormant 2 Mean power: 79.54830287206266\nFormant 2 Mean width: 3.8929503916449084\nFormant 2 Mean dissonance: 1.0783289817232375\nDone\n\n```\n\n\n## Bulk processing\n\nPass a list of DB files objects (see \u003chttps://github.com/tabahi/SER_Datasets_Import\u003e) and path of HDF file to save extracted features:\n\n\n`Extract_files_formant_features`\n--------------------------------\n\n```python\nimport formantfeatures as ff\n\nff.Extract_files_formant_features(array_of_clips, features_save_file, window_length=0.025, window_step=0.010, emphasize_ratio=0.7,  f0_min=30, f0_max=4000, max_frames=400, formants=3,)\n```\n\n### Parameters\n\n\n`array_of_clips`: list of `Clip_file_Class` objects from 'SER_DB.py' \u003chttps://github.com/tabahi/SER_Datasets_Import/blob/master/SER_Datasets_Libs/SER_DB.py\u003e\n\n`features_save_file`: string, Path for HDF file where extracted features will be stored\n\n\n### Returns\n\n\n`processed_clips`: int, number of successfully processing clips;\n\n\n## Read HDF data files\n\nHDF read functions: `import_features_from_HDF` import from `FormatsHDFread`\n\n```python\nimport formantfeatures as ff\n\nformant_features, labels, unique_speaker_ids, unique_classes = ff.import_features_from_HDF(storage_file, deselect_labels=['B', 'X'])\n# Import without deslected labels B (Boring) and X (unknown)\n```\n\nPrint label stats and save features stats to file:\n\n```python\nff.print_database_stats(labels)\n\nff.save_features_stats(\"DB_X\", \"csv_filename.csv\", labels, formant_features)\n```\n\n\n\n------------------\n\n## Citations\n\n```tex\n@article{LIU2021309,\ntitle = {Speech emotion recognition based on formant characteristics feature extraction and phoneme type convergence},\njournal = {Information Sciences},\nvolume = {563},\npages = {309-325},\nyear = {2021},\nissn = {0020-0255},\ndoi = {https://doi.org/10.1016/j.ins.2021.02.016},\nurl = {https://www.sciencedirect.com/science/article/pii/S0020025521001584},\nauthor = {Zhen-Tao Liu and Abdul Rehman and Min Wu and Wei-Hua Cao and Man Hao},\nkeywords = {Speech, Emotion recognition, Formants extraction, Phonemes, Clustering, Cross-corpus},\nabstract = {Speech Emotion Recognition (SER) has numerous applications including human-robot interaction, online gaming, and health care assistance. While deep learning-based approaches achieve considerable precision, they often come with high computational and time costs. Indeed, feature learning strategies must search for important features in a large amount of speech data. In order to reduce these time and computational costs, we propose pre-processing step in which speech segments with similar formant characteristics are clustered together and labeled as the same phoneme. The phoneme occurrence rates in emotional utterances are then used as the input features for classifiers. Using six databases (EmoDB, RAVDESS, IEMOCAP, ShEMO, DEMoS and MSP-Improv) for evaluation, the level of accuracy is comparable to that of current state-of-the-art methods and the required training time was significantly reduced from hours to minutes.}\n}\n```\n\nPaper: [Speech emotion recognition based on formant characteristics feature extraction and phoneme type convergence](https://www.sciencedirect.com/science/article/abs/pii/S0020025521001584)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftabahi%2Fformantfeatures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftabahi%2Fformantfeatures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftabahi%2Fformantfeatures/lists"}