11 ms·
How to create minimal music with code in any programming language
- nijaru 6y agoSmall nitpick: CD quality is in fact 44.1khz. The nyquist theorem essentially says you need to use a sampling rate twice as high as the highest frequencies you want to record and reproduce. The article gets the gist of this right, just the cd quality numbers wrong. Izotope has a really good article that goes into digital to analog conversion, sampling rates, and the history behind them. https://www.izotope.com/en/learn/digital-audio-basics-sample-rate-and-bit-depth.html https://www.izotope.com/en/learn/digital-audio-basics-sample...
- mhh__ 6y agoAlso, this https://www.youtube.com/watch?v=cIQ9IXSUzuM https://www.youtube.com/watch?v=cIQ9IXSUzuM
- aurelian15 6y agoThe "code poem" at the beginning of the post reminds me of the "Bit Shift Variations in C-Minor" [1] by Robert S K Miles (chiptune music in 214 bytes of C; featured in the computerphile video "Code Golf & the Bitshift Variations"). [1] http://txti.es/bitshiftvariationsincminor http://txti.es/bitshiftvariationsincminor
- deleted 6y ago[deleted]
- munificent 6y agoThis is a great article! I've been interested in music software and hardware for decades and my lockdown hobby has been finally spending the time to really dig into it. It is both very challenging and very rewarding. If you want to go a little deeper than the article, here's a few more notes: The way the author generates the sawtooth and square waves is "analytically". That means treating them like a function of time and simply calculating the waveform position each point in time. As you can see, it's really simple. Unfortunately, it also introduces a ton of aliasing and will sound pretty harsh, especially at higher pitches. If you're familiar with nearest-neighbor sampling in image resizing, think about how nasty and chunky the resulting image looks when you scale it down using nearest neighbor. Analytic waveforms do the equivalent thing for audio. Fixing that problem is surprisingly hard. It's a lot like texture rendering in games where there's a bunch of filtering, tricks, and hacks you can do to make things look smooth without burning a ton of CPU cycles. --- The clever trick the author uses to simulate strings is: https://en.wikipedia.org/wiki/Karplus%E2%80%93Strong_string_synthesis https://en.wikipedia.org/wiki/Karplus%E2%80%93Strong_string_... --- The low-pass filter they show is a simple first-order 6 dB/octave digital low-pass filter. Filtering is fundamental to electronic music. The majority of synthesizers you hear in electronic music use "subtractive synthesis" which means to start with the simple sawtooth and square waves introduced early in the article and use filters to tame their harsh overtones. I find the math behind filter design, especially the moving filters used for synths, really difficult, but also interesting.
- contravariant 6y agoThis somewhat related talk about functional composition (in lisp) is also quite interesting: https://www.youtube.com/watch?v=jyNqHsN3pEc https://www.youtube.com/watch?v=jyNqHsN3pEc
- emmanueloga_ 6y agoI think I've seen that one. I also like this presentation by extempore's author [1]. It is pretty cool in that it shows how to model instruments out of simple waves and "attack, decay, sustain and release" envelope modeling. Pretty quickly he comes up with something that kind of starts sounding like real instruments (squinting a bit... :-). 1: https://www.youtube.com/watch?v=phYHOUICe7Q https://www.youtube.com/watch?v=phYHOUICe7Q
- soulofmischief 6y agoA Sorenson lecture I haven't seen yet! Thank you! Sorenson is low key one of the most innovative minds in the scene. Extempore is such a blast to work with.
- elihu 6y agoA random suggestion to make for nicer, more interesting music: the article takes pitches from a table of equal tempered note frequencies relative to A440: > For example, here’s a familiar riff “E B D E D B A B”. It uses only 4 notes - D and E from one octave and A + B from the other, lower octave. If we look at the note frequency table, the pitches of those notes in octaves 5 and 4 would be 659.2Hz (E), 587.3Hz (D), 440Hz (A) and 493.8Hz (B). Instead of equal tempered pitches (which are generated by repeatedly multiplying by the 12th root of 2), use pitches that form whole number ratios with respect to the root of your key. A decent 12-note chromatic scale would be something like 1:1, 16:15, 9:8, 6:5, 5:4, 4:3, 45:32, 3:2, 8:5, 5:3, 15:8, and 2:1. So, for instance if your root is C=256 hz, you'd have 256 hz for C, (25616)/15 for C#, (2569)/8 for D, and so on. This is a just intonation (JI) scale. An advantage of JI is that the musical intervals blend with each other better, whereas the advantage of equal temperament (ET) is that you can use any note as the root and change keys on the fly without causing problems. If you're doing electronic music, though, there's a lot less reason to stick with ET: you can always just multiply your whole tuning table by a constant if you want to switch key. JI scales can be made with any ratios: the above maps well to most conventional music, but there's no rule that you have to limit yourself to 12 steps per octave. Using the harmonic series is another option, or adding in ratios that have a 7 in them.
- reitzensteinm 6y agoMaybe a decade ago, I read a story here on HN where somebody was analyzing a singer's audio to detect how close their pitch was, coming to the conclusion that the root was spot on but other notes were slightly sharp or flat. Someone in the comments pointed out that the analysis was done assuming even temperament, and the singer was actually totally nailing just intonation. It's one of those anecdotes that has stuck with me since as a reminder to try to not get tunnel vision on a specific metric.
- andi999 6y agoThats funny. I am generally surprised how singers actually practise with a piano player (which seems to be done here often), since the piano is equally tempered. Wouldnt it make more sense tonpractise with a violin player?
- zengargoyle 6y agoMy first hacking as it were was loading the Apple ][ game Lemonade and then writing my own programs. Because Lemonade loaded a bit of code that played music and I could figure out how to play notes and durations once the magic code was loaded but not how to do the magic code myself. It took quite a while and a book on 6502 assembly and my high-school's Franklin Apple clones (Franklin had a built in assembler in the ROM) to figure out how to make that speaker beep actually play notes. My first great hack was finally being able to write a program that played music on the other Bell & Howell Black Apple machines. Then I got an Amiga and that musical note playing became trivial. Article seems a bit bogus by not going down to speaker-on/speaker-off and delay loops.
- dylan604 6y agoBack when I was kid playing with a C64, it was the DATA section at the end of BASIC programs that blew my mind. If you programmed line 10 wrong with a typo or other syntax sin, then the entire thing would fail. If you had a typo in the DATA section that was (now I know as) Hex, then the program would not fail but glitch, and it was typically with the sound/music of the game. I had no idea what Hex was, but I did realize that it was only 0-9A-F. That made the confusion of 0(zero) and O(upper-case 'oh') less of a problem during transcription. I never understood it enough to modify any of it in a useful manner, but it definitely helped avoid hunt&peck typos for a kid
- mypalmike 6y agoThat reminds me of the evolution of magazine code listings, which eventually came with per-line CRC values. If I remember correctly, there was a mod for Atari 800 BASIC where it would spit out the CRC after you typed each line of code.
- dylan604 6y agoThat's actually where I was getting my BASIC code from to transcribe. I don't remember exactly which magazine, but in my fuzzy memory, I think it was Byte.
- 6y ago
- brody_hamer 6y agoThank you! For weeks now I've been thinking about how handy it'd be if I could audibly 'listen' to the output of a command. I had no idea it was as easy as piping it to aplay. `tail -f output.txt | aplay` I know this is a lame takeaway, but I'm just so happy to learn about this.
- kortex 6y agoThis is most decidedly not lame! I'm sitting there looking at the code poem trying to figure out how the sound happens, it looks like it's just writing bytes to a file. I figured there was some driver or something but "sound driver from file" is not super googleable. aplay was the missing link.
- lloeki 6y agoThere’s /dev/dsp that you can write to (and read from). https://en.wikipedia.org/wiki/Open_Sound_System https://en.wikipedia.org/wiki/Open_Sound_System
- slx26 6y agoI find the lack of a common API for audio across OSes a tragedy. The waves are so deadly simple to work with that you could even use them as exercises to start learning programming. You would also need to be aware of the buffer you send the audio samples to; yes, you need to be aware that latency exists, there's no way around that. But in practice it's much more annoying: you have to deal with the APIs on each OS, which treat audio devices differently. Even getting info about the devices might be poorly documented and rather cumbersome, and then each device might or might not support the sample format you need/want, and might or might not support the buffer sizes you need/want. And if you try to work with a language that's not C/C++, then you have to resort to C wrappers to connect to the APIs (which in many languages is not trivial). 99% of the things we want to do could be so easy (give me a format that's 100% supported everywhere, a minimum buffer size supported everywhere, and support for 2 channels everywhere)... but nope.
- PaulDavisThe1st 6y ago
- devilduck 6y agoThat's neat, but doing sound design and creating listenable/good compositions are two different endeavors. You'd likely be better off writing an actual DSP engine in C than trying to diddle with frequencies in this way. Use Supercollider if you actually want to make music with code rather than just do little experiments like this.
- marttt 6y agoPete Elmore also recently wrote an interesting post about Bytebeat and Algorithmic Composition: http://debu.gs/entries/making-music-with-computers-two-unconventional-approaches http://debu.gs/entries/making-music-with-computers-two-uncon...
- dcanelhas 6y agoI thought CDs had a sampling rate of 44kHz? You need twice as many samples as the frequency you want to represent, after all (to make a wave you need both a positive anda negative sample in the same period). This is the essence of the Nyquist-Shannon a.k.a. the sampling theorem.
- bronlund 6y agoThat's correct. CD's has a sample rate of 44.1kHz. And humans can hear above 20kHz, it's just that most don't.
- pgt 6y agoFunctional Composition by Chris Ford: https://www.youtube.com/watch?v=Mfsnlbd-4xQ https://www.youtube.com/watch?v=Mfsnlbd-4xQ
- amboo7 6y agoI wrote this trying to compress the notes: https://github.com/amb007/sound-series https://github.com/amb007/sound-series
- FullyFunctional 6y agoThe article and this whole thread is awesome; there’s so much to learn. My only contribution is to point out that the late Hudak was very interested in making music with software and spent a significant portion of The Haskell School of Expression, https://books.google.com/books/about/The_Haskell_School_of_Expression.html?id=lQbth9j5j9oC&printsec=frontcover&source=kp_read_button https://books.google.com/books/about/The_Haskell_School_of_E... on it.
- calmchaos 6y agoGreat stuff! Now who's the first person to listen to the entire linux kernel source code? ;)
- thecodrr 6y agoHyped to see someone implement this in C#. This is great!
- yowlingcat 6y agoObligatory plug to TidalCycles [1], which is a Haskell based system folks have begun to use for live coding with IMO impressive results. [1] https://www.youtube.com/watch?v=sNj-I2pZwX8 https://www.youtube.com/watch?v=sNj-I2pZwX8
- whiddershins 6y agoVery interesting article. However, this is false: “ that’s why CD music had a sample rate of 22000 Hz. Modern sound cards however tend to use sampling rates twice as high - 44100 Hz or 48000 Hz” CDs are/were 44100 hz, they were never 22000, because you need two samples per wave and because you need slight over sampling and to make the conversion from 48k in to bad math to discourage DAT machine as a lossless copy format for the masses.
- MaxBarraclough 6y ago> you need slight over sampling and to make the conversion from 48k in to bad math to discourage DAT machine as a lossless copy format for the masses What do you mean by this?
- whiddershins 6y agoI might be wrong about the 48k vs 44.1k thing. My impression is that the difference in sample rate between the formats was some sort of attempt to discourage lossless copying of published music. Recall that we couldn’t just throw it on a computer and resample it back then. But regardless, you need to slightly over sample when doing A/D conversion because you need to do a very strong low pass filter before you hit the sample rate to avoid harmonic distortion. So you need the filter to be some amount higher than the target maximum reproduced frequency, because the filter is in the analog domain and itself introduces audible artifacts. So you must sample at a higher frequency than you intend target. 48k makes sense because you have more ‘extra’ frequencies to work with, so it’s easier to get the filtering out of the audible space.
- Jasper_ 6y agoConverting from 44.1k to 48k is lossless, and has always been. Converting from 48k to 44.1k is practically lossless: You lose frequencies above 28KHz, but that's about the range at which human hearing drops off anyway. > Recall that we couldn’t just throw it on a computer and resample it back then. Of course you could. How else do you think CDs were mastered and produced? The CD was developed with the idea of using it on computers, and for computer storage. And if, in practice, someone wanted to copy it, they'd just record the CD to tape using analog out (not quite lossless, but nobody cared back then), or copy CD/CD with no resampling required. The 44.1k is a mostly historical accident, and it goes back to the Red Book CD audio spec being reused from an earlier project for digital audio that Sony was working on, the U-matic, where 44.1k was basically how much audio would fit evenly into some number of lines in the tape's storage.
- tobyhinloopen 6y agoCds were 44100Hz, right?
- vezycash 6y agoIs there any hum to sound software?