1. #1
    AceInfinity's Avatar
    Join Date
    Feb 2012
    Location
    Canada
    Posts
    1,725

    [C#] Loading WAV formatted beep to MemoryStream & played by system audio

    Here's a little snippet to write a beep in WAV format to a MemoryStream to be played by the system. Easily enough done with the kernel32.dll's internal function 'Beep' although here's a way to do it manually.

    Code:
    using System;
    using System.Windows.Forms;
    using System.IO;
    using System.Media;
    using System.Linq;
    
    public class Sound
    {
    	public static void CreateBeep(int amp, int freq, int dur)
    	{
    		int smp = 441 * dur / 10;
    		int bytes = smp * 4;
    		int[] h = { 0X46464952, 0x24 + bytes, 0X45564157, 0X20746D66, 0x10, 0X20001, 0xAC44, 0x2B110, 0X100004, 0X61746164, bytes };
    
    		using (MemoryStream ms = new MemoryStream(44 + bytes))
    		{
    			using (BinaryWriter bw = new BinaryWriter(ms))
    			{
    				Array.ForEach(Enumerable.Range(0, h.Length).ToArray(), i => bw.Write(h[i]));
    
    				for (int i = 0; i < smp; i++)
    				{
    					Int16 s = Convert.ToInt16((((amp * (Math.Pow(2, 15))) / 1000) - 1) * Math.Sin((2 * Math.PI * freq / 44100.0) * i));
    					Array.ForEach(Enumerable.Range(1, 2).ToArray(), n => bw.Write(s));
    				}
    
    				bw.Flush();
    				ms.Seek(0, SeekOrigin.Begin);
    				using (SoundPlayer SP = new SoundPlayer(ms)) { SP.PlaySync(); }
    			}
    		}
    	}
    }
    And to test, i've created a little Twinkle Twinkle little star melody for you guys :)

    Code:
    new Thread(new ThreadStart(
    	(MethodInvoker)delegate
    			{
    				int[] freqs = { 
    									  131, 131, 196, 196, 220, 220, 196, 0,
    									  175, 175, 165, 165, 147, 147, 131, 0,
    									  196, 196, 175, 175, 165, 165, 147, 0,
    									  196, 196, 175, 175, 165, 165, 147, 0,
    									  131, 131, 196, 196, 220, 220, 196, 0,
    									  175, 175, 165, 165, 147, 147, 131, 0
    								  };
    				Array.ForEach(freqs, f => Sound.CreateBeep(1000, f, 400));
    			}
    )).Start();
    We use a BinaryWriter to write to a MemoryStream, so that we can load that data (bytes) using a System.Media.SoundPlayer. What needs to happen first though is that we write the WAV file header to the MemoryStream, then, we can start writing out the samples using a formulated value. Flush the rest of the data out of the BinaryWriter, and reset the start position of the MemoryStream back to the beginning for our SoundPlayer to use the data in the MemoryStream to be played. If you use the Play() method instead of PlaySound() you get a really cool distorted sound effect :)

    To do that, look into the class and change:
    Code:
    using (SoundPlayer SP = new SoundPlayer(ms)) { SP.PlaySync(); }
    To:
    Code:
    using (SoundPlayer SP = new SoundPlayer(ms)) { SP.Play(); }
    Just one of the things I noticed while doing this.

    I got the idea from here: http://paste.blixt.org/543

    Highest amplitude you'll want would be 1000, if you want to provide handling for that, you can probably check that parameter and throw an exception if it's too high:
    Code:
    if (amp > 1000) throw new Exception("Amplitude too high");
    Last edited by AceInfinity; 06-23-2012 at 06:43 PM.
    Automation Programmer
    Microsoft MVP [2012 - 2018]


    • Ad Bot

      advertising
      Beep.

        
       

  2. #2
    jcgriff2's Avatar
    Join Date
    Feb 2012
    Location
    New Jersey Shore
    Posts
    16,323
    • specs System Specs
      • Manufacturer:
        HP
      • Model Number:
        HP ENVY TouchSmart 17-j130us Notebook - E8A04UA
      • Motherboard:
        HP Insyde 720265-501 6050A2549501-MB-A02
      • CPU:
        Intel Core i7-4700MQ Processor with Turbo Boost up to 3.4GHz.
      • Memory:
        12GB DDR3L SDRAM (2 DIMM)
      • Graphics:
        Intel HD graphics 4600 with up to 1792MB total graphics memory
      • Sound Card:
        Beats Audio quad speakers and two subwoofers
      • Hard Drives:
        1TB 5400RPM hard drive with HP ProtectSmart Hard Drive Protection
      • Disk Drives:
        Hitachi 500 GB SSD; 7 TB USB External
      • Power Supply:
        90w
      • Case:
        Laptop
      • Display:
        17.3-inch diagonal HD+ BrightView LED-backlit touchscreen display (1600 x 900)
      • Operating System:
        Windows 8.1

    Re: [C#] Loading WAV formatted beep to MemoryStream & played by system audio

    I like system sounds; hence the reason only IE is used here.

    You're coding up a storm!

    BSOD Posting Instructions - Windows 10, 8.1, 8, 7 & Vista ` ` `Carrona Driver Reference Table (DRT)
    https://www.sysnative.com/
    Sysnative Hex-Decimal-UNIX Date Conversion

    Has Sysnative Forums helped you?
    Please consider donating to help support the forum.
    Thank You!

    Microsoft MVP 2009-2015
    Windows Insider MVP 2018 - Present

  3. #3
    AceInfinity's Avatar
    Join Date
    Feb 2012
    Location
    Canada
    Posts
    1,725

    Re: [C#] Loading WAV formatted beep to MemoryStream & played by system audio

    Browsers could be created to make system sounds based on the defaults if they wanted to, I think they get annoying though lol. I wish more people would be in these parts of the forum though :)
    Automation Programmer
    Microsoft MVP [2012 - 2018]

Similar Threads

  1. Audio drop outs on a known latency issue system
    By madbadger in forum Windows 7 | Windows Vista
    Replies: 6
    Last Post: 06-17-2013, 12:50 PM
  2. Audio Virus and BSOD Support
    By reztreib in forum Security Arena
    Replies: 7
    Last Post: 05-17-2013, 09:53 AM
  3. Audio cuts out on video players
    By Chupacablehbleh in forum Windows 7 | Windows Vista
    Replies: 4
    Last Post: 05-02-2013, 05:36 PM
  4. Replies: 5
    Last Post: 06-02-2012, 10:53 AM

Log in

Log in