Twinkle Twinkle Little Star

27

6

Write a program to play the popular English nursery rhyme.

Sheet music (This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. Attribution: Helix84 at the English language Wikipedia; Blahedo at the English language Wikipedia.)

Some Wikipedia articles that may be useful:

Some guidelines for your submission:

  • Your program must use the computer's sound card. If your programming language doesn't have convenient access to audio hardware, your program must create an output file in some standard format such as WAV or MIDI.

  • Your program must actually generate its output. For example, embedding the Ogg Vorbis file from Wikipedia would not be allowed.

  • The audio quality must be acceptable. At the very least, the song should be easily recognizable. Preferably, it should sound good as well.

  • The focus should be on code size, sound quality, or both (explain which one you decided on). Elegant solutions would also be great. Have fun!

  • This is a , so shortest code wins

PleaseStand

Posted 2011-01-31T03:37:02.097

Reputation: 5 369

1Why is this closed? – programmer5000 – 2017-05-16T18:12:29.163

@programmer5000 I'd say the close reason describes it extremely well... – totallyhuman – 2017-09-28T10:58:34.920

2Even after making it code golf, I'd say this is still off topic. The audio quality must be acceptable. is not an objective validity criterion. – Dennis – 2017-09-28T15:46:55.700

3@Dennis I'd say that's more like "unclear" rather than "off-topic". – Erik the Outgolfer – 2017-09-28T17:45:05.060

can I approximate note frequencies? – Ming-Tang – 2011-05-20T04:06:50.490

Answers

30

QBasic (56)

A$="CCGGAAG2FFEEDDC2"
B$="GGFFEED2"
PLAY "L4"+A$+B$+B$+A$

Focus is on reminiscence :)

(Don't have a QBasic to test this though)

Eelvex

Posted 2011-01-31T03:37:02.097

Reputation: 5 204

1Works on my DOSBox installation at least, but could you modify it to play the full song? – PleaseStand – 2011-01-31T11:49:56.233

Done. I'll go work on my reading skills :/ – Eelvex – 2011-01-31T11:57:04.693

Hmm is this page wrong? http://en.wikibooks.org/wiki/QBasic/Appendix#PLAY -- >An octave begins with C and ends with B. I did half expect QBASIC to be middle C based, but that notation would suggest it's A220 based if exactly correct :)

– mootinator – 2011-01-31T15:35:32.737

6Wow, this brings back memories of my first programming experiences with QBasic...which involved, among other things, writing cheesy music! – Daniel Standage – 2011-01-31T16:40:58.610

Technically this doesn't qualify, though, as the task specifies that the program must use the computer's sound card. – Joey – 2011-05-20T19:39:07.220

3+1 for trip down memory lane! Now all I need is a DRAW command sample :) – System Down – 2011-05-20T21:32:38.293

Great. Just change >AA< to AA and it sounds great. – PleaseStand – 2011-01-31T21:42:00.787

@idealmachine: are you sure? A has to be in a higher scale than the other notes. – Eelvex – 2011-02-01T11:46:02.723

@Eelvex: QBasic seems to consider C the first note in an octave (C-D-E-F-G-A-B), as verified by testing your code without the octave shifts. I also tried PLAY "CDEFGAB>C" and it performed how I expected it to. – PleaseStand – 2011-02-01T12:27:42.007

Ok, then. Thanks. – Eelvex – 2011-02-01T12:29:37.443

Why the L4? Aren't quarter notes the default? – dan04 – 2014-06-05T13:41:44.317

16

JavaScript (214 212 211 characters)

Open Safari, Opera, or Google Chrome to JavaScript Shell, then enter the code below:

for(s="",y=192e3;x=--y/4e3|0;)s+="~ "[(y%4e3>800|x%8==1)&Math.pow(2,"024579702457245702457970"[x>>1]/12)*y/31%2];open("data:audio/wav;base64,UklGRiXuAgBXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQHuAgCA"+btoa(s))

