Volume and Media events functions not working?

Oct 12, 2010 at 12:29 PM

First, great job to the author of this kit. 

I can get MediaUriPlayer to play sound.   I tried setting different levels for volume on the MediaUriPlayer and it does not respond.   Also could not get Loop to work and none of the media events do fire.  There was a slight modify required in WorkDispatcher to get MediaUriPlayer to play sound.  Anyone know how to get Volume + Media events to work?

I noticed this same problem with DirectShow PlayWnd2008 sample. 

TIA.

Sep 19, 2011 at 6:55 PM

Yep, I have similar problem.

When I set Volume to 0 there is (logically) no sound.
When I set Volume to 1 volume is on maximum possible level.

But when I setting volume from 0.1 to 0.49 it acts like there is no sound. I can hear audio just from value 0.5 maybe 0.4, but it sounds like the volume is set to 0.1.

Any ideas? Fixes?

 

jmorill, indeed very very good work! Video and audio playing smoothly even when there is multiple instances of media player.

Sep 20, 2011 at 6:16 AM

I've found that WPF Media Kit volume works on a log scale in many hardware environments.

Therefore, 0.7 is probably already less than half the volume.

This probably came from DirectShow, which also worked in a log scale but from -10,000 to 0.

- Stephen

Sep 20, 2011 at 9:53 PM

Thanks Stephen for explanation! Good one :-)

Sep 21, 2011 at 11:35 AM

FWIW, the following is the code I used to map device audio volume to 0-100:

		private const double MinBase = 0.7;

		/// <summary>Map audio device volume to percentage</summary>
		/// <param name="volume">Audio device volume value</param>
		/// <param name="minvalue">Minimum device audio volume</param>
		/// <param name="maxvalue">Maximum device audio volume</param>
		/// <param name="minbase"></param>
		/// <param name="maxbase"></param>
		/// <param name="logscale">Is logarithmic scaling used?</param>
		/// <param name="slots">Number of slots to fit the percentage into</param>
		/// <returns>Percentage volume, 0 to 100</returns>

		public static int VolumeToPercent (double volume, double minvalue = 0, double maxvalue = 1, double minbase = MinBase, double maxbase = 1, bool logscale = true, int slots = 100)
		{
			if (volume <= minvalue) return 0;
			if (volume >= maxvalue) return 100;

			if (logscale) {
				var minrange = Math.Pow(10.0, (minvalue - minbase) / (maxbase - minbase));
				var maxrange = Math.Pow(10.0, (maxvalue - minbase) / (maxbase - minbase));

				var p = Math.Pow(10.0, (volume - minbase) / (maxbase - minbase)) - minrange;
				var r = (maxrange - minrange) / slots;
				var px = (int) Math.Round(p / r);

				double r100 = 100.0 / slots;
				return (px <= 0) ? 0 : ((px >= slots) ? 100 : (int) Math.Round(px * r100));
			} else {
				return (int) ((volume - minvalue) / (maxvalue - minvalue) * 100);
			}
		}

		/// <summary>Map percentage audio volume to device audio volume</summary>
		/// <param name="percent">Percentage volume, 0 to 100</param>
		/// <param name="minvalue">Minimum device audio volume</param>
		/// <param name="maxvalue">Maximum device audio volume</param>
		/// <param name="minbase"></param>
		/// <param name="maxbase"></param>
		/// <param name="logscale">Is logarithmic scaling used?</param>
		/// <returns>Device audio volume</returns>

		public static double PercentToVolume (int percent, double minvalue = 0, double maxvalue = 1, double minbase = MinBase, double maxbase = 1, bool logscale = true)
		{
			if (percent >= 100) return maxvalue;
			if (percent <= 0) return minvalue;

			if (logscale) {
				double minrange = Math.Pow(10.0, (minvalue - minbase) / (maxbase - minbase));
				double maxrange = Math.Pow(10.0, (maxvalue - minbase) / (maxbase - minbase));

				return (maxbase - minbase) * Math.Log10((percent / 100.0) * (maxrange - minrange) + minrange) + minbase;
			} else {
				return (maxvalue - minvalue) * (percent / 100) + minvalue;
			}
		}

Sep 21, 2011 at 5:17 PM

This is great! I really appreciate your contribution.

The code looks very clear and also love the complete help :-) Nicely done

Detecting the current volume system (log or standard) maybe? Specifically I would like to determine whenever I must pass false/true to logscale variable. If you have code for that, this thread will shine because of its perfection :-P

Sep 22, 2011 at 4:57 AM

Well, unfortunately, I don't think there is an auto-detection method.  You'll have to experiment with different hardware to get the characteristics of each device separately.  I've found that most devices are log (although a few rare ones are linear), and that 0.7 as a coefficient works well in most cases.  Please let me know if you discover a way to find this info automatically!