{"id":42050766,"url":"https://github.com/rimio/specgram","last_synced_at":"2026-01-26T06:35:46.150Z","repository":{"id":86669388,"uuid":"320373589","full_name":"rimio/specgram","owner":"rimio","description":"Small program that computes and plots spectrograms, either in a live window or to disk, with support for stdin input.","archived":false,"fork":false,"pushed_at":"2025-08-03T16:47:14.000Z","size":14261,"stargazers_count":11,"open_issues_count":6,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-03T18:26:42.321Z","etag":null,"topics":["audio","audio-visualization","fft","spectrogram","stdin"],"latest_commit_sha":null,"homepage":"","language":"C++","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/rimio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-12-10T19:45:22.000Z","updated_at":"2025-05-24T15:49:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"844f829b-ed23-4120-844a-b1a01a29cfd8","html_url":"https://github.com/rimio/specgram","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/rimio/specgram","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rimio%2Fspecgram","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rimio%2Fspecgram/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rimio%2Fspecgram/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rimio%2Fspecgram/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rimio","download_url":"https://codeload.github.com/rimio/specgram/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rimio%2Fspecgram/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28768466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T03:54:34.369Z","status":"ssl_error","status_checked_at":"2026-01-26T03:54:33.031Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["audio","audio-visualization","fft","spectrogram","stdin"],"created_at":"2026-01-26T06:35:45.684Z","updated_at":"2026-01-26T06:35:46.145Z","avatar_url":"https://github.com/rimio.png","language":"C++","readme":"# specgram\n\n![build](https://github.com/rimio/specgram/workflows/build/badge.svg)\n\nSmall program that computes and plots spectrograms, either in a live window or to disk, with support for stdin input.\n\n## Preview\n\n![example](resources/readme_images/example.png?raw=true \"Example\")\n\n## Build and install\n\nIf you are using ArchLinux you can grab the latest release from the AUR package [specgram](https://aur.archlinux.org/packages/specgram/), or get the main branch with [specgram-git](https://aur.archlinux.org/packages/specgram-git/).\n\nOtherwise, you can build and install the program from source:\n```bash\n# Clone the repo\ngit clone https://github.com/rimio/specgram.git\ncd specgram \u0026\u0026 mkdir build \u0026\u0026 cd build\n\n# Build\ncmake ..\nmake\n\n# Install\nsudo make install\n```\n\n## Dependencies\n\nThis program dynamically links against [FFTW](http://www.fftw.org/) and [SFML 3.0](https://www.sfml-dev.org/).\n\nThe source code of [Taywee/args](https://github.com/Taywee/args) is embedded in the program (see ```src/args.hxx```).\n\n## Usage\n\nFor a complete description of the program functionality please see the [manpage](man/specgram.1.pdf).\n\n### Input and output modes\n\n**specgram** has two mutually exclusive input methods: from standard input and from file.\n\nIn order to generate a spectrogram from an input file ```infile``` and write the output to ```output.png```:\n\n```bash\nspecgram -i infile outfile.png\n```\n\nIf no input file is specified, then the default behaviour is to read input data *indefinitely* from standard input.\nFor example, we can query PulseAudio for audio sources:\n\n```bash\n$ pactl list sources short\n1\talsa_output.usb-BEHRINGER_UMC204HD_192k-00.analog-surround-40.monitor\tmodule-alsa-card.c\ts16le 4ch 44100Hz\tIDLE\n2\talsa_input.usb-BEHRINGER_UMC204HD_192k-00.analog-stereo\tmodule-alsa-card.c\ts32le 2ch 44100Hz\tSUSPENDED\n3\talsa_output.pci-0000_00_1f.3.iec958-stereo.monitor\tmodule-alsa-card.c\ts16le 2ch 44100Hz\tSUSPENDED\n4\tstereo.A.monitor\tmodule-remap-sink.c\ts16le 2ch 44100Hz\tIDLE\n5\tstereo.B.monitor\tmodule-remap-sink.c\ts16le 2ch 44100Hz\tSUSPENDED\n11\talsa_output.pci-0000_01_00.1.hdmi-stereo.monitor\tmodule-alsa-card.c\ts16le 2ch 44100Hz\tSUSPENDED\n\n$ export PASOURCE=\"stereo.A.monitor\"\n```\n\nIn my case the default sink is ```stereo.A```, and I use the monitor source ```stereo.A.monitor``` to capture what I'm hearing in my headphones:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram outfile.png\n[2020-12-27 15:56:15.058] [info] Creating 1024-wide FFTW plan\n[2020-12-27 15:56:15.058] [info] Input stream: signed 16bit integer at 44100Hz\n```\n\nThe program will keep reading data and computing FFTs until end of times or until it receives a ```SIGINT```.\nIn the Linux terminal this can be achieved by pressing ```CTRL+C```.\n\nOnce the signal is received, the program stops reading data from input and writes to ```outfile.png``` whatever it cached so far:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram outfile.png\n[2020-12-27 15:57:29.967] [info] Creating 1024-wide FFTW plan\n[2020-12-27 15:57:29.967] [info] Input stream: signed 16bit integer at 44100Hz\n^C[2020-12-27 15:57:31.813] [info] Terminating ...\n```\n\nIt is sometimes useful to see the spectrogram in real time. Live mode can be enabled with the ```-l, --live``` flag:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l outfile.png\n```\n\nThe spectrogram will now be displayed as it is being compute from standard input.\nWhen either ```SIGINT``` is received or the live window is closed, the program will terminate and write ```outfile.png```.\n\nIf file output is not desired, only live mode can be used, and nothing is written upon termination:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l\n```\n\nFor obvious reasons, live mode cannot be used with file input.\n\n### Input options\n\nIn the above examples we assumed that the program input is 16-bit signed integer at 44.1kHz, which happens to be what my sound card (and many others) outputs by default.\n\nWe can, however, specify any other rate with ```-r, --rate``` and datatype with ```-d, --datatype```:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw --format=float32 --rate=48000 | specgram -l -r 48000 -d f32\n```\n\nThe above example will read 32-bit floating point input at 48kHz.\nFor a full list of supported data types see the [manpage](man/specgram.1.pdf).\n\n**NOTE:** The specified rate is used only for display purposes and for interpreting other command line parameters.\nThere's nothing stopping us from using a different rate than the actual device rate, going down to nanohertz:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -r 1e-8\n```\n\n#### Usage with FFmpeg\n\nIn order to generate a spectrogram for an encoded audio file, it is neccesarily to decode it first. This can be done with FFmpeg, using any of the [raw audio formats available](https://trac.ffmpeg.org/wiki/audio%20types#SampleFormats).\n\nFor example, to generate the spectrogram for an MP3 file:\n\n```bash\n$ ffmpeg -i input.mp3 -f s16le - | specgram output.png\n```\n\nOr, in order to use 32-bit data:\n\n```bash\n$ ffmpeg -i input.mp3 -f s32le - | specgram -d s32 output.png\n```\nNote that you will have to manually stop specgram with a SIGINT once the ffmpeg stream is finished.\n\n### FFT options\n\nThe FFT window width can be specified with ```-f, --fft_width``` and the stride, that is the distance between the beginning of two subsequent FFT windows, can be specified with ```-g, --fft_stride```:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -f 2048 -g 1024 \n```\n\nThe above will compute 2048 elements wide FFT windows with a stride of 1024 elements, that is with a 50% overlap between windows.\n\nUsually, a larger FFT window will give better frequency resolution but worse time resolution (i.e. it will be harder to locate signals in the time domain).\n\nA smaller stride will give a *smoother* and richer output, but will strain the CPU more.\n\n**NOTE:** You will notice that there isn't much difference between the output of the above command and the others.\nThat is because the display width is different from the FFT window width.\nTo change the display width, see **Display Options** below.\n\nLastly, if you encounter high sample rate signals, for which you can't display a wide enough (or often enough) window, you can use window averaging (```-A, --average```).\n\n```bash\n$ rx_sdr -d 0 -g 50 -f 97300000 -s 960000 -F CF32 - | ./specgram -lq -r 960000 -d cf32 -A 20 \n```\n\nThe above example consumes input at 960k samples per second from a RTL-SDR dongle, which at a 1024 wide FFT window would mean displaying over 900 windows per second; a bit much for the average PC, and for the average human to follow.\n\nAveraging 20 windows gives us a much more reasonable 47 windows per second.\n\n### Display options\n\nTo change the display width we can use ```-w, --width```:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -f 1024 -w 1024\n```\n\nAs you will notice, the spectrogram is somewhat blurry, because the program is resampling the 513 element wide positive part of the FFT output to the display width of 1024.\nIf you need sharp, crisp spectrograms, then you can use ```-q, --no_resampling``` to disable resampling:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -lq -f 1024\n```\nWhen not resampling, you can no longer specify the display width, as it is computed from the rest of the parameters.\n\nAnother use case is displaying a specific band of frequencies, using ```-x, --fmin``` and ```-y, --fmax``` to set the frequency bounds.\nFor example, to zoom in on the 500-3000Hz band:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -lq -f 9192 -x 500 -y 3000 \n```\n\nThe colormap can be specified with ```-c, --colormap```; see image below the example for supported colormaps:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -c orange\n```\n\n![colormaps](resources/readme_images/colormaps.png?raw=true \"Colormaps\")\n\nIn order to see how to specify the background, foreground and custom colormap colors, please see the [manpage](man/specgram.1.pdf).\n\nWhile the live view has both axes and legend enabled by default, file output does not.\nTo enable them use ```-a, --axes``` or ```-e, --legend```.\nPlease note that axes are implicit when displaying the legend.\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -le outfile.png\n```\n\nFinally, if you'd like to rotate the spectrogram 90 degrees counter-clockwise, so as to read it from left to right, you can use ```-z, --horizontal```:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -lz\n```\n\nThis flag applies to both the live window and output file.\n\n### Live options\n\nUse ```-k, --count``` to control the number of FFT windows displayed in live view:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -k 128\n```\n\nUse ```-t, --title``` to specify the live window title:\n\n```bash\n$ parec --channels=1 --device=\"${PASOURCE}\" --raw | specgram -l -t \"My spectrogram\"\n```\n\n## License\n\nCopyright (c) 2020-2023 Vasile Vilvoiu \\\u003cvasi@vilvoiu.ro\u003e\n\n**specgram** is free software; you can redistribute it and/or modify it under the terms of the MIT license.\nSee LICENSE for details.\n\n## Acknowledgements\n\nTaywee/args library by Taylor C. Richberger and Pavel Belikov, released under the MIT license.\n\nProgram icon by Flavia Fabian, released under the CC-BY-SA 4.0 license.\n\nShare Tech Mono font by Carrois Type Design, released under Open Font License.\n\nSpecial thanks to Eugen Stoianovici for code review and various fixes.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frimio%2Fspecgram","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frimio%2Fspecgram","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frimio%2Fspecgram/lists"}