{"id":42844104,"url":"https://github.com/transcriptaze/snyth","last_synced_at":"2026-01-30T11:55:11.046Z","repository":{"id":175475736,"uuid":"636991304","full_name":"transcriptaze/snyth","owner":"transcriptaze","description":"Experimental additive synthesiser using Jacobi ellipses as generator functions.","archived":false,"fork":false,"pushed_at":"2024-02-14T03:50:52.000Z","size":1251,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-03-15T05:55:25.345Z","etag":null,"topics":["audio","audio-worklet","synthesizers","webaudio"],"latest_commit_sha":null,"homepage":"","language":"Go","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/transcriptaze.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":"ROADMAP.md","authors":null,"dei":null}},"created_at":"2023-05-06T07:08:51.000Z","updated_at":"2024-03-15T05:55:25.345Z","dependencies_parsed_at":"2023-12-02T22:39:06.810Z","dependency_job_id":null,"html_url":"https://github.com/transcriptaze/snyth","commit_stats":null,"previous_names":["transcriptaze/snyth"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/transcriptaze/snyth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transcriptaze%2Fsnyth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transcriptaze%2Fsnyth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transcriptaze%2Fsnyth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transcriptaze%2Fsnyth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/transcriptaze","download_url":"https://codeload.github.com/transcriptaze/snyth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/transcriptaze%2Fsnyth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28912144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T08:15:08.179Z","status":"ssl_error","status_checked_at":"2026-01-30T08:14:31.507Z","response_time":66,"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":["audio","audio-worklet","synthesizers","webaudio"],"created_at":"2026-01-30T11:55:10.970Z","updated_at":"2026-01-30T11:55:11.037Z","avatar_url":"https://github.com/transcriptaze.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# snyth\n\n_tl;dr:_ the web app is [here](https://snyth.pages.dev) and there is a basic user guide [here](documentation/guide.md).\n\nBe warned, it's just barely alpha software so expect rough edges and also **please** see the [notes](documentation/NOTES.md)\nfor things like browser compatibility (basically Chrome is ok, mostly) and MIDI files.\n\nFor the only mildly curious, there are a couple of basic YouTube demo videos:\n- [Nuclear](https://youtu.be/2jzFQkDbAyU)\n- [Greensleeves](https://youtu.be/AzKBIvqoMz4)\n- [Rondo alla Turca](https://www.youtube.com/watch?v=I3ut6H6-gvE)\n- [Time (Inception)](https://youtu.be/DRVajO5q-xo)\n\n_snyth_ is an experimental additive synthesizer that uses the _Jacobi ellipse_ as the generator function. By\nadjusting the eccentricity, rotation and horizontal shift of an ellipse a single oscillator can morph smoothly\nand intuitively between sine, square, triangular and sawtooth waveforms. \n\n|                            sine                              |                       square                               |\n:-------------------------------------------------------------:|:-----------------------------------------------------------:\n| \u003cimg height=\"128\" src=\"documentation/images/sine.png\"\u003e       | \u003cimg height=\"128\" src=\"documentation/images/square.png\"\u003e   |\n|                            **triangular**                    |                       **sawtooth**                         |\n| \u003cimg height=\"128\" src=\"documentation/images/triangular.png\"\u003e | \u003cimg height=\"128\" src=\"documentation/images/sawtooth.png\"\u003e |\n\nThe canonical _snyth_ experience: \n   1. _Power up_.\n   2. Hit _Reset_ to reset everything to the most basic synthesizer.\n   3. Start the _Take Five_ MIDI (3rd slot from the top on the retro cassette tape).\n   4. And then just play with the controls to hear it come alive as you add harmonics and distortions.\n\nPlease bear in mind that this is still very early stage and experimental. Have fun!\n\n## Background\n\nAt it's most basic, additive audio synthesis typically starts with four basic functions:\n- sine \n- square\n- triangular\n- sawtooth\n\nwhich are then summed, filtered, modulated, distorted and otherwise shaped to create the desired ouput sound (e.g. [DSP function\nused by musical distortion plugins [13]](#13)). As commonly presented, the square, triangular and sawtooth waveforms are the\ntheoretical result and practical implementation of summing an infinity of sine waves to generate a harmonically rich sound.\n\nMathematically though, a sine can be seen as a special case of a Jacobi elliptic _sn_ function in the same way that\na circle is a special case of an ellipse. From there, it's a small step from using a circle as a generator function\nfor a sine wave to using the Jacobi _sn_ function and corresponding Jacobi ellipse as a harmonically rich generator\nfunction for an audio oscillator.\n\nThe Wikipedia page on the [Jacobi ellipse [1]](#1) makes this a bit clearer, although the explanation in \n[Elliptic functions as trigonometry [2]](#2) is substantially easier to follow.\n\nSome points of interest:\n - A sine is of course a special case of an ellipse with eccentricity 0.\n - Ellipses with eccentricities approaching -1 and +1 approximate the square and triangular functions (shown above).\n - An ellipse with an eccentricity between 0 and -1 _squashes_ the wave into a shape with round shoulders that is\n   very characteristic of valve distortion.\u003cbr/\u003e\u003cimg height=\"128\" src=\"documentation/images/squished.png\"\u003e\n - An ellipse with an eccentricity between 0 and 1 _squishes_ the sine into a shape reminiscent of the distortion\n   characteristic of early transistor amplifiers.\u003cbr/\u003e\u003cimg height=\"128\" src=\"documentation/images/squashed.png\"\u003e\n - A sawtooth is an asymmetric waveform which can't be directly approximated using an ellipse that is symmetric\n   about the origin, but shifting the ellipse along the horizontal axis does a reasonable job (although it's not\n   at all clear what the maths is doing - probably just huddled in a corner in horror). Stacking two _sn_ waves\n   and playing carefully with the settings produces a quite credible waveform.\u003cbr/\u003e\u003cimg height=\"128\" src=\"documentation/images/stacked.png\"\u003e\n- The square wave is continuous and continuously differentiable (which a real square wave is not) right up to the\n  limit at which the eccentricity is exactly ±1.\n\n\n### Summary\n\nAll of which means that the four separate oscillator functions can be replaced by a single not-very-complicated\nfunction that can be smoothly varied across it's range e.g. using a VCA. \n\n\n## Generalising to other shapes\n\nIn 2023, there's more to life than ellipses and with the merest smidgeon of hand-waving it's possible\nto extend the concept to other shapes. Audio-wise, the other shapes are more visually entertaining than \nacoustically radical but can be useful when creating a curve for use as an LFO. Or of course for creating\nthat idiosyncratic sound that is yours alone.\n\n### Polygons\n\nShapes that identify as convex polygons are relatively straightforward to implement and the web app includes\ntwo additional shapes:\n- square\n- cowbell\n\nConcave polygons have some weird edge cases though and need a bit more thought but should hopefully make into a \nrelease quite soon.\n\n## Getting Started\n\nThe [web app](https://snyth.pages.dev) is the easiest but if you want to run it locally the\n[Releases](https://github.com/transcriptaze/snyth/releases) section has executables for:\n\n- Linux\n- MacOS\n- Windows\n\nDownload the executable for your operating system to the folder of your choice, run it and then open http://localhost:9000\nin a web browser. \n\n### Building from source\n\nRequired tools:\n- [Go 1.20+](https://go.dev)\n- [sass](https://sass-lang.com)\n- [eslint](https://eslint.org) (optional but recommended)\n- [eslint-config-standard](https://www.npmjs.com/package/eslint-config-standard) (optional but recommended)\n- make (optional but recommended)\n\n**NOTES:**\n\n1. `apt install sass` on Ubuntu installs `ruby-sass` which was marked **[obsolete](https://sass-lang.com/ruby-sass)**\nin 2019. Please follow the installation instructions on the [Sass homepage](https://sass-lang.com) to install\nthe current version._\n\n2. The _make_ build uses `eslint` and `eslint_config_standard`. `eslint_config_standard` is a **dev** dependency and\nshould be installed locally in the project:\n\n    * Initial project setup:\n```\ngit clone --recurse-submodules https://github.com/transcriptaze/snyth.git\ncd snyth\n```\n   * To build using the included Makefile:\n```\ncd snyth-js\nmake build\ncd ../snythd\nmake build\nmake debug\n```\n   * Without using `make`:\n```\ncd snyth-js\nsass --no-source-map sass/themes:html/css\ncd ../snythd\ngo fmt ./...\nmkdir -p bin\ngo build -mod readonly --trimpath -o bin ./...\n./bin/snythd --debug --html ../snyth-js/html\n```\n\n## Waivers and Demurrers\n\nThis seems to be a relatively unexplored approach which is surprising considering the basic simplicity. It's quite\npossibly just lurking somewhere under a different name, but the only related work I've stumbled across so far is:\n\n- Lance Putnam's [thesis [3]](#3) and [publications [4]](#4) which approach it from a different direction\n  (pattern generation).   \n- Agostino Di Scipio's two papers on audio synthesis using iterated non-linear functions (with an implementation\n  in Supercollider):\n  - [Synthesis Of Environmental Sound Textures by Iterated Nonlinear Functions [7]](#7)\n  - [Iterated Nonlinear Functions as a Sound-Generating Engine [7]](#7)\n  - [SuperCollider:GFIS [8]](#8)\n\n\n## Contributing\n\nThis is an umbrella repository and all the actual code lives in submodules:\n\n- [snyth-js](https://github.com/transcriptaze/snyth-js) for the HTML, CSS and Javascript source that go to \n  make up the web app. The actual web-app is a rollup'd version of this repo.\n- [snyth-pd](https://github.com/transcriptaze/snyth-pd) is a basic implementation in _PureData_. At the moment\n  there isn't much beyond a basic working demo.\n- [snyth-supercollider](https://github.com/transcriptaze/snyth-supercollider) is a _Supercollider_ UGen for the \n  basic _sn_ function and a couple of demo scripts.\n- [sn-vcv](https://github.com/transcriptaze/sn-vcv) is a set of _VCV Rack_ modules that implement a VCO and LFO\n  for the _sn_ function.\n\nPlease see the READMEs for the respective modules for submitting bug reports, issues, feature requests, etc.\n\n\n### MIDI\n\nIt would be great to have a selection of really good demo MIDI files but it's probably legally murky unless \nthe arrangements are clearly copyright free. Having said which, if you do have a MIDI file that you would \nlike to share:\n\n1. Please create a pull request against the [MIDI](https://github.com/transcriptaze/snyth/tree/midi) branch of\n   this repository.\n2. The pull request should:\n   - Update the MIDI files list with a link to where the MIDI file is hosted\n   - Include the MIDI file\n   - Include a _snyth.json_ file\n3. After merging the pull request the MIDI files themselves will be stashed somewhere safe (but in good company) \n   until the legal situation is clearer.\n\nArrangements of classical music are mostly copyright free but be aware that some are copyrighted by the arranger.\n\n\n## Licensing\n\nEverything in this repository and all it's submodules is licensed under [GPL-3.0](https://github.com/transcriptaze/snyth-js/blob/master/LICENSE). \n\n\n## References and Related\n\n\u003ca id=\"1\"\u003e1.\u003c/a\u003e [Jacobi_elliptic_functions](https://en.wikipedia.org/wiki/Jacobi_elliptic_functions#Definition_as_trigonometry:_the_Jacobi_ellipse)  \n\u003ca id=\"2\"\u003e2.\u003c/a\u003e [Elliptic functions as trigonometry](https://iopscience.iop.org/book/mono/978-1-6817-4230-4/chapter/bk978-1-6817-4230-4ch1)  \n\u003ca id=\"3\"\u003e3.\u003c/a\u003e [Lance Putnam: The Harmonic Pattern Function: A Mathematical Model Integrating Synthesis of Sound and Graphical Patterns](https://w2.mat.ucsb.edu/l.putnam/papers/ljp_diss_final.pdf)  \n\u003ca id=\"4\"\u003e4.\u003c/a\u003e [Lance Putnam: List of Publications](https://w2.mat.ucsb.edu/l.putnam)  \n\u003ca id=\"5\"\u003e5.\u003c/a\u003e [The history of the universe is an elliptic curve](https://arxiv.org/abs/1411.2192)  \n\u003ca id=\"6\"\u003e6.\u003c/a\u003e [The Synthesis of Environmental Sound Textures by Iterated Nonlinear Functions and its Ecological Relevance to Perceptual Modeling](https://www.academia.edu/84487853/The_Synthesis_of_Environmental_Sound_Textures_by_Iterated_Nonlinear_Functions_and_its_Ecological_Relevance_to_Perceptual_Modeling)  \n\u003ca id=\"7\"\u003e7.\u003c/a\u003e [Iterated Nonlinear Functions as a Sound Generating](https://direct.mit.edu/leon/article-abstract/34/3/249/44078/Iterated-Nonlinear-Functions-as-a-Sound-Generating)  \n\u003ca id=\"8\"\u003e8.\u003c/a\u003e [SuperCollider:GFIS](https://pustota.basislager.org/_/sc-help/Help/Classes/GFIS.html)  \n\u003ca id=\"9\"\u003e9.\u003c/a\u003e [Mathematicians Complete Quest to Build Spherical Cubes](https://www.quantamagazine.org/mathematicians-complete-quest-to-build-spherical-cubes-20230210)  \n\u003ca id=\"10\"\u003e10.\u003c/a\u003e [Chaos Theory for Synthesizers](http://ijfritz.byethost4.com/Chaos/ch_over.htm)  \n\u003ca id=\"11\"\u003e11.\u003c/a\u003e [Introduction to the Transcendent Waveform Analog Oscillator ](https://www.youtube.com/watch?v=xdjGRF7Wtwg)  \n\u003ca id=\"12\"\u003e12.\u003c/a\u003e [Spatial Audio, Francis Rumsey](https://www.routledge.com/Spatial-Audio/Rumsey/p/book/9780240516233)  \n\u003ca id=\"13\"\u003e13.\u003c/a\u003e [DSP function used by musical distortion plugins](https://dsp.stackexchange.com/questions/87879/dsp-function-used-by-musical-distortion-plugins)  \n\u003ca id=\"13\"\u003e13.\u003c/a\u003e [Poly Rhythms](https://www.youtube.com/watch?v=Lxs4cvSximc)  \n\n\n## Attributions\n\n1. FFT by [Project Nayuki](https://www.nayuki.io/page/free-small-fft-in-multiple-languages).\n2. The _Greensleeves Too_ MIDI is based on _Charles Duncan's_ fingerstyle guitar arrangement.\n3. Loop, settings and info icons by [onlinewebfonts.com](http://www.onlinewebfonts.com/icon).\n4. Save icon (https://www.iconarchive.com/show/flatwoken-icons-by-alecive/Apps-File-Save-icon.html)\n5. Sound wave icon (https://clipground.com/images/sound-wave-icon-png.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftranscriptaze%2Fsnyth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftranscriptaze%2Fsnyth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftranscriptaze%2Fsnyth/lists"}