Welcome to irritatedVowel.com Sign in | Help

POKE 53280,0: Pete Brown's Blog

Silverlight, WPF, Windows Client Development, Woodworking, .NET Programming, CNC, Nature, and other topics.

Subscribe

Subscribe to my feed
Add to Technorati Favorites

My Book

Order my upcoming book, Silverlight in Action, covering Silverlight 4, ViewModel/MVVM, WCF RIA Services, MEF and more

About Pete Brown

Pete Brown is a Microsoft Developer Division Community Program Manager, focusing on Windows Client Development as well as a former Microsoft Silverlight MVP and INETA Speaker. Pete writes on a number of topics including Silverlight, WPF, .NET, woodworking and working as a consultant in the DC area. read more

Community Events


who's online

AddThis Social Bookmark Button

Silverlight Synthesizer Source Code – MediaStreamSource Raw Sound

A while back, I wrote about the sound test project I created in Silverlight that quickly turned into an experimentation on audio synthesis.

Silverlight sound synthesizer

I plan to set up a codeplex site for this once I get back from vacation. However, since I’ve had a few requests for the source, I thought I’d quickly post it here.

Issues

  • My mixing algorithm is bad. If anyone knows the right algorithm for mixing multiple channels of sound, while keeping the same end volume regardless of how many channels are mixed (including times when some of the channels are silent) I’d love to know it. Please share!
  • Related to above, you can get distortion pretty quickly when you press more than a few notes
  • Fair bit of dead code – this is a test project :)

None of those are Silverlight issues – they’re issues with my code.

One key thing that changed in Silverlight 3 RTW vs. the beta was the addition of the new MediaStreamSource AudioBufferLength property. It represents the number of milliseconds of sound to buffer before output. The minimum value is 15, but on most machines you won’t be able to get close to that unless you have highly optimized sound generation code (doing wavetable lookups rather than real-time sawtooth waves, for example)

This value is highly machine dependent, so if you do anything serious with this code, you’ll want to make that something the user can change to suit their own machine. To low a value and the sound will stutter, too high and the sound will have an audible delay.

The value is in the InitializeMediaStreamSource method of Synthesizer.MediaStreamSource.cs

AudioBufferLength = 30;

Source code is available here. I hope it helps jumpstart your own projects.

  Add to Technorati Favorites
Posted: Sunday, July 19, 2009 11:32 AM by Pete.Brown

Comments

NewsPeeps said:

Thank you for submitting this cool story - Trackback from NewsPeeps
# July 19, 2009 12:16 PM

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout
# July 19, 2009 5:34 PM

sapience said:

you done your work with great perfection you invented the silversynthesizer.its sound speed is best than others this synnthesier is totally based on a machine. its frequency is too high its achieve success in market . ==================================================== reshu
# July 20, 2009 3:32 AM

Pete.Brown said:

@sapience

Not sure what you're saying there. The project is a test, and not meant to compete commercially.

As to frequency being too high...try a key lower on the keyboard :)

Pete

# July 20, 2009 10:15 AM

Pete said:

Excellent work! I've been looking for some interesting Silverlight examples with the intention of writing a simple synthesizer. Thanks for posting the code - that gives me more than the head start I was looking for :) I think the answer to your mixer problem is just to give yourself more headroom. The overall level should increase if you add another channel to the mix. If you want the level to stay roughly the same then add a compressor. I'm really looking forward to playing about with this code - I'll try and add some analogue style filters. Pete (a different one...)
# July 22, 2009 5:20 AM

Ryan Brown said:

For channel mixing... Add together all the outputs while keeping track of how many outputs you have. Then if your total number of outputs is below say, 2.5, set it to 2.5. Then divide your summed outputs by that number. Feel free to email me for any more synth questions...
# July 23, 2009 1:58 AM

Pete.Brown said:

@Ryan

Thanks.

I ran into a number of problems doing that, but I think it was just due to how I got the samples to begin with.

Pete

# July 24, 2009 12:44 AM

kindohm.com said:

Silverlight Synthesizer Progress (with audio!)
# July 24, 2009 11:12 PM

System.Reflection.Emit said:

Silverlight 3 Is A Lot Cooler, But Still Not Worthy Of Taking Seriously
# August 5, 2009 2:05 AM

System.Reflection.Emit said:

Silverlight 3 Is A Lot Cooler, But Still Not Worthy Of Taking Seriously
# August 5, 2009 2:18 AM

Silverlight al descubierto said:

Pete Brown ha puesto a disposición el código fuente de un sintetizador desarrollado en Silverlight 3
# August 5, 2009 10:00 AM

Silverlight al descubierto said:

Pete Brown ha puesto a disposición el código fuente de un sintetizador desarrollado en Silverlight 3
# August 5, 2009 10:02 AM

Microsoft Weblogs said:

Anyone who has spent more than 5 minutes talking with me, reading this blog, or listening to me on podcasts
# August 21, 2009 11:19 AM

Tim Heuer said:

Anyone who has spent more than 5 minutes talking with me, reading this blog, or listening to me on podcasts
# August 21, 2009 11:53 AM

Microsoft Weblogs said:

Talking amongst a few of my cohorts, Erik Mork asked “What are your favorite apps to show?” After some
# August 26, 2009 7:12 PM

TheNut said:

Cool app, but you have a runaway memory leak with your _steam MemoryStream object. You keep adding onto it, but that's not necessary because Silverlight will copy the stream over to a sound buffer object after you make the call to ReportGetSampleCompleted(). You should reuse the 512 bytes of memory on each pass rather than continuously adding onto it. You'll also gain a slight performance boost if you deal with the byte array directly rather than calling the memory stream functions (negligible, but every bit counts in .NET). It's also worth noting (an FYI) that the timestamp is optional. If you're not going to display the current playback time from the media element, you could save some cycles by avoiding those calculations. Just slap a "1" or some random value (other than 0) in the MediaStreamSample object and it will work out as well. This is an interesting application and I hope you continue on it. I think if you work on minimizing the CPU load, you'll fix the audio latency issue that pops in when 2 or more signals are being processed. In my own audio engine, I manage dozens of waves, some with carrier signals with optional ADSHR applied. It takes up no CPU usage (1.8GHz core duo). Cheers!
# August 29, 2009 4:31 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the text you see in the image:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS