Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version
Go to top

Compose sounds from frequencies and visualize them

, 17 Apr 2006
What you never wanted to know about PCM.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WaveMixer
{
    public partial class MainForm : Form
    {
		WaveUtility utility;
        
        public MainForm()
        {
            InitializeComponent();
			utility = new WaveUtility();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
			CreateWave();
        }

        private void btnAddWave_Click(object sender, EventArgs e)
        {
			AddWave();
        }

        private void btnAddRandom_Click(object sender, EventArgs e)
        {
			string message = "Minimum must be less than or equal to maximum.";
			bool canStart = true;

			//remove old error meessage
			errors.SetError(numRandomFrequencyMax, string.Empty);
			errors.SetError(numRandomAmplitudeMax, string.Empty);
			errors.SetError(numRandomOffsetMax, string.Empty);
			errors.SetError(numRandomDurationMax, string.Empty);

			//check values
			if (numRandomFrequencyMin.Value > numRandomFrequencyMax.Value)
			{
				errors.SetError(numRandomFrequencyMax, message);
				canStart = false;
			}
			if (numRandomAmplitudeMin.Value > numRandomAmplitudeMax.Value)
			{
				errors.SetError(numRandomAmplitudeMax, message);
				canStart = false;
			}
			if (numRandomOffsetMin.Value > numRandomOffsetMax.Value)
			{
				errors.SetError(numRandomOffsetMax, message);
				canStart = false;
			}
			if (numRandomDurationMin.Value > numRandomDurationMax.Value)
			{
				errors.SetError(numRandomDurationMax, message);
				canStart = false;
			}

			if (canStart)
			{	//add random waves
				AddRandomWaves();
			}
		}

		private void nunWidth_ValueChanged(object sender, EventArgs e)
		{
			PaintWave();
		}

		private void numHeight_ValueChanged(object sender, EventArgs e)
		{
			PaintWave();
		}

		private void sbWidth_Scroll(object sender, ScrollEventArgs e)
		{
			numWidth.Value = sbWidth.Value;
		}

		private void sbHeight_Scroll(object sender, ScrollEventArgs e)
		{
			numHeight.Value = sbHeight.Value;
		}

		private void tabctlVisualization_Selected(object sender, TabControlEventArgs e)
		{
			if (e.TabPage == tabSynaesthesia)
			{
				PaintWave();
			}
		}

		private void channelColor_CheckChanged(object sender, EventArgs e)
		{
			PaintWave();
		}

		private void btnNewWave_Click(object sender, EventArgs e)
		{
			CreateWave();
		}

		private void btnChangeVolume_Click(object sender, EventArgs e)
		{
			WaveSound waveSound = waveControl.WaveSound;
			utility.ChangeAmplitude(waveSound, waveControl.MaxSampleValue, (short)numChangeVolume.Value);
			DisplayWave();
		}

		private void DisplayWave()
		{
			waveControl.DrawWave();
			if (tabctlVisualization.SelectedTab == tabSynaesthesia)
			{
				PaintWave();
			}
		}

		/// <summary>Adds a specific wave to the current wave.</summary>
		private void AddWave()
		{
			WaveSound waveSound = waveControl.WaveSound;
			WaveUtility utility = new WaveUtility();
			utility.AddWave(waveSound, (float)numFrequency.Value, (float)numOffset.Value, (float)numDuration.Value, (int)numAmplitude.Value);
			
			//display the changed wave
			DisplayWave();
		}

		/// <summary>Adds random waves to the current wave.</summary>
		private void AddRandomWaves()
		{
            this.Cursor = Cursors.WaitCursor;
            try
            {
                WaveSound waveSound = waveControl.WaveSound;

                WaveUtility utility = new WaveUtility();
                Random random = new Random();

                int count = (int)numRandomCount.Value;
                float minFrequency = (float)numRandomFrequencyMin.Value;
                float maxFrequency = (float)numRandomFrequencyMax.Value;
                float scaleFrequency = maxFrequency - minFrequency;

				float minOffset = (float)numRandomOffsetMin.Value;
				float maxOffset = (float)numRandomOffsetMax.Value;
				float scaleOffset = maxOffset - minOffset;

                float minDuration = (float)numRandomDurationMin.Value;
                float maxDuration = (float)numRandomDurationMax.Value;
                float scaleDuration = maxDuration - minDuration;

                int minAmplitude = (int)numRandomAmplitudeMin.Value;
                int maxAmplitude = (int)numRandomAmplitudeMax.Value;

                for (int n = 0; n < count; n++)
                {
                    utility.AddWave(
                        waveSound,
                        (float)random.NextDouble() * scaleFrequency + minFrequency,
						(float)random.NextDouble() * scaleOffset + minOffset,
						(float)random.NextDouble() * scaleDuration + minDuration,
						(int)random.Next(minAmplitude, maxAmplitude));
                }

				//display the changed wave
				DisplayWave();
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

		/// <summary>Paints a bitmap for the current wave.</summary>
		private void PaintWave()
		{
			this.Cursor = Cursors.WaitCursor;
			try
			{
				picSynaesthesia.Width = (int)numWidth.Value;
				picSynaesthesia.Height = (int)numHeight.Value; 
					
				WaveSound waveSound = waveControl.WaveSound;

				ChannelColorFlags firstChannelColors = new ChannelColorFlags();
				firstChannelColors.IsRed = chkStereoLR.Checked;
				firstChannelColors.IsGreen = chkStereoLG.Checked;
				firstChannelColors.IsBlue = chkStereoLB.Checked;

				ChannelColorFlags secondChannelColors = new ChannelColorFlags();
				secondChannelColors.IsRed = chkStereoRR.Checked;
				secondChannelColors.IsGreen = chkStereoRG.Checked;
				secondChannelColors.IsBlue = chkStereoRB.Checked;

				Bitmap waveBitmap = utility.PaintWave(
					waveSound, 
					picSynaesthesia.Width,
					picSynaesthesia.Height, 
					firstChannelColors, 
					secondChannelColors, 
					chkConvertSignedToAbsoluteValues.Checked,
					chkScaleSamplesForPainting.Checked,
					waveControl.MaxSampleValue);
				picSynaesthesia.Image = waveBitmap;
			}
			finally
			{
				this.Cursor = Cursors.Default;
			}
		}

		/// <summary>Starts a new, empty wave.</summary>
		private void CreateWave()
		{
			WaveFormat format = new WaveFormat(44100, 16, 2);
			short[] samples = new short[(int)(format.Channels * format.SamplesPerSec * numNewWave.Value)];
			WaveSound waveSound = new WaveSound(format, samples);
			waveControl.WaveSound = waveSound;

			if (numOffset.Value > numNewWave.Value)
			{
				numOffset.Value = 0;
			}
			if (numRandomOffsetMin.Value > numNewWave.Value)
			{
				numRandomOffsetMin.Value = 0;
			}
			if (numRandomOffsetMax.Value > numNewWave.Value)
			{
				numRandomOffsetMax.Value = numNewWave.Value;
			}
		}
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Corinna John
Software Developer
Germany Germany
Corinna lives in Hannover/Germany (CeBIT City) and works as a Delphi developer, though her favorite language is C#.

| Advertise | Privacy | Mobile
Web02 | 2.8.140926.1 | Last Updated 17 Apr 2006
Article Copyright 2005 by Corinna John
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid