Exemple #1
0
        public Form1()
        {
            InitializeComponent();

            Part part1 = new Part();
            Part part2 = new Part();
            Part part3 = new Part();
            Part part4 = new Part();

            part1.Script = "@k 1-g 2-g 3-g 4-g 5-g 6-g 7-g 1g 2g 3G 4G 5G 6G 7G 1+G 2+g 3+g 4+g 5+g 6+g 7+g 1++g";
            part2.Script = "1-g 2-g 3-g 4-g 5-g 6-g 7-g 1g 2g 3G 4G 5G 6G 7G 1+G 2+g 3+g 4+g 5+g 6+g 7+g 1++g";
            part3.Script = "@0v 1-g 2-g 3-g 4-g 5-g 6-g 7-g 1g 2g 3G 4G 5G 6G 7G 1+G 2+g 3+g 4+g 5+g 6+g 7+g 1++g";
            part4.Script = "@1+k 1+ 2+ 3+ 4+ 5+ 6+ 7+ A4";

            Tune tune = new Tune();

            //tune.Parts[0] = part1;
            tune.Parts[0] = part4;
            //tune.Parts[1] = part2;
            //tune.Parts[2] = part3;

            Compiler.CompileTune(tune, 1.0);
        }
        public static MemoryStream CompileTune(Tune tune, double masterVolume)
        {
            int duration = 0;             // equal to the longest part
            List <List <Beep> > parts = new List <List <Beep> >();

            for (int i = 0; i < tune.Parts.Count; i++)
            {
                Part rawPart = tune.Parts[i];
                if (rawPart.IsMuted || rawPart.Volume == 0)
                {
                    continue;
                }

                parts.Add(CompileScript(rawPart.Script, tune.Key, masterVolume * rawPart.Volume, tune.Bpm, out int temp));

                if (temp > duration)
                {
                    duration = temp;
                }
            }

            MemoryStream stream = new MemoryStream();

            using (BinaryWriter writer = new BinaryWriter(stream))
            {
                // awesome code by Shawn Kovac
                // https://stackoverflow.com/questions/12611982/generate-audio-tone-to-sound-card-in-c-or-c-sharp
                // thank you Shawn

                const int   formatChunkSize = 16, headerSize = 8, waveSize = 4;
                const short formatType = 1, tracks = 1, bitsPerSample = 16, frameSize = tracks * ((bitsPerSample + 7) / 8);

                int bytesPerSecond = Note.SampleRate * frameSize;
                int dataChunkSize  = duration * frameSize;
                int fileSize = waveSize + headerSize + formatChunkSize + headerSize + dataChunkSize;

                writer.Write(0x46464952);
                writer.Write(fileSize);
                writer.Write(0x45564157);
                writer.Write(0x20746D66);
                writer.Write(formatChunkSize);
                writer.Write(formatType);
                writer.Write(tracks);
                writer.Write(Note.SampleRate);
                writer.Write(bytesPerSecond);
                writer.Write(frameSize);
                writer.Write(bitsPerSample);
                writer.Write(0x61746164);
                writer.Write(dataChunkSize);

                short[] buffer = new short[duration];
                foreach (List <Beep> part in parts)
                {
                    int i = 0;
                    foreach (Beep beep in part)
                    {
                        double theta     = beep.Freq * 2 * Math.PI / Note.SampleRate;
                        double amplitude = beep.Volume * 32_767;
                        for (int step = 0; step < beep.Duration; step++, i++)
                        {
                            buffer[i] += (short)(amplitude * Math.Sin(theta * step));
                        }

                        Console.WriteLine($"{beep.Freq}, {beep.Duration}");
                    }
                }

                foreach (short sample in buffer)
                {
                    writer.Write(sample);
                }

                // TODO: move these
                stream.Seek(0, SeekOrigin.Begin);
                new System.Media.SoundPlayer(stream).PlaySync();
            }

            return(stream);
        }