Unminified for readability (even then it may be hard to understand):

for(s = "", y = 192E3; x = --y / 4E3 | 0;) {
  s += "~ "[(y % 4E3 > 800 | x % 8 == 1) & Math.pow(2, "024579702457245702457970"[x >> 1] / 12) * y / 31 % 2];
}
open("data:audio/wav;base64,UklGRiXuAgBXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQHuAgCA" + btoa(s));

With several more characters, it could work on Firefox as well, but you can change the audio/wav part to at least save the WAV file.

PleaseStand

Posted 2011-01-31T03:37:02.097

Reputation: 5 369

This works for me in Firefox 25. – Duncan Jones – 2013-12-11T09:15:41.923

Wow! This is wonderful. – Phillip Senn – 2011-05-19T22:00:23.733

what do you mean by "with several more characters"? What would those characters be? – Phillip Senn – 2011-05-19T22:02:42.937

@cf_PhillipSenn: When I ran the code on Firefox, I got a non-functional QuickTime Player. I had to change the code open(...) to Audio(...).play() (8 more characters) to get it to use Firefox's working built-in audio player. – PleaseStand – 2011-05-20T02:19:54.210

1Works just fine in Chrome. – mootinator – 2011-01-31T23:19:47.767

@mootinator: Works for me as well. I hadn't thought of checking it in Chrome -- it had not gained WAV file support until fairly recently. http://code.google.com/p/chromium/issues/detail?id=23916

– PleaseStand – 2011-01-31T23:42:21.273

11

C# (Length: LOL)

So, what I did here was implement support for generating a .wav file from the string used for the QBasic solution in C# (single octave, no accidentals). Emphasis was on:

  1. Avoiding unsafe code blocks
  2. Not wasting too much of my time doing it
  3. Making it relatively simple to extend

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.IO;

namespace ConsoleApplication1
{
    public static class Extension
    {
        public static byte[] ToByteArray(this object o)
        {
            return o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .SelectMany(x =>
                                {
                                    var value = x.GetValue(o, null);
                                    if (value.GetType().Equals(typeof (UInt16)))
                                    {
                                        return BitConverter.GetBytes((UInt16) value);
                                    }
                                    if (value.GetType().Equals(typeof (UInt32)))
                                    {
                                        return BitConverter.GetBytes((UInt32) value);
                                    }
                                    if (value.GetType().Equals(typeof(char[])))
                                    {
                                        return ((char[]) value).Select(y => Convert.ToByte(y));
                                    }
                                    if (value.GetType().Equals(typeof(byte[])))
                                    {
                                        return (byte[]) value;
                                    }
                                    throw new NotImplementedException();
                                }).ToArray();
        }
    }
    public class Wave
    {
        public readonly byte[] WavFile; 

