示例#1
0
        /// <summary>
        /// Creates the sound wave of one beat with specified bpm
        /// </summary>
        /// <param name="bpm">Beats per minute</param>
        /// <returns></returns>
        public static short[] GenerateBeatWave(int bpm)
        {
            // 60 / bpm gives us the period of beat envelope
            // data loss from casting to int will be negligible
            int length = (int)(60f / bpm * Config.SAMPLE_RATE);

            // the beat is generated by mixing a sawtooth and a square wave
            short[] sawtooth = SampleWaveForm(Pitch.A3, length, x => x / 5, WaveForms.SawtoothWave, Config.SAMPLE_RATE);
            short[] square   = SampleWaveForm(Pitch.A3, length, x => x / 7, WaveForms.SquareWave, Config.SAMPLE_RATE);
            short[] toneWave = Mixing.MixListOfWaves(new List <short[]> {
                sawtooth, square
            });

            // to get the right loudness progression, we multiply the tone wave by an exponential function
            short[] wave      = new short[length];
            float   frequency = 50;                 // determined by trial and error

            for (int i = 0; i < length; ++i)
            {
                double expValue = i < length?Math.Pow(0.0001, (double)i / length) : 0;

                wave[i] = Convert.ToInt16(expValue * toneWave[i]);
            }
            return(wave);
        }
示例#2
0
        /// <summary>
        /// Converts to a corresponding sound wave
        /// </summary>
        /// <param name="sampleRate">Sample rate</param>
        /// <param name="shift">Pitch shift, if any</param>
        /// <param name="waveForm">Wave form</param>
        /// <returns></returns>
        public short[] ConvertToWave(int sampleRate, Shift shift, WaveFormEquation waveForm)
        {
            int            length = ConvertDurationToLength(sampleRate);
            List <short[]> waves  = new List <short[]> {
            };

            foreach (Pitch frequency in Frequencies)
            {
                waves.Add(Wave.SampleWaveForm(frequency, length, shift, waveForm, sampleRate));
            }
            short[] mixed = Mixing.MixListOfWaves(waves);
            return(mixed);
        }
示例#3
0
        /// <summary>
        /// Generates a new recording from all the changes that have been made
        /// (e.g. added harmony, shifted scale).
        /// </summary>
        public void RegenerateRecording()
        {
            // dispose recording channel and recording output if they exist
            if (recordingOutput != null)
            {
                recordingOutput.Dispose();
            }
            if (recordingChannel != null)
            {
                recordingChannel.Dispose();
            }

            // generate waves from epochs
            short[] melody  = ConcatWaves(melodyEpochs);
            short[] harmony = ConcatWaves(harmonyEpochs);
            harmony = harmony.MultiplyToLength(melody.Length);
            if (beatWave == null)
            {
                beatWave = GenerateBeat(bpm, melody.Length);
            }

            // mix melody, harmony and beat
            short[] combinedWave = Mixing.MixListOfWaves(new List <short[]> {
                melody, harmony, beatWave
            });
            byte[] binaryWave = Wave.ConvertShortWaveToBytes(combinedWave);

            // write the result into a file
            using (FileStream fs = File.Create(Filename))
            {
                Wave.WriteToStream(fs, binaryWave, melody.Length,
                                   Config.SAMPLE_RATE, Config.BITS_PER_SAMPLE, Config.CHANNELS);
            }

            // create new channel and output for playing the recording
            recordingChannel        = new WaveChannel32(new WaveFileReader(Filename));
            recordingChannel.Volume = 1.0f;
            recordingOutput         = new DirectSoundOut();
            recordingOutput.Init(recordingChannel);
        }