Skip to content

Instantly share code, notes, and snippets.

@ff8c00
Last active February 10, 2017 16:41
Reddit Daily Programmer 300 Hard
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using System;
using System.Collections.Generic;
namespace Reddit
{
internal static class Hard
{
internal static void Run()
{
var items = new Dictionary<string, Music>();
items.Add("banjo", new Music(new double[]
{
392.00,
146.83,
196.00,
246.94,
293.66
}, 105, 11050));
items.Add("violin", new Music(new double[]
{
196.00,
293.66,
440.00,
659.25
}, 42, 88200));
using (var wave = new WaveOut())
{
wave.Init(items["banjo"]);
wave.Play();
while (true)
{
var info = Console.ReadKey(true);
if (info.Key == ConsoleKey.Enter)
{
break;
}
}
wave.Stop();
}
}
public class Music : ISampleProvider
{
private bool[] sequence;
private bool[] rule;
private int sample;
private int size;
private float[][] samples;
private WaveFormat format;
public WaveFormat WaveFormat
{
get { return format; }
}
public Music(double[] frequencies, int number, int speed)
{
int count = frequencies.Length;
var random = new Random();
sequence = new bool[count * 10];
for (int i = 0; i < sequence.Length; i++)
{
sequence[i] = random.NextDouble() >= 0.5;
}
rule = Intermediate.Rule(number);
sequence = Intermediate.Next(sequence, rule);
sample = -1;
size = speed;
format = WaveFormat
.CreateIeeeFloatWaveFormat(44100, 1);
samples = new float[count][];
for (int i = 0; i < samples.Length; i++)
{
samples[i] = new float[size];
var source = new SignalGenerator(format.SampleRate,
format.Channels);
source.Type = SignalGeneratorType.Sin;
source.Frequency = frequencies[i];
source.Gain = 0.1;
source.Read(samples[i], 0, samples[i].Length);
for (int j = 0; j < samples[i].Length; j++)
{
float amplitude = (float)Math.Sin((Math.PI *
j) / samples[i].Length);
samples[i][j] = samples[i][j] * amplitude;
}
}
}
public int Read(float[] buffer, int offset, int count)
{
int max = size - 1;
for (int i = 0; i < count; i++)
{
if (sample < max)
{
sample = sample + 1;
}
else
{
sample = 0;
sequence = Intermediate.Next(
sequence, rule);
}
float value = 0.0f;
for (int j = 0; j < samples.Length; j++)
{
if (sequence[j] == true)
{
value = value + samples[j][sample];
}
}
buffer[i + offset] = value;
}
return count;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment