Attenuating SoundPlayer Volume  
Author Message
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

I use SoundPlayer to punctuate long file downloads and other processes and give me sound cues of the app state in broad sense. One problem I have now is that the volume is so loud that after a long pause it might frighten me a bit with some sounds. Manually adjusting volume in SoundPlayer 10 does not seem to help.

I cannot get a hang of it although I tried numerous inroads. SendKeys.Send ( "VolumeDown" ); did not work. I tried to exploit Volume.exe: Set Volume Control Levels Using Visual Basic at http://www.hide-link.com/ %3bEN-US%3bQ178456&%5d and another related sites to no avail so far.

It may all boil down to controlling volume in MS kernel sound mixer or something, I do not know.

Please, help.




Visual C#20  
 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

BTW, I forgot to mention that I do have this Super Natural MS keyboard, wireless and with all the extra keys for media control and when I click the "-" or "+" keys at the center of keyboard it affects the volume pretty well. However, I want to have a task oriented volume control free of manual interference and I know it is possible.

Thanks.



 
 
Evan Mulawski





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace VolumeControl
{
   public partial class Form1 : Form
   {

      [DllImport("winmm.dll")]
      public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

      [DllImport("winmm.dll")]
      public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);


      public Form1()
      {
         InitializeComponent();
         // By the default set the volume to 0
         uint CurrVol = 0;
         // At this point, CurrVol gets assigned the volume
         waveOutGetVolume(IntPtr.Zero, out CurrVol);
         // Calculate the volume
         ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
         // Get the volume on a scale of 1 to 10 (to fit the trackbar)
         trackWave.Value = CalcVol / (ushort.MaxValue / 10);
      }

      private void trackWave_Scroll(object sender, EventArgs e)
      {
         // Calculate the volume that's being set. BTW: this is a trackbar!
         int NewVolume = ((ushort.MaxValue / 10) * trackWave.Value);
         // Set the same volume for both the left and the right channels
         uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
         // Set the volume
         waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
      }

   }
}

 

Thank You, GEEKPEDIA.COM

 

If you want to change the volume on the keyboard, try the keydown event, then:

if (e.KeyCode == Keys.VolumeUp) [or VolumeDown]

{

trackWave.Value--; / ++;

[or]

trackWave.Value = trackWave.Value - 10; / +10

}



 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

Thank you very much, Evan. I will try the code tomorrow but I can see it even now that it is pretty much what I wanted and it should work.

 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

Evan hi,

I did check the code. It works very well. I simplified and modified it according to may spec. I do not have a slider to scroll. I ran into a peculiar problem though. I will explain it after you take a look at the code.

class Form1
{
[DllImport ( "winmm.dll" )]
public static extern int waveOutGetVolume ( IntPtr hwo, out uint dwVolume );
[DllImport ( "winmm.dll" )]
public static extern int waveOutSetVolume ( IntPtr hwo, uint dwVolume );

private void button1_Click (object sender, EventArgs e)
{
TrackWave trackWave = new TrackWave();
trackWave.Value = 3;
trackWave_Control ( trackWave );

// trackWave.Value = 10; // <== an attempt to reset the Value screws the previously reset volume
// trackWave_Control ( trackWave );
}

private void trackWave_Control ( TrackWave trackWave)
{
// Calculate the volume that's being set. BTW: this is a trackbar!
int NewVolume = ((ushort.MaxValue / 10) * trackWave.Value);
// Set the same volume for both the left and the right channels
uint NewVolumeAllChannels = ((( uint )NewVolume & 0x0000ffff) | (( uint )NewVolume << 16));
// Set the volume
waveOutSetVolume ( IntPtr.Zero, NewVolumeAllChannels );
} // trackWave_Control
}

public class TrackWave
{
private int Value_ = 0;
public int Value
{
get { return Value_; }
set { Value_ = value; }
}
} // class TrackWave

There is an arrow pointing to the problem statement. I commented this one and next one out. What happens is that when those two statements are absent the speaker volume is attenuated all right. I put those two statements in an attempt to restore the volume for the next occasion somewhere at a different place in the app.

It turned out that the second tackWave.Value = 10; had a retroactive effect on the first one and the sound was loud as if the first statement did not even exist.

Why is it so

It does not seem to be a lethal problem. I will use the code all right anyway.

Thanks.



 
 
Evan Mulawski





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

What control are you using

 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

What control are you using

Evan, I do not have a control the way you think I do. I mean, there are many but they are for different other reasons. The thing is if I click a button and a successful connection is made to the server I want to have a sound cue tell me that. Thus that Click event may have a call to the sound routine and since many .wav files actually sound at different volume I want to have control over that too.

When a set of some 300 files finished downloading and it sometimes takes 10 min I want to have another sound event, etc.

I just want to know how I can have a complete freedom in sound control.

That question I asked why the second call to volume control routine retroactively spoils the first one is not a good one. I do understand why it happens: the OS prioritizes threads and sound is an output and therefore has lower priority. Apparently, the OS first rushes all commands that change something in the internals and then the turn comes for the sound to get output.

I want to know if there is a workaround for this dilemma.

Thanks.



 
 
Evan Mulawski





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

You could try using a trackbar and using the scroll value to update the server cue.

Also, for the .wav files, try using an IF statement to check the file extension, then lowering the volume by a certain amount, say Value = Value - 10.

Does this help at all

As for the Threads, use this:

ThreadStart tStart = new ThreadStart(put the method here that uses the sounds);

Thread threadMethod = new Thread(tStart);

threadMethod.Start();



 
 
cablehead





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

If you supply the wavs....why not just normailize the volume of all wavs

 

Even sndrec32.exe, provided with Windows can do this.

This way you can set the volume once...and forget about it.



 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

You could try using a trackbar and using the scroll value to update the server cue.

Also, for the .wav files, try using an IF statement to check the file extension, then lowering the volume by a certain amount, say Value = Value - 10.

Does this help at all

As for the Threads, use this:

ThreadStart tStart = new ThreadStart(put the method here that uses the sounds);

Thread threadMethod = new Thread(tStart);

threadMethod.Start();

Thank you Evan. That thing about checking the extension is somewhat superfluous. I do know the extension in advance. The file path is a parameter. I can lower the volume according to individual files but the trouble is: it will complicate my life in the long run. Suppose I have 50 places in the code where I invoke 10 sound files in aggregate, one wav file per place. If I forget to individually adjust the volume beforehand this file may not sound right or something. I kind of thought that I could find a global inroad to this problem.

However, I think your idea about using soundPlayer in a Thread is much better. It may actually work. It is pity this simple thing has never occured to me.



 
 
AlexBB





PostPosted: Visual C# General, Attenuating SoundPlayer Volume Top

If you supply the wavs....why not just normailize the volume of all wavs

Even sndrec32.exe, provided with Windows can do this.

This way you can set the volume once...and forget about it.

It is an incredibly cute and useful toy! Thank you very much. This may be what I actually need.

I am not in the sound that much so for me it was an eye opener.