for anyone wondering, that app he used is called pitchlab, and its excellent. it's designed for tuning instruments, but it's still fun to play around with.
If you use hurd (I wish they could get that working properly), then you could have a filter (a file, that looks is realy an executable, but looks like a file). Can you do that with fuse. Oh but it will not auto mount.
That type of music is also called "bytebeat" on the interweb and if you're into that kind of wierd stuff I recommend the work of Jerobeam Fenderson who makes "oscilloscope music" the concept is different of bytebeat but it's still incredibly interesting, the sound is similar and you get visuals along with it.
In C, _signed_ eight bit is the same as a character [not _unsigned_ as stated in the video]. However, it's true that putchar accepts a signed integer as an argument, and emits an unsigned eight-bit value.
+GodlikeBlock There's nothing much here to make it human readable, to be honest. Most of the code is bitwise operations on integers, and you can't really make them "human-readable" in the usual sense. At most, we could comment on what each piece is doing, but most of the "magic numbers" and operations were likely coded randomly and then the program was run to see if they sounded good. This is usually how we do this. It's extremely difficult for a human to look at the code and predict what the music will sound like. At most, we can get a sense of the timbre generated, which is why he mentions the bit on sawtooth waves.
That's not exactly what i meant. by "Human-readable" i mean things like: giving variables proper names, actually using the "int" keyword, using proper lines/indentation and all that. its not that i want to read the code like a book, but rather make it easier for me to understand. comments could be helpful,. but are not reqirered. but I guess you're right, by "human-readable" i could easily have meant what you described, i'm sorry =]
+GodlikeBlock except if you know what the int specifier is then you probably understand code and could decipher the original. its not going to make it any easier to read if its spaced out with a few extra keywords, etc.
Sure, here you go. This is the best I can do. int g(int sample, int x, int t, int overdrive) { return ( ( 3 & x & ( // some arbitrary manipulation of the timbre generated below sample * // multiply the current sample number (pretty much the current time) to... // the following block creates an array of 8 chars (a string) and reads each letter // as an int. These seem to be used for composing a general rule for the melody, // but maybe they have to do with the timbre, as if two instruments // I'm not sure which ( ( 3 & sample >> 16 // if this is true ? "BY}6YB6%" // use this string as a melody source : "Qj}6jQ6%" // otherwise use this one )[t % 8] // cycle over which character to use based on the parameter t + 51 // add 51 arbitrarily, possibly to increase volume and/or to get a different melody? ) >> overdrive // divide result by 2^overdrive ) )
+1ucasvb The strings decide the notes being played, effectively. The repetition in the strings sort of sets up what key and what octave you are using. Without that, the range would be higher, or the song would be heavily dissonant.
The loop variable is incremented in the loop. You could probably shave off a character by incrementing it the first time it is read (++I), though I believe that location is not defined. You can shave off 3 characters if the loop can start with 1 (argc, first parameter to main, is 1).
Robert Miles I've not been able to try it, unfortunately, but how different is it if you start the loop from 1 instead of 0? If the audio output is all but identical, it might still count. :-) (At a glance, it seems like i = 0 generates silence, anyway.)
The provided code: :1:80: error: second parameter of 'main' (argument array) must be of type 'char **' :1:80: error: third parameter of 'main' (environment) must be of type 'char **'
For general purpose coding you usually don't want to minimize code size because smaller code does not necessarily mean faster computation and you also need to take into account stability, reliability and security as well as how much time you need to put into crafting the code. But for time critical low level code written in machine language you may need to minimize size in order to be clock cycle perfect and also fit within the registers available. Examples would be firmwares, control systems and parts of the graphics code in video games.
+Anders Öhlund I understand the point "smaller code does not necessarily mean faster computation". But why "and you also need to take into account stability, reliability and security"...why a smaller code would be less reliable or less secure?
+Russell Teapot The real issue with smaller code is that fewer people are able to understand it fully. When you're using abbreviations and unintuitive but shorter ways to write things, the chances of someone later maintaining that code screwing it up are higher. There's a programming philosophy called "clean code" where one of the main points is to make the code so it can be fully understood by the most basic programmer with little experience in that specific language and at the end of a rough work day. Often enough, I find bugs by just stretching out the code a bit to be more readable. When some peace of code is too compact/smart/elegant, a logic error can slip by another programmer whose job it is to review that piece of code and then that piece of code is running a nuclear power plant. That would be bad.
I remember on the ZX spectrum writing a boot loader. It had to fit into very little memory (optimized for memory size): it had lines like goto sign pi (3 keystrokes + shifts, and 3 bytes). I may remember that wrong as that will do the same as run, and that is one byte, one keystroke. I remember arranging for it to start in the middle, so that I could use run as a goto 1. sign pi evaluates to 1 and takes 2 bytes of code. Where as 1 takes 5 bytes (is is floating point).
3:45 A little mistake. That graph is not a sine, it's a circular waveform which has a similar harmonic distribution. But good video anyways. The music they talk about is "ByteBeat", and there are many websites where you can try writing your own C and JS expressions to create sounds. There's even a research paper about it but I don't have the link now
Old sound chips create the frequency by dividing a base input frequency, coming from the master clock, or some already divided value of it. The oscillator of a sound channel is clocked by this frequency, but only every x-th clock actually causes the next sample to be output. That x is what the software can manipulate, to change the divisor value in the equation and get different frequencies. This however also makes the precision and "in-tune-ness" of the oscillator get progressively worse as you go higher in frequency, because you start to divide by lower and lower numbers.
+za909returns Neat! So let's say the clock runs at 1 Mhz. This is the base input frequency. If I divide it by 1000 (so I output only on the 1000th clock), I obtain 1000 Hz soundwaves. Right?
You got it right, that's exactly what happens. The division is there to regulate the frequency. The NES gets the same rate initially as the CPU, 1.789773 MHz However, the audio circuitry is integrated into the CPU, so it makes sense really... The APU (Audio Processing Unit) gets this frequency divided by 2. But that's not all. The rest depends on the which sound channel we're speaking of. For example, the NES APU has two pulse waves, with configurable pulse width to control the timbre of the sound. A sequencer is involved that outputs 8 samples repeatedly to create the pulse wave (The samples are either 0 or the current volume level of the channel), so the actual frequency you get to divide is 1.789773 MHz / 16 Also, the divisor is also limited by the number of bits available. The divisor in the NES APU channels is 11-bit wide, so you can divide by 1-2048. The chip of the Sega Master System, the Texas Instruments SN76489 only has a 10-bit divisor, so you get a smaller range of possibly frequencies. The Atari POKEY has 8-bit divisors by default, but you can sacrifice channels to combine two divisors for 16-bit ones.
It's not an app exactly. What he's done here is use some tools for developers to write a program, compile it, execute it, and send whatever it outputs straight to the headphone jack. So in order to actually run this, you would need a copy of Linux or similar (because APlay, the tool to send the data to the sound card, requires Linux or something that uses ALSA unless you can find an alternative), and a copy of GCC. I think a stock install of Ubuntu *might* be able to play this, so if you're really curious pop in the live cd, run the command and shut down and that would do the trick.
In a Java class we were supposed to make an object to represent a playing card, and I instead made an int to represent a card and used bitwise operators at the front to determine the suit. an int instead of an object, I'd call that a birdie.
I made a mp3 out of the output on my 64-bit linux-box. The file is 825M huge and plays almost 74:34 hours - I mismatched the output on the display of the player for minutes, first. BTW: The sine-wave looks a little bit different than two hemicycles; but I must admit it's easier to draw. :) Edit: I think, 74,5 hours is way to long for an “optimized length” of the audio. The parameter type of »putchar« is »int« on my system, and it's a 64-bit-system. Is there an other “optimal” point to interrupt the for-loop than »INT_MAX« - which is 2147483647 on my system?
2:19 I think he meant to say _statically typed_ -as C lets you "type pun" and converts between certain types implicitly, i.e. has a -_-weak-_- type system.-
+Pontus Lundström I think those definitions have morphed a bit over the years. A weakly typed language would be javascript. Looking at wikipedia though, your assessment about static typing seems accurate. I used to hear "strongly typed" to mean what is now apparently statically typed. C just allows certain implicit type conversion, although there are very specific and well defined rules for when this can happen. Any time a type (class) has a constructor that accepts a single parameter of another type, the compiler is allowed to implicitly convert one type to another, as a one way operation. It can not, however, perform a chain of two conversions where it converts to an intermediate type and then to the desired type. For built in numerical types, the idea of a constructor is built in to the compiler itself, but it can be thought of this way. There is a single step between a void* and an int, basically a reinterpret_cast. This also applies mainly to rvalues, not variables that you declare in your code. Anything you declare as an int can never just become a bool or a float all of a sudden. It retains its type, but functions which know how to convert an int to what they want are allowed to do so. In Javascript, a single 'var' can hold an integer value one moment, and a string the next. The type of the variable itself is fluid. That's what distinguishes a weakly typed language.
+DFPercush You're probably right about the definitions changing over time. If you look up Wikipedia for "Strong and weak typing" or "Type system" you'll find even their definitions aren't completely unambiguous so I guess we might be debating apples vs. oranges here. That also means my initial statement is strictly correct only until the word "as" :) What you say about JavaScript is correct. However, it's working on a much higher abstraction level compared to C thanks to its _dynamicity_ some of which I think you mixed into your comment about what is representative of a weak type system. Also, talking about classes, constructors and reinterpret_cast is confusing as C and C++ are two distinct languages. Fortunately, in C++ casts like void* -> SomeType* or vice versa aren't allowed implicitly but in C they are.
Pontus Lundström Interesting note about void* conversions being allowed in C but not C++. In my experience you can implicitly assign any pointer to a void*, but void* must be explicitly cast if you want to use it for anything else.
I wonder if we can make a program that transcribes the program into sheet music... It would probably have to be transposed by a bit to line up with musical conventions, but you could totally turn this into a piano duet or something. Either that or send it back in time to be the theme music to one of those old video games.
It is very late, and im not sure if anyone has suggested this because I didn't read ALL of the comments, but you can save 4 more bytes by using single quotes for the echo and then removing the backslashes in the code itself and just using double quotes
Actually, I seem to be able to remove " -xc -&&" and replace that with ; and it runs fine on (GCC) 6.3.1 20170306. That saves six bytes. && does some error checking which really isn't needed, and the shell handles the fact that there isn't a .c extension. I'm wondering if a.out can be truncated in some way with something like a shell expansion symbol? Back to the lab.
+NeatNit Wait. You don't run linux. Why may i ask ? Any sufficiently advanced linux user can run any windows program and soon to be any mac application.
***** I dual boot between win 10 and xubuntu and I feel there are reasons to use both. I seem to have bad luck with linux software stability and availability.
TheAnoniemo Then you're not sufficiently advanced, I myself have had no problems I have only experienced one dependency hell and I don't get any errors. If you become good with linux then you'll never return to windows and especially the new excuse for a windows operating system there are too many bugs, security issues, graphical errors and enforced features to ever make it worthwhile.
More ways to shorten it: echo can use single quotes, so you don't have to escape the double quotes in middle (4 bytes). You can redo it as a HERE document, instead of echo, which takes as many characters (including 2 required newlines) as 'echo ', so you won't even need the single quotes (another 2 bytes). Remove the extra parenthesis after the 'return' - return is NOT a function-like statement, and the parentheses around the value returned is a bad practice (another 2 bytes - but this one you really should have known). I have not been able to shorten the actual code, besides for the comments I already posted on this topic. BTW, if '.' is in your path, you can save another 2 bytes, but I don't know if that counts.
+Menachem Salomon I thought I'd already done some of those... On closer inspection the version that's in the video is not the shortest version I've got, which is this: pastebin.com/tRXZBZWx
Do you have an un-golfed version of this? The nested parens and quotes make it difficult for me to read it. Vim's syntax highlighter can't even handle it.
Does this count as code golf? Usually, code golf requires some sort of competition to do something very specific. Having an open-ended goal of "making a program that makes music" wouldn't fit this criteria.
If you were to try to get a similar result in fewer bytes you wouldn't be designing software in traditional way per se. Demo as in demoscene is a more fitting term.
+TheAnoniemo That's still a very specific kind of program. Shortest code to make music isn't specific. Shortest code to play Beethoven's 9th Symphony would be.
+Killian Maladath It is clearly some sort of common area at a university/college. My guess given the apparent size would be a department post grad lounge.
With 256 characters, wouldn't some of them have to represent negative values? Amplitude is usually -1, 0 +1. So if you have 256 available positions, wouldn't it be -127, 0 +128?
Timely reply here. The program outputs integer values [0-255]. It's up to the program aplay to interpret these and relay the signal to your audio playback devices, going through whatever transformations are necessary to actually drive a speaker. What probably happens is that 0-127 are considered "negative" and 129-255 are considered "positive", with 0 at 128.
Shame the code doesn't work on Mac - 2 errors are raised: :1:80: error: second parameter of 'main' (argument array) must be of type 'char **' :1:80: error: third parameter of 'main' (environment) must be of type 'char **'
+Tristan Saldanha the whole song is ridiculously long. You can copy and paste the command that he wrote that makes this music (assuming of course that you've got a Linux box). If I recall correctly someone posted a link to part of the song as an mp3.
2:20 This reminded me of this: "When C coders talk about strong typing they mean hitting the keys harder" ;)
The title of this video gave me no clue that it was about bytebeat music. Bit of a pleasant surprise, I love that stuff. :)
I love Rob Miles.
Code Golf!!!! This is my favorite game in all of the Internet and it is great that it is getting some attention! Thanks Computerphile!
Perfect jump-off point to explain Kolmogorov complexity!
Wow, I remember piping my files through aplay this one time but I never thought something like this would be cool. I love you Rob.
for anyone wondering, that app he used is called pitchlab, and its excellent. it's designed for tuning instruments, but it's still fun to play around with.
Instead of piping it to aplay wrote it to a file called music.
After ~a minute I had 1,7 GB - 63,38 hours - of awesome music!
Worth it!
If you use hurd (I wish they could get that working properly), then you could have a filter (a file, that looks is realy an executable, but looks like a file). Can you do that with fuse. Oh but it will not auto mount.
You can use a named pipe (fifo) for this.
You can now pipe that file to aplay! cat music.txt | aplay
broer gun
0:19 this is how i feel about the entire haskell language lol
That type of music is also called "bytebeat" on the interweb and if you're into that kind of wierd stuff I recommend the work of Jerobeam Fenderson who makes "oscilloscope music" the concept is different of bytebeat but it's still incredibly interesting, the sound is similar and you get visuals along with it.
In C, _signed_ eight bit is the same as a character [not _unsigned_ as stated in the video]. However, it's true that putchar accepts a signed integer as an argument, and emits an unsigned eight-bit value.
That code snippet is the most brilliant thing ever! That just made my day!
What an accurate drawing of a sine wave.
I noticed that too lol
You just have to type sin(x) on whatever to get a proper plot.
I think it's because of 3D effect
Wow, this is one of the best videos I've seen in a long while. Amazing.
The Compiler Complaining, that we're TORTURING the C language. LMAO.
The fact that you said "I can't do maths" just gave me hope for actually completing my engineering program.
The difference is he know what maths to do
did you?
You don't need the ";" in front of main I think. saves 1 byte.
+The Aaaargh I just tested that, and you are correct. :D
+The Aaaargh Also return is not a function, it doesn't need parens. return x, not return(x). Save 1 more byte.
2 bytes*
return x is one byte shorter than return(x), not 2. Mind the space.
that's such a great piece of code. I like the music it makes.
Can you please provide a "human-readable"(just not a code golf) version of the program?
Love it anyway!
+GodlikeBlock There's nothing much here to make it human readable, to be honest. Most of the code is bitwise operations on integers, and you can't really make them "human-readable" in the usual sense.
At most, we could comment on what each piece is doing, but most of the "magic numbers" and operations were likely coded randomly and then the program was run to see if they sounded good. This is usually how we do this.
It's extremely difficult for a human to look at the code and predict what the music will sound like. At most, we can get a sense of the timbre generated, which is why he mentions the bit on sawtooth waves.
That's not exactly what i meant.
by "Human-readable" i mean things like: giving variables proper names, actually using the "int" keyword, using proper lines/indentation and all that.
its not that i want to read the code like a book, but rather make it easier for me to understand.
comments could be helpful,. but are not reqirered.
but I guess you're right, by "human-readable" i could easily have meant what you described, i'm sorry =]
+GodlikeBlock except if you know what the int specifier is then you probably understand code and could decipher the original. its not going to make it any easier to read if its spaced out with a few extra keywords, etc.
Sure, here you go. This is the best I can do.
int g(int sample, int x, int t, int overdrive) {
return (
(
3 & x & ( // some arbitrary manipulation of the timbre generated below
sample * // multiply the current sample number (pretty much the current time) to...
// the following block creates an array of 8 chars (a string) and reads each letter
// as an int. These seem to be used for composing a general rule for the melody,
// but maybe they have to do with the timbre, as if two instruments
// I'm not sure which
(
(
3 & sample >> 16 // if this is true
?
"BY}6YB6%" // use this string as a melody source
:
"Qj}6jQ6%" // otherwise use this one
)[t % 8] // cycle over which character to use based on the parameter t
+
51 // add 51 arbitrarily, possibly to increase volume and/or to get a different melody?
) >> overdrive // divide result by 2^overdrive
)
)
+1ucasvb
The strings decide the notes being played, effectively. The repetition in the strings sort of sets up what key and what octave you are using. Without that, the range would be higher, or the song would be heavily dissonant.
This is the first one in a while that was genuinely beyond me for most of it.
Awesome episode! Would love to know more about the coded music theory behind this
Had to test aplay, a sql backup file sounds like grindcore.
bad idea, some clever person may re-interpret the file by taking the sound and thus maybe compromising his security!
I just tried, it really sound like a cheap scooter engine running at full power xDD
Just tried this on my Raspberry Pi and I must say, I'm impressed. Thank you for sharing it :)
I simply loved this video! I enjoyed being able to play around with the code. More videos like this, please!! Hahaha
The loop variable is incremented in the loop. You could probably shave off a character by incrementing it the first time it is read (++I), though I believe that location is not defined. You can shave off 3 characters if the loop can start with 1 (argc, first parameter to main, is 1).
Robert Miles I've not been able to try it, unfortunately, but how different is it if you start the loop from 1 instead of 0? If the audio output is all but identical, it might still count. :-) (At a glance, it seems like i = 0 generates silence, anyway.)
Love the lil ukuleles in the background
I really like this guy :D He is very intelligent and entertaining.
When did Jean-Ralphio get into coding?
Tried the code and it worked great.
I really like this kind of coding whether or not it is important.
The code has a set of function-like parentheses on the return statement. In both code-golf and readability sense that's just two extra characters.
The provided code:
:1:80: error: second parameter of 'main' (argument array) must be of type 'char **'
:1:80: error: third parameter of 'main' (environment) must be of type 'char **'
ROB MILES IS BACK! YAAAAAY!
Can't you save one character by removing the brackets around the quantity being returned by the g function? i.e., "return x;" instead of "return(x);".
The title stood out to me, because i'm actually working on a golf sim right now in Blender/Python (just started like an hour ago)
This.... is beautiful!
Very very interesting indeed. I love the 5 string bass as well:) As a bass player I loved it.
This was awesome, please make more videos about coding and stuff, like this one :)
Dude, thanks for spoiling the plot to the book :D
Best oveflow animation ever ! :D
For general purpose coding you usually don't want to minimize code size because smaller code does not necessarily mean faster computation and you also need to take into account stability, reliability and security as well as how much time you need to put into crafting the code. But for time critical low level code written in machine language you may need to minimize size in order to be clock cycle perfect and also fit within the registers available. Examples would be firmwares, control systems and parts of the graphics code in video games.
+Anders Öhlund I understand the point "smaller code does not necessarily mean faster computation". But why "and you also need to take into account stability, reliability and security"...why a smaller code would be less reliable or less secure?
+Russell Teapot The real issue with smaller code is that fewer people are able to understand it fully. When you're using abbreviations and unintuitive but shorter ways to write things, the chances of someone later maintaining that code screwing it up are higher. There's a programming philosophy called "clean code" where one of the main points is to make the code so it can be fully understood by the most basic programmer with little experience in that specific language and at the end of a rough work day. Often enough, I find bugs by just stretching out the code a bit to be more readable. When some peace of code is too compact/smart/elegant, a logic error can slip by another programmer whose job it is to review that piece of code and then that piece of code is running a nuclear power plant. That would be bad.
I remember on the ZX spectrum writing a boot loader. It had to fit into very little memory (optimized for memory size): it had lines like goto sign pi (3 keystrokes + shifts, and 3 bytes). I may remember that wrong as that will do the same as run, and that is one byte, one keystroke. I remember arranging for it to start in the middle, so that I could use run as a goto 1. sign pi evaluates to 1 and takes 2 bytes of code. Where as 1 takes 5 bytes (is is floating point).
3:45 A little mistake. That graph is not a sine, it's a circular waveform which has a similar harmonic distribution. But good video anyways. The music they talk about is "ByteBeat", and there are many websites where you can try writing your own C and JS expressions to create sounds. There's even a research paper about it but I don't have the link now
This is my new favourite thing.
Code golf is awesome!!
Old sound chips create the frequency by dividing a base input frequency, coming from the master clock, or some already divided value of it.
The oscillator of a sound channel is clocked by this frequency, but only every x-th clock actually causes the next sample to be output. That x is what the software can manipulate, to change the divisor value in the equation and get different frequencies.
This however also makes the precision and "in-tune-ness" of the oscillator get progressively worse as you go higher in frequency, because you start to divide by lower and lower numbers.
+za909returns Neat! So let's say the clock runs at 1 Mhz. This is the base input frequency. If I divide it by 1000 (so I output only on the 1000th clock), I obtain 1000 Hz soundwaves. Right?
+za909returns what was the clock frequency of one of those chips?
You got it right, that's exactly what happens. The division is there to regulate the frequency.
The NES gets the same rate initially as the CPU, 1.789773 MHz
However, the audio circuitry is integrated into the CPU, so it makes sense really...
The APU (Audio Processing Unit) gets this frequency divided by 2. But that's not all. The rest depends on the which sound channel we're speaking of. For example, the NES APU has two pulse waves, with configurable pulse width to control the timbre of the sound. A sequencer is involved that outputs 8 samples repeatedly to create the pulse wave (The samples are either 0 or the current volume level of the channel), so the actual frequency you get to divide is 1.789773 MHz / 16
Also, the divisor is also limited by the number of bits available. The divisor in the NES APU channels is 11-bit wide, so you can divide by 1-2048.
The chip of the Sega Master System, the Texas Instruments SN76489 only has a 10-bit divisor, so you get a smaller range of possibly frequencies. The Atari POKEY has 8-bit divisors by default, but you can sacrifice channels to combine two divisors for 16-bit ones.
7:13 what app was that?
It's not an app exactly. What he's done here is use some tools for developers to write a program, compile it, execute it, and send whatever it outputs straight to the headphone jack.
So in order to actually run this, you would need a copy of Linux or similar (because APlay, the tool to send the data to the sound card, requires Linux or something that uses ALSA unless you can find an alternative), and a copy of GCC.
I think a stock install of Ubuntu *might* be able to play this, so if you're really curious pop in the live cd, run the command and shut down and that would do the trick.
is that Brady in the background at 7:09?
this is amazing
One can program audio from code. Neat, will definitely check it ou!
In a Java class we were supposed to make an object to represent a playing card, and I instead made an int to represent a card and used bitwise operators at the front to determine the suit. an int instead of an object, I'd call that a birdie.
2 bits suit, 4 bits number. And I assume the Jokers were either number 0 or number 15?
I think I know where those ukulele end credits in Robert Miles videos are being recorded...
Nice video!
I made a mp3 out of the output on my 64-bit linux-box. The file is 825M huge and plays almost 74:34 hours - I mismatched the output on the display of the player for minutes, first.
BTW: The sine-wave looks a little bit different than two hemicycles; but I must admit it's easier to draw. :)
Edit: I think, 74,5 hours is way to long for an “optimized length” of the audio. The parameter type of »putchar« is »int« on my system, and it's a 64-bit-system. Is there an other “optimal” point to interrupt the for-loop than »INT_MAX« - which is 2147483647 on my system?
That's real neat!
more videos of this guy pls
2:19 I think he meant to say _statically typed_ -as C lets you "type pun" and converts between certain types implicitly, i.e. has a -_-weak-_- type system.-
+Pontus Lundström You're right. (I also said square wave once when I meant sawtooth wave)
+Pontus Lundström I think those definitions have morphed a bit over the years. A weakly typed language would be javascript. Looking at wikipedia though, your assessment about static typing seems accurate. I used to hear "strongly typed" to mean what is now apparently statically typed. C just allows certain implicit type conversion, although there are very specific and well defined rules for when this can happen. Any time a type (class) has a constructor that accepts a single parameter of another type, the compiler is allowed to implicitly convert one type to another, as a one way operation. It can not, however, perform a chain of two conversions where it converts to an intermediate type and then to the desired type. For built in numerical types, the idea of a constructor is built in to the compiler itself, but it can be thought of this way. There is a single step between a void* and an int, basically a reinterpret_cast. This also applies mainly to rvalues, not variables that you declare in your code. Anything you declare as an int can never just become a bool or a float all of a sudden. It retains its type, but functions which know how to convert an int to what they want are allowed to do so. In Javascript, a single 'var' can hold an integer value one moment, and a string the next. The type of the variable itself is fluid. That's what distinguishes a weakly typed language.
+DFPercush You're probably right about the definitions changing over time. If you look up Wikipedia for "Strong and weak typing" or "Type system" you'll find even their definitions aren't completely unambiguous so I guess we might be debating apples vs. oranges here. That also means my initial statement is strictly correct only until the word "as" :)
What you say about JavaScript is correct. However, it's working on a much higher abstraction level compared to C thanks to its _dynamicity_ some of which I think you mixed into your comment about what is representative of a weak type system. Also, talking about classes, constructors and reinterpret_cast is confusing as C and C++ are two distinct languages. Fortunately, in C++ casts like void* -> SomeType* or vice versa aren't allowed implicitly but in C they are.
Pontus Lundström
Interesting note about void* conversions being allowed in C but not C++. In my experience you can implicitly assign any pointer to a void*, but void* must be explicitly cast if you want to use it for anything else.
+DFPercush Ah, my bad, you are indeed allowed to assign _any non-function pointer_ to void* implicitly.
I studied The Curious Incident in high school. That was a very interesting read. I'd recommend it.
+Jared Mulconry I don't seem to recall understanding it. :(
Where can I get that "Do Not Be On Fire" poster you guys got on the wall there xD
I wonder if we can make a program that transcribes the program into sheet music... It would probably have to be transposed by a bit to line up with musical conventions, but you could totally turn this into a piano duet or something. Either that or send it back in time to be the theme music to one of those old video games.
Awesome!
It is very late, and im not sure if anyone has suggested this because I didn't read ALL of the comments, but you can save 4 more bytes by using single quotes for the echo and then removing the backslashes in the code itself and just using double quotes
There's an article about this, called "The Science of the Bit Fiddle".
What app is that at 7:02 ? PitchLab?
I can't seem to find it even though I peeked the splash screen
+andrew kim Yes it is
I loved it!
BTW, It depends on alsa-utils.
I had to install it to run the code.
that song is giving me flashbacks to pirating software in the early 2000s!
Actually, I seem to be able to remove " -xc -&&" and replace that with ; and it runs fine on (GCC) 6.3.1 20170306. That saves six bytes. && does some error checking which really isn't needed, and the shell handles the fact that there isn't a .c extension. I'm wondering if a.out can be truncated in some way with something like a shell expansion symbol? Back to the lab.
Could you upload a clean recording of the entire song (after calculating how long it lasts), for those of us who don't have Linux?
+NeatNit Run it in a VM, say Virtualbox.
+NeatNit plfgr.eu.org/hdd/tinycodemelody.wav here you go 30 min of it, used $ ./a.out | ffmpeg -f u8 -ar 8000 -i - -t "30:00" tinycodemelody.wav
+NeatNit Wait. You don't run linux. Why may i ask ?
Any sufficiently advanced linux user can run any windows program and soon to be any mac application.
***** I dual boot between win 10 and xubuntu and I feel there are reasons to use both. I seem to have bad luck with linux software stability and availability.
TheAnoniemo Then you're not sufficiently advanced, I myself have had no problems I have only experienced one dependency hell and I don't get any errors. If you become good with linux then you'll never return to windows and especially the new excuse for a windows operating system there are too many bugs, security issues, graphical errors and enforced features to ever make it worthwhile.
C is a statically typed language, but actually quite weakly typed -- it doesn't hide the fact that everything is actually bytes underneath.
More ways to shorten it: echo can use single quotes, so you don't have to escape the double quotes in middle (4 bytes). You can redo it as a HERE document, instead of echo, which takes as many characters (including 2 required newlines) as 'echo ', so you won't even need the single quotes (another 2 bytes). Remove the extra parenthesis after the 'return' - return is NOT a function-like statement, and the parentheses around the value returned is a bad practice (another 2 bytes - but this one you really should have known).
I have not been able to shorten the actual code, besides for the comments I already posted on this topic. BTW, if '.' is in your path, you can save another 2 bytes, but I don't know if that counts.
+Menachem Salomon
I thought I'd already done some of those... On closer inspection the version that's in the video is not the shortest version I've got, which is this:
pastebin.com/tRXZBZWx
in c does ' do the job as " or is it like java were ' is just for chars. if not remove \" and replace it with '.
1) If you use pulseaudio, change "aplay" to "aplay -D pulse"
2) It's even more fun with "aplay -r 16000"
CODE GOLF! Hurra you did something about code golf.
How do you use the given code to actually listen the music ?
Do you have an un-golfed version of this? The nested parens and quotes make it difficult for me to read it. Vim's syntax highlighter can't even handle it.
Very cool
How would one go about getting a MIDI file of this song?
I see that it's meant to run on a command line, but how to I get it to run? It says it's expecting an identifier or ( before the string
This is crazy neat 😁
What program/vm is used in this video to program?
o snap I use that app to tune my guitar. (fucking love this dude, hes always on a topic that intrigues the fuck out of me.)
Sooo amazing. Please, I must know, who is this guy?
3:47 that's not a sine wave, that's a semicircle wave
(stdin):1:1 error: expected identifier or '(' before string constant
Pet peeve: at 3:43 those are circular arcs, not a sine.
Very interesting
Oh, you are in NottingHack
suuuper cool!
Does this count as code golf? Usually, code golf requires some sort of competition to do something very specific.
Having an open-ended goal of "making a program that makes music" wouldn't fit this criteria.
code golf-solitaire?
If you were to try to get a similar result in fewer bytes you wouldn't be designing software in traditional way per se. Demo as in demoscene is a more fitting term.
+cyberconsumer Exactly. This is more demo-ish than code-golf-ish
+1ucasvb There are records for shortest program that does X. Chess is a popular one for example.
+TheAnoniemo That's still a very specific kind of program. Shortest code to make music isn't specific. Shortest code to play Beethoven's 9th Symphony would be.
whats up with the ukuleles?
How to run this file program?
What was the android app you were using to detect the pitch?
+TraciFaahkahrn Pretty sure it's pitchlab guitar tuner. one of the several functions of it.
+kjell Titulaer Yep, just downloaded it and looks identical - many thanks! :)
+TraciFaahkahrn you're welcome :)
"It assumes"? Surely there's default tables in UNIX? Like when I used Pascal it was layered to Assembler code?
Damned be you all - scriptkiddies. (⌒▽⌒)
Where was this filmed? The surroundings are very peculiar and there are people walking through so it is definitely not an office or a classroom.
+Killian Maladath I'd guess a student's mess.
+Killian Maladath It is clearly some sort of common area at a university/college. My guess given the apparent size would be a department post grad lounge.
I would like to download this tune and make it my alarm tone! Does anyone know where I could download it from?
+Gabriel N. L. Check the other comments. Some people posted links to the generated audio.
With 256 characters, wouldn't some of them have to represent negative values? Amplitude is usually -1, 0 +1. So if you have 256 available positions, wouldn't it be -127, 0 +128?
Timely reply here. The program outputs integer values [0-255]. It's up to the program aplay to interpret these and relay the signal to your audio playback devices, going through whatever transformations are necessary to actually drive a speaker. What probably happens is that 0-127 are considered "negative" and 129-255 are considered "positive", with 0 at 128.
Shame the code doesn't work on Mac - 2 errors are raised:
:1:80: error: second parameter of 'main' (argument array) must be of type
'char **'
:1:80: error: third parameter of 'main' (environment) must be of type
'char **'
I just made a comment with working Mac code
mp3 download?
Can anyone find the whole song somewhere?
+Tristan Saldanha the whole song is ridiculously long. You can copy and paste the command that he wrote that makes this music (assuming of course that you've got a Linux box). If I recall correctly someone posted a link to part of the song as an mp3.
This reminds me alot about Caustic's 8Bit Synth :)