예제 #1
0
        public void BasicOperations()
        {
            using (var buf = new RingBuffer()) {
                Assert.Equal(0, buf.BytesAvailable());
                Assert.Equal(8191, buf.WriteBytesAvailable());                   // implementation dependent.
                using (var synth = new SynthUnit(buf)) {
                    var bytes = new byte [] { 0x90, 0x30, 0 };                   // note on at 0x30, but with no velocity = no sound.
                    buf.Write(bytes, 0, bytes.Length);
                    var results = new short [1024];
                    Assert.Equal(3, buf.BytesAvailable());
                    synth.Init(44100);
                    synth.GetSamples(results, 0, results.Length);
                    Assert.All(results, r => Assert.Equal(0, r));

                    bytes = new byte [] { 0x90, 0x30, 100 };                     // now give vel = 100
                    buf.Write(bytes, 0, bytes.Length);
                    synth.GetSamples(results, 0, results.Length);
                    Assert.Contains(results, r => r != 0);

                    // to see what's being generated, enable these lines.
                    //var str = string.Concat (results.Select (s => s.ToString ("X04")));
                    //Console.WriteLine (str);
                }
            }
        }
예제 #2
0
        void WriteCallback(SoundIOOutStream outStream, int min, int max)
        {
            if (!play_audio)
            {
                return;
            }

            Console.WriteLine($"WriteCallback invoked: {min} / {max}");

            double float_sample_rate = outStream.SampleRate;
            double seconds_per_frame = 1.0 / float_sample_rate;

            //if (max - min > samples.Length)
            //	samples = new short [max - min];

#if test_with_sine
            //double seconds_offset = 0;
#else
            synth.GetSamples(samples, 0, samples.Length);
#endif
            //if (samples.Any (s => s != 0))
            //    Console.WriteLine (string.Concat (samples.Take (50).Select (s => s.ToString ("X04"))));
            int frameRemaining = max;
            int frameCount     = frameRemaining;
            while (play_audio && frameRemaining > 0)
            {
                var results = outStream.BeginWrite(ref frameCount);
                if (frameCount == 0)
                {
                    break;
                }

#if test_with_sine
                double pitch = 440.0;
                double radians_per_second = pitch * 2.0 * Math.PI;
                for (int frame = 0; frame < frameCount; frame += 1)
                {
                    double sample = Math.Sin((seconds_offset + frame * seconds_per_frame) * radians_per_second);
                    for (int channel = 0; channel < outStream.Layout.ChannelCount; channel += 1)
                    {
                        var    area  = results.GetArea(channel);
                        double range = (double)short.MaxValue - (double)short.MinValue;
                        double val   = sample * range / 2.0;
                        unsafe { *((short *)area.Pointer) = (short)val; }
                        area.Pointer += area.Step;
                    }
                }
                seconds_offset = Math.IEEERemainder(seconds_offset + seconds_per_frame * frameCount, 1.0);
#else
                for (int i = 0; i < outStream.Layout.ChannelCount; i++)
                {
                    var area = results.GetArea(i);
                    unsafe {
                        Marshal.Copy(samples, 0, area.Pointer, samples.Length);
                        area.Pointer += area.Step * samples.Length;
                    }
                }
#endif

                outStream.EndWrite();

                frameRemaining -= frameCount;
            }
        }