{"id":39176114,"url":"https://github.com/cristoper/wav2vec","last_synced_at":"2026-01-17T22:28:35.301Z","repository":{"id":62588275,"uuid":"101432496","full_name":"cristoper/wav2vec","owner":"cristoper","description":"Python package and cli tool to convert wave files (WAV or AIFF) to vector graphics (SVG, PostScript, CVS)","archived":false,"fork":false,"pushed_at":"2026-01-03T03:16:49.000Z","size":6053,"stargazers_count":110,"open_issues_count":1,"forks_count":12,"subscribers_count":7,"default_branch":"master","last_synced_at":"2026-01-17T22:23:52.825Z","etag":null,"topics":["aiff","audio","cli","graphics","postscript","python","python3","svg","wav","waveform"],"latest_commit_sha":null,"homepage":"","language":"PostScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cristoper.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"cristoper","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2017-08-25T18:42:56.000Z","updated_at":"2026-01-16T14:16:29.000Z","dependencies_parsed_at":"2025-09-06T06:27:11.176Z","dependency_job_id":null,"html_url":"https://github.com/cristoper/wav2vec","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cristoper/wav2vec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristoper%2Fwav2vec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristoper%2Fwav2vec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristoper%2Fwav2vec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristoper%2Fwav2vec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cristoper","download_url":"https://codeload.github.com/cristoper/wav2vec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cristoper%2Fwav2vec/sbom","scorecard":{"id":308996,"data":{"date":"2025-08-11","repo":{"name":"github.com/cristoper/wav2vec","commit":"457eddbbf42135e07ffb091a3a970742378de231"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Do What The F*ck You Want To Public License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T22:47:48.374Z","repository_id":62588275,"created_at":"2025-08-17T22:47:48.374Z","updated_at":"2025-08-17T22:47:48.374Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28520526,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["aiff","audio","cli","graphics","postscript","python","python3","svg","wav","waveform"],"created_at":"2026-01-17T22:28:34.704Z","updated_at":"2026-01-17T22:28:35.288Z","avatar_url":"https://github.com/cristoper.png","language":"PostScript","readme":":toc:\n:toc-placement!:\n\n= wav2vec\n\ntoc::[]\n\n== Introduction\n\n`wav2vec` is a Python script and package for converting waveform files (WAV or AIFF) to vector graphics (SVG or PostScript). Use cases include using an audio waveform as an element in a graphic design or including a waveform in a document.\n\nNote:: This project is completely unrelated to the https://arxiv.org/abs/1904.05862[wav2vec speech recognition model] (which was published after this tool).\n\n== Features\n\n* Portable: runs on Python 2.7+ and Python 3 and does not depend on any third-party packages.\n** Python 3.13 removed several modules this tool relies on (see https://peps.python.org/pep-0594/), but those packages are still available on pypi (as `standard-aifc` and `standard-sndhdr`) and will be installed automatically if you install `wav2vec` with uv or pip.\n* Supported PCM input file formats:\n** 8-bit signed AIFF\n** 8-bit unsigned WAV\n** 16-bit signed WAV and AIFF\n** 32-bit signed WAV and AIFF\n** Floating point WAV files are not supported because they are not yet supported by the Python `wave` module (https://github.com/cristoper/wav2vec/issues/5)\n* Input file format is automatically detected and handled (the file name/extension is unimportant)\n* Output file formats:\n** Scalable Vector Graphics (SVG)\n** PostScript\n** Comma-Separated Values (CSV)\n* Easy to write a custom output formatter\n* Options to scale the output data\n* Can process input files in chunks so large files can be processed with minimal memory\n\n== Install\n\n=== From PyPI with PIP\nThe easiest way to install `wav2vec` is to use `pip` to install from the Python Package Index:\n\n[source, sh]\n----\n$ uv tool install wav2vec\n----\n\nor\n\n[source, sh]\n----\n$ pip install wav2vec\n----\n\nDepending on your system, in order to install in the Python 3 path, you may have to use `pip3` instead of `pip`.\n\n=== From git repo\n\nAlternatively, clone the git repository:\n\n[source, sh]\n----\n$ git clone https://github.com/cristoper/wav2vec.git\n$ cd wav2vec\n----\n\nIf you are running Python \u003e=3.13 then you'll also need to install the `aifc` and `sndhdr` modules:\n\n[source, sh]\n----\n$ pip install standard-aifc standard-sndhdr\n----\n\nor on Debian:\n[source, sh]\n----\n$ apt install python3-standard-aifc python3-standard-sndhdr\n----\n\nNow you can run `wav2vec.py` directly:\n\n[source, sh]\n----\n$ python wav2vec.py -h\n----\n\nOr install the package with PIP:\n\n[source, sh]\n----\n$ pip install .\n$ wav2vec -h\n----\n\n== Usage\n\nOnce the package is installed using pip (see above), the command can be invoked as `wav2vec`. It takes an input file and outputs (SVG, by default) to stdout:\n\n[source, sh]\n----\n$ wav2vec filename.wav \u003e filename.svg\n----\n\nRun `wav2vec -h` to get a usage summary:\n\n----\nusage: wav2vec [-h] [--format {PostScript,SVG,CSV}] [--width WIDTH]\n               [--height HEIGHT] [--stream BS] [--downtoss N]\n               [--log {DEBUG,INFO,WARNING,ERROR,CRITICAL}]\n               filename\n\nConvert WAV and AIFF files to vector (SVG, PostScript, CSV) graphics.\n\npositional arguments:\n  filename              The WAV file to read\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --format {PostScript,SVG,CSV}, -f {PostScript,SVG,CSV}\n                        The output format, one of: SVG, CSV, PostScript.\n                        Default is SVG.\n  --width WIDTH         Maximum width of generated SVG (graphic will be scaled\n                        down to this size in px)\n  --height HEIGHT       Maximum height of generated SVG (graphic will be\n                        scaled down to this size in px). Note that this scales\n                        according to the highest possible amplitude (given the\n                        sample bit depth), not the highest amplitude that\n                        actually occurs in the data.\n  --stream BS           Stream the input file size in chunks (of BS number of\n                        frames at a time) and process/format each chunk\n                        separately. Useful for conserving memory when\n                        processing large files, but note that multi-channel\n                        paths will be split up into BS-sized chunks. By\n                        default BS=0, which causes the entire file to be read\n                        into memory before processing.\n  --downtoss N          Downsample by keeping only 1 out of every N samples.\n  --log {DEBUG,INFO,WARNING,ERROR,CRITICAL}\n                        Set the logging level.\n\nThe output is sent to stdout.\n\n----\n\n=== Options\n==== Output format\n\nThe `--format` flag sets the output format. `wav2vec` includes three formatters: `SVG` (default if no `--format` is given), `PostScript`, and `CSV`.\n\n[source, sh]\n----\n$ wav2vec filename.wav --format PostScript \u003e output.ps\n----\n\n==== Scale output\n\nUse the `--width` and `--height` options to scale the output so that its maximum bounds are equal to or less than the values following the flags. In SVG these values are pixels (\"user units\"); in PostScript the values are interpreted as pts (1/72 of an inch). By default (if the flags are not given), the width is set to 1000 and the height to 500.\n\n[source, sh]\n----\n$ wav2vec filename.wav --width 500 --height 350 \u003e output.svg\n----\n\n==== Stream input file\n\nBy default, `wav2vec` reads the entire input file into memory and then streams the output to stdout as it process it. Passing the `--stream` flag will cause `wav2vec` to process the input file in chunks. This can be useful if the input file is very big and won't fit into available memory. The `--stream` flag requires one argument, the number of frames to read and process at a time (each frame includes one sample from each channel). A value of around 1024 seems to work well.\n\n[source, sh]\n----\n$ wav2vec filename.aiff --stream 1024 \u003e output.svg\n----\n\nNote that using the `--stream` flag on files with multiple channels will result in non-continuous paths in the output (because channel data is interleaved in WAV/AIF files).\n\nNote also that converting very large audio files to SVG may not be practical: most SVG editors will not handle paths with hundreds of thousands or millions of points well.\n\n==== Downsampling\n\nThe `--downtoss N` flag will keep only 1 out of every N samples. This is a brutal form of downsampling which will clobber high frequency and add aliasing noise. It's best to instead downsample in your waveform recorder/editor before processing (or in your drawing program after processing).\n\n=== API\n\nYou can also `import wav2vec` in order to convert wave files to the supported output formats in your own Python scripts. The package provides two main classes: `WavDecoder` and the abstract `Formatter` (and the concrete implementations: `SVGFormatter`, `PSFormatter`, and `CSVFormatter`). The documentation is currently contained in the source files; look at link:./wav2vec/main.py[main.py] for an example of usage.\n\nThe `WavDecoder` class wraps the standard library's `wave` and `aifc` modules and provides an easy way to read and decode WAV/AIFF files.  Use it as a context manager to ensure `close()` is called. Use it as an iterator to process all frames:\n\n[source, python]\n----\n\u003e\u003e\u003e wd = WavDecoder('filename')\n\u003e\u003e\u003e with wd as data:\n\u003e\u003e\u003e     for frames in data:\n\u003e\u003e\u003e         print(frames)\n----\n\nSee link:./wav2vec/WavDecoder.py[wav2vec/WavDecoder.py].\n\nThe `Formatter` class is an abstract base class which defines the interface for all formatters which output WAV data in textual formats. Each concrete subclass of `Formatter` takes a `WavDecoder` object in its constructor which is what is responsible for reading/decoding data from a WAV or AIFF file.\n\nThe `output()` method will stream output to a file (stdout by default), but the entire output string can be captured using the `__str__()` method.\n\n[source, python]\n----\n\u003e\u003e\u003e wd = WavDecoder(\"filename\")\n\u003e\u003e\u003e svgformatter = SVGFormatter(wd)\n\u003e\u003e\u003e svgformatter.output() # outputs SVG to stdout\n\u003e\u003e\u003e svg_str = str(svgformatter) # get SVG as a string\n----\n\nSee link:./wav2vec/formatter/[the formatter package].\n\n=== Examples\n\n==== SVG\n\nHere's what the link:tests/valfiles/snd/test-16-stereo.wav[tests/valfiles/snd/test-16-stereo.wav] file looks like in Audacity:\n\nimage::./readme_imgs/audacity.png[]\n\nWe can convert it to an SVG and then open it in Inkscape:\n\n[source, sh]\n----\n$ wav2vec tests/valfiles/snd/test-16-stereo.wav \u003e test.svg\n$ inkscape test.svg\n----\n\nimage::./readme_imgs/inkscape.png[]\n\nThen we can use Inkscape to non-destructively add filters and path effects and otherwise incorporate the waveform into a design:\n\nimage::./readme_imgs/output.png[]\n\n==== PostScript\n\nTo convert to PostScript instead of SVG:\n\n[source, sh]\n----\n$ wav2vec tests/valfiles/snd/test-16-stereo.wav -f PostScript \u003e test.ps\n$ ps2pdf test.ps\n$ evince test.pdf\n----\n\nThe above uses the Ghostscript `ps2pdf` tool to convert the resulting PostScript file to PDF and then opens it in the evince PDF reader (shown in the screenshot below). You could instead open `test.ps` directly in a PostScript viewer (or send it to a printer/plotter, or embed it in a LaTeX document, etc).\n\nimage::./readme_imgs/evince.png[]\n\n==== CSV\n\n`wav2vec` also comes with a CSV formatter, which is useful to get WAV data into a spreadsheet:\n\n[source, sh]\n----\n$ wav2vec tests/valfiles/snd/test-16-stereo.wav -f CSV --height 0 \u003e test.csv\n$ libreoffice test.csv\n----\n\nNote the `--height 0` option which prevents `wav2vec` from scaling the raw PCM values.\n\n== Hacking\n\n=== Run tests\n\nTo run unit and validation tests (requires python3):\n\n[source, sh]\n----\n$ python -m unittest discover\n----\n\n=== Write custom formatter\n\nCreating a custom formatter is simply a matter of subclassing `Formatter` and overriding the five abstract methods it defines. Use the included SVGFormatter, PSFormatter, or CSVFormatter as a template (see link:./wav2vec/formatter/formatters.py[wav2vec/formatter/formatters.py]).\n\n== Issues\n\nPlease feel free to use the Github issue tracker as a support forum for any questions, suggestions, bug reports, or feature requests. Thanks! https://github.com/cristoper/wav2vec/issues\n\n== See also\n\n- http://www.audacityteam.org/[Audacity] is a good Free audio recorder and waveform editor.\n- https://inkscape.org/en/[Inkscape] is a Free SVG-based drawing program\n- https://www.ghostscript.com/[Ghostscript] is a Free PostScript interpreter which can distill to PDF.\n\n- https://github.com/afreiday/php-waveform-svg[php-waveform-svg] is a PHP script for converting mp3-\u003ewav-\u003esvg. (It looks simple, but I haven't tried it.)\n","funding_links":["https://ko-fi.com/cristoper"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristoper%2Fwav2vec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcristoper%2Fwav2vec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcristoper%2Fwav2vec/lists"}