{"id":13564160,"url":"https://github.com/novoic/surfboard","last_synced_at":"2025-04-03T21:30:28.189Z","repository":{"id":43371426,"uuid":"264249526","full_name":"novoic/surfboard","owner":"novoic","description":"Novoic's audio feature extraction library","archived":false,"fork":false,"pushed_at":"2022-03-04T23:04:03.000Z","size":612,"stargazers_count":427,"open_issues_count":11,"forks_count":47,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-04-24T20:27:25.383Z","etag":null,"topics":["alzheimers-disease","audio","audio-processing","feature-extraction","healthcare","machine-learning","parkinsons-disease","python","signal-processing","speech-processing"],"latest_commit_sha":null,"homepage":"https://novoic.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/novoic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-15T16:54:18.000Z","updated_at":"2024-04-11T09:17:30.000Z","dependencies_parsed_at":"2022-09-26T21:21:01.842Z","dependency_job_id":null,"html_url":"https://github.com/novoic/surfboard","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novoic%2Fsurfboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novoic%2Fsurfboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novoic%2Fsurfboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/novoic%2Fsurfboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/novoic","download_url":"https://codeload.github.com/novoic/surfboard/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246717557,"owners_count":20822565,"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":["alzheimers-disease","audio","audio-processing","feature-extraction","healthcare","machine-learning","parkinsons-disease","python","signal-processing","speech-processing"],"created_at":"2024-08-01T13:01:27.345Z","updated_at":"2025-04-03T21:30:27.571Z","avatar_url":"https://github.com/novoic.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003ca href=\"https://novoic.com\"\u003e\n    \u003cimg src=\"https://assets.novoic.com/surfboard.png\" alt=\"surfboard-logo\" border=\"0\"\u003e\n\u003c/a\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003ca href='https://surfboard.readthedocs.io/en/latest/?badge=latest'\u003e\n    \u003cimg src='https://readthedocs.org/projects/surfboard/badge/?version=latest' alt='Documentation Status' /\u003e\n\u003c/a\u003e\n\u003ca href='https://app.circleci.com/pipelines/github/novoic/surfboard'\u003e\n    \u003cimg src='https://circleci.com/gh/novoic/surfboard.svg?style=shield\u0026circle-token=a1b00a7def3a0a97090888e7380b771f58836046' alt='Build Status' /\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n_A Python package for modern audio feature extraction_\n\nFor information about contributing, citing, licensing (including commercial licensing) and getting in touch, please see [our wiki](https://github.com/novoic/surfboard/wiki).\n\nOur documentation can be found [here](https://surfboard.readthedocs.io/en/latest). Our paper can be found [here](https://arxiv.org/abs/2005.08848). \n\nPlease join our [Slack channel](https://join.slack.com/t/surfboard-novoic/shared_invite/zt-f5usu4qo-PHLEyOTk8NE1lfn_hHnxoA) if you have questions or suggestions!\n\n## :surfer: Installation :surfer:\n\nInstall using pip\n```bash\npip install surfboard\n```\n\nAlternatively,\n* Clone the repo: `git clone https://github.com/novoic/surfboard.git`\n* Navigate into the repo: `cd surfboard`\n* Install the repo: `pip3 install .`\n\n## Quickstart (be cooler than [Bodhi in Point Break](https://youtu.be/LniUPlffoB0) in 2 minutes)\n\n### Example 0: Compute features using Python\nGiven a set of components and an optional set of statistics to apply to the time-varying components, extract them using Python.\n```python\nfrom surfboard.sound import Waveform\nfrom surfboard.feature_extraction import extract_features\n\nsound = Waveform(path='/path/to/audio.wav')\n\n# Option 1: Extract MFCC and RMS energy components as time series.\ncomponent_dataframe = extract_features([sound], ['mfcc', 'rms'])\n\n# Option 2: Extract the mean and standard deviation of the MFCC and RMS energy features over time.\nfeature_dataframe = extract_features([sound], ['mfcc', 'rms'], ['mean', 'std'])\n\n# Option 3: Extract MFCC and RMS energy features as time series with non-default arguments.\nmfcc_with_arg = {'mfcc': {'n_mfcc': 26, 'n_fft_seconds': 0.08, 'hop_length_seconds': 0.02}}\nfeature_with_args_dataframe = extract_features([sound], [mfcc_with_arg, 'rms'], ['mean', 'std'])\n```\n\n### Example 1: Compute audio features from a folder of `.wav` files\nAssume the following directory structure:\n```\nmy_wav_folder/\n│   swell.wav\n│   cool_hair.wav\n|   wave_crash.wav\n|   ...\n```\nUsing a `.yaml` config (see `example_configs` for examples), you can use the surfboard CLI to return a `.csv` file containing a set of features computed for every `.wav` file in `my_wav_folder`. You can optionally use multiple processes with the `-j` flag.\n```bash\nsurfboard compute-features -i my_wav_folder -o cool_features.csv -F surfboard/example_configs/spectral_features.yaml -j 4\n```\n\n### Example 2: Create a custom `.yaml` config\nYou can create a custom `.yaml` config in order to extract specific features from your audio data. You can also pick specific statistics to apply to the time-varying components. The set of available statistics is described in the __Available statistics__ section below.\n\nTake a peak at the example configs in `surfboard/example_configs/`. The package assumes a `.yaml` file with the following structure:\n```yaml\ncomponents:\n  - mfcc\n      n_mfcc: 26\n  - log_melspec\n      n_mels: 64\n  \nstatistics:\n  - mean\n  - std\n```\n\nThis config will compute the mean and standard deviation of every MFCC (13 by default but set to 26 here) and log mel-spectrogram filterbank (128 by default but 64 here) on every `.wav` file in `my_wav_folder` if called with the following command:\n```bash\nsurfboard compute-features -i my_wav_folder -o epic_features.csv -F my_config.yaml\n```\n\n### Example 3: Use the `compute-components` functionality\nSometimes you might want to retain the time axis of time-dependent components but still use the CLI. Given a `.yaml` config without a `statistics` section, you can. It will dump the components as `.pkl` file which can be loaded with `pd.read_pickle`.\n```bash\nsurfboard compute-components -i my_wav_folder -o epic_features.pkl -F surfboard/example_configs/chroma_components.yaml\n```\n\n## Example 4: \nWe have provided notebooks in `notebook_tutorials` for examples of how Surfboard can be used to extract features from audio and even to perform environmental sound classification.  \nOtherwise, here are some examples:\n\nDefine a waveform:\n```python\nfrom surfboard.sound import Waveform\nimport numpy as np\n\n# Instantiate from a .wav file.\nsound = Waveform(path=\"/surf/in/USA/sound.wav\", sample_rate=44100)\n\n# OR: instantiate from a numpy array.\nsound = Waveform(signal=np.sin(np.arange(0, 2 * np.pi, 1/24000)), sample_rate=44100)\n```\nGet the F0 contour:\n```python\nimport matplotlib.pyplot as plt\nf0_contour = sound.f0_contour()\nplt.plot(f0_contour[0])\n```\nGet the MFCCs:\n```python\nmfccs = sound.mfcc()\n```\nGet different shimmers, jitters, formants:\n```python\nshimmers = sound.shimmers()\njitters = sound.jitters()\nformants = sound.formants()\n```\n\n## Available components\n\nYou can take a look at `COMPONENTS.md` to see which components can be computed using Surfboard.\n\nThere is extensive documentation in the method docstrings in `surfboard/sound.py`. Please refer to those for more details on each individual feature (or to our documentation, alternatively). \n\n\n## Available statistics\n\nA thorough list of the statistics implemented in Surfboard can be found in `STATISTICS.md`\n\nOften, the components computed from the `surfboard.sound.Waveform` class have a time dimension, in which case they are represented as numpy arrays with shape `[n_components, T]`. For example a log mel spectrogram can be an array with shape `[128, T]`. We often want a fixed-length representation of variable length audio signals. Hence, we need to somehow aggregate the time dimension. \n\nFollowing best practices, we have implemented a variety of statistics which take an array with shape `[n_components, T]` and return an array with shape `[n_components,]`, aggregating each component along the time dimension with a statistic. These are implemented in `surfboard/statistics.py`.\n\n## Tests\n\nSome very rudimentary tests have been implemented in the `tests` directory, to make sure that methods run successfully. Feel free to use them while developing new components/statistics. \n\n## FAQs\n\n* __What are these components with `_slidingwindow` at the end?__ A lot of the components above are defined as floating point numbers computed from a sequence of arbitrary length. Sometimes, it makes more sense to see how these metrics change over time as a sliding window hovers over the waveform. This is what \"sliding window\" means here: we compute the component on a sliding window.\n* __How do I know what data structure is returned by `sound.{}?`__ Try it out! Otherwise, take a look at our documentation, or the docstrings in `surfboard/sound.py` to see the returned types. \n* __Can I use Surfboard on `.mp3` files?__ Yes, but it might take a while longer than if you ran Surfboard on `.wav` files because of how LibROSA loads `.mp3` files. For large jobs, we advise first converting `.mp3` files to `.wav` files using ffmpeg.\n* __Why are some of the rows returned in the `.csv` files obtained from the CLI full of NaNs?__ Sometimes, the feature extraction can fail either for a specific component/statistic, or for an entire audio file. This can have a variety of reasons. When such a failure occurs, we populate the dataframe with a NaN.\n* __I am getting weird exceptions when extracting features. Is this okay?__ This is completely normal. Sometimes the extraction of a specific component/statistic can fail or raise warnings. \n\n## License\n\nSurfboard is released under dual commercial and open source licenses. This is the open-source (GPL v3.0) version. See `LICENSE` for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnovoic%2Fsurfboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnovoic%2Fsurfboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnovoic%2Fsurfboard/lists"}