public static MIDIData readFile(string filePath)
        {
            MIDIData data = new MIDIData();

            try
            {
                Console.WriteLine("Reading file {0}", filePath);
                byte[] fileBytes = File.ReadAllBytes(filePath);

                UInt64 trackChunkStart = MIDIFileReader.readHeader(fileBytes, data);
                Console.WriteLine("format: {0}, ntracks: {1}, tickdiv: {2} ", data.format, data.ntracks, data.tickdiv);
                if (data.timing == TimingScheme.MetricalTiming)
                {
                    Console.WriteLine("Metrical timing PPQN: {0}", data.metrical_ppqn);
                }
                else
                {
                    Console.WriteLine("Timecode FPS: {0} SFR:{1}", data.timecode_fps, data.timecode_sfr);
                }
                UInt64 trackChunkEnd = trackChunkStart;
                while (trackChunkEnd < (UInt64)fileBytes.Length && data.tracks.Count < data.ntracks)
                {
                    trackChunkEnd = MIDIFileReader.readTracks(fileBytes, data, trackChunkEnd);
                    Console.WriteLine("Track {0} read with {1} events", data.tracks.Count, data.tracks[data.tracks.Count - 1].events.Count);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to read file {0}: {1}\n{2}", filePath, e.Message, e.StackTrace);
            }

            return(data);
        }
        // returns length of header
        static UInt64 readHeader(byte[] fileData, MIDIData data)
        {
            ushort expectedChunkLen = 6;

            if (fileData.Length < 8)
            {
                throw new Exception("File data too short to contain header");
            }
            if (!(fileData[0] == 0x4d && fileData[1] == 0x54 && fileData[2] == 0x68 && fileData[3] == 0x64)) // "MThd"
            {
                throw new Exception("File data does not contain header identifier");
            }
            ushort chunklen = 0;

            chunklen |= (ushort)((ushort)fileData[4] << 24);
            chunklen |= (ushort)((ushort)fileData[5] << 16);
            chunklen |= (ushort)((ushort)fileData[6] << 8);
            chunklen |= (ushort)((ushort)fileData[7]);
            Console.WriteLine("Chunk length: {0}", chunklen);
            if (fileData.Length < 8 + chunklen)
            {
                throw new Exception("File data too short to contain header chunk");
            }
            if (chunklen != expectedChunkLen)
            {
                throw new Exception("Unexpected chunk length in header (was " + chunklen + " expected " + expectedChunkLen + ")");
            }
            data.format = (ushort)((ushort)fileData[8] << 8 | (ushort)fileData[9]);
            if (data.format > 2)
            {
                throw new Exception("Undefined format value in header (" + data.format + ")");
            }
            data.ntracks = (ushort)((ushort)fileData[10] << 8 | (ushort)fileData[11]);
            data.tickdiv = (ushort)((ushort)fileData[12] << 8 | (ushort)fileData[13]);

            if (((data.tickdiv >> 15) & 0x01) == 1)
            {
                data.timing       = TimingScheme.TimeCode;
                data.timecode_fps = (ushort)((data.tickdiv >> 8) & 0x7);
                data.timecode_sfr = (ushort)(data.tickdiv & 0xf);
            }
            else
            {
                data.timing        = TimingScheme.MetricalTiming;
                data.metrical_ppqn = (ushort)(data.tickdiv & 0x7f);
            }

            return((UInt64)(chunklen + 8));
        }
        static UInt64 readTracks(byte[] fileData, MIDIData data, UInt64 chunkStart)
        {
            UInt64 index = chunkStart;

            while (index < (UInt64)fileData.Length)
            {
                // start reading a track chunk
                if ((UInt64)fileData.Length < index + 8)
                {
                    throw new Exception("File data too short to contain track chunk at index " + index);
                }
                if (!(fileData[index + 0] == 0x4d && fileData[index + 1] == 0x54 && fileData[index + 2] == 0x72 && fileData[index + 3] == 0x6B))  // "MTrk"
                {
                    throw new Exception("File data does not contain expected track identifier at index " + index);
                }
                index += 4;
                ushort chunklen = 0;
                chunklen |= (ushort)((ushort)fileData[index + 0] << 24);
                chunklen |= (ushort)((ushort)fileData[index + 1] << 16);
                chunklen |= (ushort)((ushort)fileData[index + 2] << 8);
                chunklen |= (ushort)((ushort)fileData[index + 3]);
                index    += 4;
                Console.WriteLine("Chunklen {0}", chunklen);
                if ((UInt64)fileData.Length < index + chunklen)
                {
                    throw new Exception("File data too short to contain track chunk of length " + chunklen + " at index " + (index - 8));
                }
                MIDITrack track      = new MIDITrack();
                UInt64    trackindex = index;
                MIDIEvent previous   = new MIDIEvent();
                while (trackindex < index + chunklen)
                {
                    MIDIEvent new_event = MIDIFileReader.readEvent(fileData, ref trackindex, previous);
                    previous = new_event;
                    track.events.Add(new_event);
                }
                data.tracks.Add(track);

                index = trackindex;
                break;
            }
            return(index);
        }
Example #4
0
        static void Main(string[] args)
        {
            WaveFormat waveFormat = new WaveFormat(44100, 16, 1);

            Oscillator freqOsc      = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(0.1f), new ConstantScalar(80.0f), new ConstantScalar(0), new ConstantScalar(100.0f));
            Oscillator ampOscVel    = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(0.05f), new ConstantScalar(8.0f), new ConstantScalar(0.5f), new ConstantScalar(8.0f));
            Oscillator ampOsc       = new Oscillator(Oscillator.WaveType.SawtoothWave, waveFormat.SampleRate, ampOscVel, new ConstantScalar(0.5f), new ConstantScalar(0), new ConstantScalar(1.1f));
            Oscillator variableFreq = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, freqOsc, ampOsc, new ConstantScalar(0), new ConstantScalar(0));

            ScalarPassthrough scalarPassthru = new ScalarPassthrough(waveFormat, variableFreq);

            NoiseGenerator noiseGen  = new NoiseGenerator(waveFormat, NoiseGenerator.NoiseType.WhiteNoise);
            Oscillator     freqsweep = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(0.1f), new ConstantScalar(200), new ConstantScalar(0), new ConstantScalar(440));
            Oscillator     qsweep    = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(1.0f), new ConstantScalar(0.9f), new ConstantScalar(0), new ConstantScalar(1.0f)); //new ConstantScalar((float)(1.0 / Math.Sqrt(2)));
            //Oscillator gainSweep = new Oscillator(Oscillator.WaveType.TriangleWave, waveFormat.SampleRate, new ConstantScalar(0.025f), new ConstantScalar(2), new ConstantScalar(0), new ConstantScalar(6));
            ConstantScalar gainSweep = new ConstantScalar(6);

            SampleProcessor.SampleProcessor filter = new SampleProcessor.NotchFilter(waveFormat, freqsweep, qsweep, gainSweep, scalarPassthru);


            // distortion "pedal" on a minimally modified hard body electric guitar signal
            Oscillator     gainOsc     = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(0.5f), new ConstantScalar(2), new ConstantScalar(0), new ConstantScalar(5));
            Oscillator     cutoffOsc   = new Oscillator(Oscillator.WaveType.SineWave, waveFormat.SampleRate, new ConstantScalar(0.95f), new ConstantScalar(3), new ConstantScalar(0), new ConstantScalar(4));
            ConstantScalar cutoff      = new ConstantScalar(0.2f);
            IWaveSource    cleanguitar = CodecFactory.Instance.GetCodec(@"..\..\sampledata\guitar-sample.mp3"); // sample signal from single-pickup electric guitar. Recorded 8/14/20.
            IReadableAudioSource <float> convertedguitar = cleanguitar.ToMono().ToSampleSource();

            SampleProcessor.DistortionEffect distortion   = new SampleProcessor.DistortionEffect(waveFormat, gainOsc, cutoff, convertedguitar);
            SampleProcessor.SampleProcessor  reverbEffect = new SampleProcessor.ReverbEffect(waveFormat, new ConstantScalar(0.4f), new ConstantScalar(0.5f), waveFormat.SampleRate, distortion);

            BasicAudioController basicAudioController = new BasicAudioController(GetSoundOut(), 1, 44100);

            basicAudioController.addSource((ISampleSource)reverbEffect);
            basicAudioController.startPlaying();

            Console.ReadKey();
            basicAudioController.stopPlaying();
            return;

            MIDI.MIDIData data = MIDI.MIDIFileReader.readFile(@"..\..\sampledata\MIDI_sample.mid");

            MIDI.MIDIData testdata = new MIDI.MIDIData();
            testdata.format       = 0;
            testdata.timing       = MIDI.TimingScheme.TimeCode;
            testdata.timecode_fps = 24;
            testdata.timecode_sfr = 4;
            testdata.ntracks      = 1;
            testdata.tracks.Add(new MIDI.MIDITrack());
            MIDI.MIDIEvent event0 = new MIDI.MIDIEvent();
            MIDI.MIDIEvent event1 = new MIDI.MIDIEvent();

            event0.delta = 4 * 24 * 5; // wait 5 seconds from start
            event1.delta = 4 * 24 * 2; // 2 seconds

            //event0.type = MIDI.EventType.MIDIEvent;
            //event0.midieventtype = MIDI.MIDIEventType.NoteOn;
            //event0.val1 = 0; // channel 0
            //event0.val2 = 60; // middle C
            //event0.val3 = 1;

            //event1.type = MIDI.EventType.MIDIEvent;
            //event1.midieventtype = MIDI.MIDIEventType.NoteOff;
            //event1.val1 = 0; // channel 0
            //event1.val2 = 60; // middle C
            //event1.val3 = 1;

            //testdata.tracks[0].events.Add(event0);
            //testdata.tracks[0].events.Add(event1);


            MIDI.MIDIPlayer player = new MIDI.MIDIPlayer(data);
            Console.WriteLine("Track 1 events:");
            player.playTrack(1);

            Console.ReadKey();
            return;

            MIDIAudioController audioController = new MIDIAudioController(GetSoundOut());

            ChromaticScale.ChromaticScale scale = new ChromaticScale.ChromaticScale();
            audioController.startPlaying();
            SampleSource.WaveGenerator.WaveType wavetype = WaveGenerator.WaveType.SineWave;

            Console.ReadKey(); // wait for input
            for (int i = 0; i < scale.notes.Count(); i++)
            {
                float freq = scale.notes[i].base_freq / 2;
                Console.WriteLine(scale.notes[i].identifier[0] + " - " + freq + " - " + wavetype);
                audioController.updatePlaying(freq, wavetype);
                Console.ReadKey(); // wait for input

                wavetype = Next(wavetype);
            }
            for (int i = 0; i < scale.notes.Count(); i++)
            {
                Console.WriteLine(scale.notes[i].identifier[0] + " - " + scale.notes[i].base_freq.ToString() + " - " + wavetype);
                audioController.updatePlaying(scale.notes[i].base_freq, wavetype);
                Console.ReadKey(); // wait for input
                wavetype = Next(wavetype);
            }
            for (int i = 0; i < scale.notes.Count(); i++)
            {
                float freq = scale.notes[i].base_freq * 2;
                Console.WriteLine(scale.notes[i].identifier[0] + " - " + freq + " - " + wavetype);
                audioController.updatePlaying(freq, wavetype);
                Console.ReadKey(); // wait for input
                wavetype = Next(wavetype);
            }

            audioController.stopPlaying();
            audioController.Dispose();
        }
Example #5
0
 public MIDIPlayer(MIDIData data)
 {
     this.data = data;
 }