        public Wave(string notes)
        {
            var header = new Header();
            var data = new List<Chunk>();
            var f = new Fmt(8000);
            data.Add(f);
            data.Add(new WavData(notes, f));
            var thefile = data.SelectMany(x => x.ToByteArray()).ToArray();
            header.Size = (uint)thefile.Length + 4;
            WavFile = header.ToByteArray().Concat(thefile).ToArray();
        }
        class WavData: Chunk
        {
            private static IEnumerable<byte> RenderNote(string note, int length, Fmt fmt)
            {
                double frequency;
                switch (note)
                {
                    case "A":
                        frequency = 440;
                        break;
                    case "B":
                        frequency = 493.883;
                        break;
                    case "C":
                        frequency = 261.626;
                        break;
                    case "D":
                        frequency = 293.665;
                        break;
                    case "E":
                        frequency = 329.628;
                        break;
                    case "F":
                        frequency = 349.228;
                        break;
                    case "G":
                        frequency = 391.995;
                        break;
                    default:
                        throw new NotImplementedException("Unsupported Note");
                }
                var result = new byte[fmt.SampleRate / length * 2];  // For 120BPM tempo
                for (int i = 0; i < result.Length; i++)
                {
                    double time = (i % fmt.SampleRate) / (double)fmt.SampleRate;
                    double position = time * frequency;
                    if (result.Length - i <= fmt.SampleRate / 16)
                        result[i] = 127;
                    else
                        result[i] = (byte)Math.Round((Math.Sin(position * 2 * Math.PI) + 1) * 127);
                }
                return result;
            }
            public WavData(string notes, Fmt fmt)
            {
                Samples = new byte[0];
                foreach (var note in Regex.Matches(notes, @"[A-G][1|2|4|8]?").OfType<Match>().Select(x => x.Value))
                {
                    Samples = Samples.Concat(RenderNote(note[0] + "", note.Length > 1 ? note[1] - '0' : 4, fmt)).ToArray();
                }

            }
            public override char[] Id
            {
                get { return "data".ToCharArray(); }
            }
            public override uint DataSize
            {
                get { return (uint)Samples.Length; }
            }
            public byte[] Samples { get; private set; }
        }
        class Fmt : Chunk
        {
            public Fmt(UInt32 sampleRate)
            {
                CompressionCode = 1; // Unknown/PCM
                Channels = 1;
                SampleRate = sampleRate;
                SignificantBits = 8;
            }
            public override char[] Id
            {
                get { return "fmt ".ToCharArray();}
            }
            public override uint DataSize
            {
                get { return 16; }
            }
            public UInt16 CompressionCode { get; private set; }
            public UInt16 Channels { get; private set; }
            public UInt32 SampleRate { get; private set; }
            public UInt32 AvgBytesPerSecond { get { return SampleRate*BlockAlign; } }
            public UInt16 BlockAlign { get { return (UInt16) (SignificantBits/8*Channels); } }
            public UInt16 SignificantBits { get; private set; }
        }
        class Header
        {
            public Header()
            {
                Type = "RIFF".ToCharArray();
                RiffType = "WAVE".ToCharArray();
                Size = 0;
            }

            public char[] Type { get; private set; }
            public UInt32 Size { get; set; }
            public char[] RiffType { get; private set; }
        }
        abstract class Chunk
        {
            public abstract char[] Id { get; }
            public abstract UInt32 DataSize { get; }
        }
    }
    class Program
    {
        public static void Main(string[] args)
        {
            var p1 = "CCGGAAG2";
            var p2 = "FFEEDDC2";
            var p3 = "GGFFEED2";
            var w = new Wave(p1+p2+p3+p3+p1+p2);
            using (var f = new FileStream("testfile.wav", FileMode.Create))
                f.Write(w.WavFile, 0, w.WavFile.Length);
        }
    }
}

mootinator

Posted 2011-01-31T03:37:02.097

Reputation: 1 171

FromDigits["LOL",36]==28101 That does not look like LOL<sub>36</sub> bytes... – CalculatorFeline – 2016-03-11T15:15:40.680

I noticed the output wave has a very small amplitude in my answer above. Clearly I'm missing something about how an 8 bit sample works. – mootinator – 2011-03-09T15:58:08.360

Ah, fixed it. Order of operations is important. Sample output here: http://dl.dropbox.com/u/469380/testfile.wav

– mootinator – 2011-03-09T16:17:19.837

6

Python (259)

import pysynth

c=('c',4)
g=('g',4)
a=('a',4)
b=('b',4)
d=('d',4)
e=('e',4)
f=('f',4)
g2=('g',2)
c2=('c',2)
d2=('d',2)

s=(c,c,g,g,a,a,g2,f,f,e,e,d,d,c2,g,g,f,f,e,e,d2,g,g,f,f,e
            ,e,d2,c,c,g,g,a,a,g2,f,f,e,e,d,d,c2)

pysynth.make_wav(s,fn="s.wav")

John

Posted 2011-01-31T03:37:02.097

Reputation: 251

1

(very late comment) For reference, here is a version -60 bytes, because it's really golfed.

– Erik the Outgolfer – 2016-06-18T20:50:15.887

3couldn't this be shortened to import ttls? – zzzzBov – 2011-03-11T20:38:18.717

@zzz: Um, is that a joke? – John – 2011-03-11T20:48:26.087

no more than this is sarcasm. – zzzzBov – 2011-03-11T20:51:42.760

2@zzz: -Bangs-head-on-desk- What are you saying exactly? – John – 2011-03-11T20:54:42.557

1@John it's obviously a koan. you should either bow or hit him. – ixtmixilix – 2011-09-09T08:41:28.460

5

C, 277 characters

#include<math.h>
a[]={0,7,9,7,5,4,2,0,7,5,4,2,7,5,4,2,0,7,9,7,5,4,2,0},i,j,f;main(){unsigned char
b[8000];f=open("/dev/dsp",1);for(i=0;i<24;i++){for(j=0;j<8000;j++){b[j]=(i%4==3
||j/400%20!=9?1+sinf(j*powf(2,a[i]/12.)):1)*127;}for(j=0;j<8000;j+=write(f,b+j,
8000-j));}close(f);}

Perl, 203 characters

open F,'>:raw','/dev/dsp';for$a(0,7,9,17,5,4,2,10,7,5,4,12,7,5,4,12,0,7,9,17,5,4
,2,10){$b=pack'C*',map 127*($a>9||$_/400%20!=9?1+sin($_*2**($a%10/12)):1),0..
7999;$b=substr$b,syswrite F,$b while length$b}

Conveniently, OSS's /dev/dsp defaults to 8kHz mono u8; all I do here is open the device and write computed samples.

ephemient

Posted 2011-01-31T03:37:02.097

Reputation: 1 601

179 - j,f;main(i){char b[8000];f=open("/dev/dsp",1);for(i=24;i--;write(f,b,j))for(j=0;j<8000;j++)b[j]=(i%4&&j/400%20==9?1:1+sinf(j*powf(2,("@BDEGIG@BDEGBDEG@BDEGIG@"[i]-64)/12.)))*127;} – gastropner – 2017-12-30T12:07:20.023

Post Perl separately; you're on codegolf :) – Eelvex – 2011-11-02T03:10:42.850

4

PowerShell: 207

Golfed code:

filter n {switch($_){C{262}D{294}E{330}F{349}G{392}A{440}}}$t="CCGGAAGFFEEDDCGGFFEEDGGFFEEDCCGGAAGFFEEDDC";1..6|%{$t[0..5]|n|%{[console]::beep($_,600)};$t[6]|n|%{[console]::beep($_,1200)};$t=$t.SubString(7)}

Ungolfed, with comments:

# Filter to define note frequencies.
filter n {switch($_){C{262}D{294}E{330}F{349}G{392}A{440}}}

# Notes for Twinkle, Twinkle, Little Star.
$t="CCGGAAGFFEEDDCGGFFEEDGGFFEEDCCGGAAGFFEEDDC"

# Run through each phrase in the song.
1..6|%{
    # Play first six notes as quarter notes.
    $t[0..5]|n|%{[console]::beep($_,600)}
    # Play seventh note as half note.
    $t[6]|n|%{[console]::beep($_,1200)}
    # Left-shift $t by 7 notes.
    $t=$t.SubString(7)
}

Not the greatest-sounding rendition of the song ever, but it works.

Iszi

Posted 2011-01-31T03:37:02.097

Reputation: 2 369

1(late comment) Can you do n{ instead of n {? – Erik the Outgolfer – 2016-06-18T20:35:04.480

4

C - 520

Bump.

#include <linux/fd.h>
#include <time.h>
struct timespec t,p;char*q="AAHHJJH  FFEECCA  HHFFEEC  HHFFEEC  AAHHJJH  FFEECCA";x,y,z,v,w;main(){x=open("/dev/fd0",3);for(y;q[y];y++){clock_gettime(CLOCK_MONOTONIC,&p);if(q[y]>' ')for(w=z=0;z<4e8;z+=t.tv_nsec,w++){struct floppy_raw_cmd s={0};s.flags=FD_RAW_NEED_SEEK;v=!v;s.track=v;ioctl(x,FDRAWCMD,&s);clock_gettime(CLOCK_MONOTONIC,&t);t.tv_nsec=(w+1)*5e8/pow(2.,q[y]/12.)-(t.tv_sec-p.tv_sec)*1e9-t.tv_nsec+p.tv_nsec;t.tv_sec=0;nanosleep(&t,0);}t.tv_nsec=2e8;nanosleep(&t,0);}}

Why use past century's hardware like speakers and headphones? This excellent piece of code lets you play the song on a modern piece of hardware: a floppy drive!
No special requirements:

  • An IDE floppy drive
  • Linux kernel
  • Compile with -lm
  • Make sure the program can access /dev/fd0, so either chown the device or run as superuser

Bends the rules a bit, but let's for a second consider the floppy drive a sound device, and the IDE controller an integrated sound card.

mniip

Posted 2011-01-31T03:37:02.097

Reputation: 9 396

I'd say this is reasonable, floppy drives are surprisingly capable for this task https://youtu.be/LkqYLOa76E0

– Hotkeys – 2016-03-11T17:37:20.130

3

HyperCard 2.2 - 113

play harpsichord "c c g g a a gh fq f e e d d ch gq g f f e e dh gq g f f e e dh cq c g g a a gh fq f e e d d ch"

Usage: Start HyperCard, type ⌘M to open the Message Box, paste the code above, and press enter.

harpsichord may be replaced with flute or boing to get different sounds.

Joey Adams

Posted 2011-01-31T03:37:02.097

Reputation: 9 929

(very late comment) harpsichord -> flute -6 remove the space between instrument and quotes -1 total -7 – Erik the Outgolfer – 2016-06-20T17:25:20.917

3

C, 96 chars

main(t){for(;++t>>16<3;)putchar(t*!!(t>>9&7|!(-t>>12&7))*(96+"#d|dOE3#dOE3dOE3"[t>>13&15])>>5);}

Produces raw 8-bit unsigned mono audio data in classic bytebeat style. Recommended sample rates for playback are between 8 and 16 kHz; changing the sample rate changes the tempo and pitch.

To compile and play under Linux, save the code above as twinkle.c and run the following commands:

gcc twinkle.c -o twinkle
./twinkle | aplay

Some notes on how the code works:

  • The general trick used for bytebeat compositions like this is that putchar() takes an integer value but only prints the low eight bits of it. Thus, putchar(t), where t is an increasing counter, generates a sawtooth wave, and the frequency of the wave can be altered by multiplying t with a suitable value.

  • !!(t>>9&7|!(-t>>12&7)) produces the repeating 6+1 note pattern. Specifically, !!(t>>9&7) evaluates to 0 whenever t>>9 & 7 == 0 and to 1 otherwise. Thus, it produces a 512-sample gap in the waveform every 4096 samples, while the !(-t>>12&7) eliminates every eighth such gap.

  • 96+"#d|dOE3#dOE3dOE3"[t>>13&15] generates the melody: the ASCII code of each characters in the string plus 96 gives the relative frequency of the corresponding note. Actually, the values are the approximate frequencies in Hz of concert pitch notes in the 3rd / small octave, i.e. with A corresponding to 220. However, since the base tone with which these values are multiplied is about 64 Hz (when played at 16 kHz, or 32 Hz when played at 8 kHz), we need to scale the result down by five octaves with >>5 to get the frequency back into a reasonable range.

Ps. If you want to try this code on a JavaScript-based bytebeat player, replace [t>>13&15] with .charCodeAt(t>>13&15).

Ilmari Karonen

Posted 2011-01-31T03:37:02.097

Reputation: 19 513

2

bash + say + gunzip, 136 bytes

say, of course, being the OS X text-to-speech command. This is... dorky. Yeah, let's go with dorky.

printf '<117 bytes>'|gunzip|sh

The 117 bytes is, of course, a gzip stream containing unprintable characters. Here's an xxd dump of the script including those characters:

00000000: 7072 696e 7466 2027 1f8b 085c 305c 305c  printf '...\0\0\
00000010: 305c 305c 3002 032b 4eac 54d0 2d0b c9c8  0\0\0..+N.T.-...
00000020: cf4d 2c56 c8e7 c2ca 75cc cb4b c4ce 71cb  .M,V....u..K..q.
00000030: ccc7 c90b 4b4d 85f0 7252 530b 14f4 4ca0  ....KM..rRS...L.
00000040: c2de 8945 a979 4061 6cbc e0c4 dcc4 bc92  ...E.y@al.......
00000050: 8c44 dc02 2e89 7999 a939 685c 5c74 7723  .D....y..9h\\tw#
00000060: ec44 755c 6e2a 8f8a ee19 581b 8767 1402  .Du\n*....X..g..
00000070: 5c30 fa36 7e25 2599 025c 305c 3027 7c67  \0.6~%%..\0\0'|g
00000080: 756e 7a69 707c 7368                      unzip|sh

Explanation

The 117 bytes is the following script gzipped:

say -vThomas o
say -vThomas o
say -vAnna o
say -vAnna o
say -vFiona o
say -vFiona o
say -vVeena o
sleep .4
say -vKaren o
say -vKaren o
say -vSamantha o
say -vSamantha o
say -vDaniel o
say -vDaniel o
say -vThomas o
sleep .4
say -vVeena o
say -vVeena o
say -vKaren o
say -vKaren o
say -vSamantha o
say -vSamantha o
say -vDaniel o
sleep .4
say -vVeena o
say -vVeena o
say -vKaren o
say -vKaren o
say -vSamantha o
say -vSamantha o
say -vDaniel o
sleep .4
say -vThomas o
say -vThomas o
say -vAnna o
say -vAnna o
say -vFiona o
say -vFiona o
say -vVeena o
sleep .4
say -vKaren o
say -vKaren o
say -vSamantha o
say -vSamantha o
say -vDaniel o
say -vDaniel o
say -vThomas o

That's right, I just made a bunch of different say voices say "o." To figure out which ones, I wrote a script using aubionotes to get a quick-and-dirty estimate of each voice's pitch, then did a lot of trial and error the find ones that sound mostly right.

I considered trying to golf this manually, but there's so much repetition that I figured Zopfli would make shorter work of it, so I took the easy way out.

Jordan

Posted 2011-01-31T03:37:02.097

Reputation: 5 001

2

Mathematica, 86 chars

s=SoundNote;If[#>9,s[#-10,2],{s@#,s@#}]&/@Join[a={0,7,9,17,5,4,2,10},b={7,5,4,12},b,a]

alephalpha

Posted 2011-01-31T03:37:02.097

Reputation: 23 988

2

Arduino, 688

int length=15;char notes[]="ccggaag ffeeddc ggffeed ggffeed ccggaag ffeeddc";int beats[]={1,1,1,1,1,1,2,1,1,1,1,1,1,2,4};int tempo=300;void playTone(int tone,int duration){for(long i=0;i<duration*1000L;i+=tone*2){digitalWrite(11,HIGH);delayMicroseconds(tone);digitalWrite(11, LOW);delayMicroseconds(tone);}}void playNote(char note, int duration){char names[]={'c','d','e','f','g','a','b','C'};int tones[]={1915,1700,1519,1432,1275,1136,1014,956};for(int i=0;i<8;i++){if(names[i]==note){playTone(tones[i], duration);}}}void setup(){pinMode(11, OUTPUT);}void loop(){for(int i=0;i<length;i++){if(notes[i]==' '){delay(beats[i]*tempo);}else{playNote(notes[i],beats[i]*tempo);}delay(tempo/2);}}

Plug in the buzzer on output 11. I concentrated mainly on quality, but also on code length.

Timtech

Posted 2011-01-31T03:37:02.097

Reputation: 12 038

(late comment) "ccggaag ffeeddc ggffeed ggffeed ccggaag ffeeddc " remove space? int beats[] = remove space? for (long remove space? 11, LOW remove space? note, int remove space? i], duration remove space? 11, OUTPUT remove space? – Erik the Outgolfer – 2016-06-18T11:27:24.627

Did you actually forget some spaces? As far as I understand, the space in ffeeddc " is for some sort of delay, which you do not need at the end, and beats[] = has no reason to have a space. Also, you should make a version concentrating on code length, just for the heck of it! – Erik the Outgolfer – 2016-06-18T20:33:01.220

I suppose the variables could all be one letter but I don't think it's worth the time on such an old answer. Thanks for those tips. – Timtech – 2016-06-18T21:01:47.230

Ok, feel free to post as a separate answer if you'd like. – Timtech – 2016-06-18T21:07:20.740

@Timtech As the question is closed, that can't be done unfortunately... :-( – wizzwizz4 – 2016-10-24T16:00:24.277

2

Python 317 305 301

This is my solution, using only standard python libraries:

import math,wave,struct;d=24000;r=1100.;t=wave.open("t.wav","w");t.setparams((1,2,int(r),d,"NONE",""));a=[0,7,9,7];b=[5,4,2,0];c=[7,5,4,2]
for h in[math.sin(6*[240*2**(j/12.)for j in a+b+c+c+a+b][x/1000]*(x/r))*(x%500>9 or x/1000%4>2)for x in range(d)]:t.writeframes(struct.pack('h', int(h*64000/2)))

And here it is with some more whitespace for readability:

import math,wave,struct;d=24000;r=1100.
a=[0,7,9,7];b=[5,4,2,0];c=[7,5,4,2];s=[240*2**(j/12.) for j in a+b+c+c+a+b]
z=[math.sin(6*s[int(x/1000)]*(x/r))*(x%500>10 or int(x/1000)%4>2) for x in range(d)]
t=wave.open("t.wav","w");t.setparams((1,2,int(r),d,"NONE",""))
for h in z:t.writeframes(struct.pack('h', int(h*64000./2)))

scleaver

Posted 2011-01-31T03:37:02.097

Reputation: 507

1

SmileBASIC, 45 bytes

BGMPLAY"{M=CCGGAAG2FFEEDDC2}{M}[GGFFEED2]2{M}

12Me21

Posted 2011-01-31T03:37:02.097

Reputation: 6 110

0

Powershell, 120 117 bytes

[Console]::beep, note labels and frequencies inspired by Iszi

 ($a='ccggaaGffeeddC')+'ggffeeD'*2+$a|% t*y|%{[console]::beep((0,110,0,65,73,82,87,98)[$_-band7]*4,600+600*($_-lt97))}

Main idea:

  • The melody is encoded in a string.
  • The notes are encoded with chars A,C,D,E,F,G.
  • Uppercase means a double duration.
  • 3 lower bits ($_-band7) of each note uses as index in the frequencies array (A->1,C->3,D->4...)
  • This script uses the reduced sampling rate for frequencies: (0,110,0,65,73,82,87,98)[$_-band7]*4 instead Iszi's (0,440,0,262,294,330,349,392)[$_-band7]. [console]::Beep is not the most accurate musical instrument, so it can slightly fake :)

Explanation: For each char from the melody string ccggaaGffeeddCggffeeDggffeeDccggaaGffeeddC, the script:

  • lookups frequensies from the array using the lower bits as index
  • calculates a duration based on char uppercase/lowercase
  • calls [console]::beep to play the note

mazzy

Posted 2011-01-31T03:37:02.097

Reputation: 4 832