SoundPlayer not playing any bundled windows sounds PCM wav files - c#

In C# I cannot get SoundPlayer class from System.Media to play any wav from my C:\Windows\Media folder using the following code. All I get is no sound:
String filename = "C:\\Windows\\Media\\tada.wav";
SoundPlayer sp = new SoundPlayer(filename);
sp.Load();
sp.Play();
I have checked the wave file "tada.wav" with a program called "Gspot" that tells me the audio codec is "PCM Audio". I do not receive any compiler warnings or errors and there is no exceptions raised when I run the program. I just do not get any sound. My speakers are on, and I can play the file with Windows Media Player.
Adding the wav as a project resource does not make any difference. Could somebody please help me figure out why I cannot get any sound?

The Play() method plays the sound a separate thread. That is, the console app spins a new thread in which to play the sound. This is great for Windows applications so that the sound playing does not stop the Windows main thread. In a console app, when the parent thread ends the child threads all die as well. -- thus no sound.
There is a PlaySync() method that does NOT spawn a new thread and thus will keep the console app thread alive until it has finished playing your sound.

Are you using this as the body of a main() method in a console application? The application is probably ending, thereby shutting down the thread which plays the audio.
I copied and pasted your code into the main of a new "Visual C# Console Application". I added the "using System.Text;" line at the top of the file, compiled, stepped through it, and it worked. When I ran it (without debugging) I got no sound.
If you add the line:
System.Threading.Thread.Sleep(2000);
After the call to Play(), the application will stay around long enough to play the audio.

For me (VS 2022, .net 6, C # 10) it worked:
Import the "tada.wav" file into the main directory.
Change in: Properties (tada.wav) - Copy to Output Directory to: Copy always.
Later it was enough to:
SoundPlayer player = new SoundPlayer("tada.wav");
player.Load ();
player.Play ();

Related

C# Windows Form App - choose output audio device

I'm trying to do some basic app, with System.Speech.Synthesis in c#
It's just a basic form with a text input and after pressing enter it reads the text using ss.SpeakAsync();
The goal is to play that sound on a exact audio output device on Windows but I can't achieve that.
I've tried do it by windows settings, App volume and device preferences, but it doesn't work, not sure why.
I'm setting the correct device, but it plays on the "default" anyways, no matter what I do. It works with any other application correctly (like browser for example) bit with mine it doesn't. It works when I change all system audio to that device, but the main goal is that i want only this app to use "cable input".
I've tried to use some 3rd party software to do this (https://github.com/a-sync/audio-router) but it doesn't work either. I set everything, and when I click "play" in my app, then my app crashes with an exception: „[17132] TrayReader.exe” exited with code -1073741819 (0xc0000005) 'Access violation'.
So maybe I'm able to set in the code the correct audio output device? Or how do I fix those previous errors? maybe I need to add some privileges or something? I'm mainly web developer, this is my first time with windows app.
//edit -> it works, when i change all my system audio to cable input, play some sound, and then go back to my main device. It seems like a windows bug?
you may use a 3rd lib Naudio; the example below shows how to return to current position in case the player was playing a song. The key code is player.DeviceNumber = deviceNum; in which deviceNum is 0, 1, 2... depending how many speakers are available in your PC.
A disadvantage of Naudio is that it loads completely the song before playing, and quite slow.
var playback = player.PlaybackState;
if (playback == PlaybackState.Stopped) // change and exit
{
player.DeviceNumber = deviceNum;
return;
}
var currentTime = reader.CurrentTime;
player.Stop(); // must stop to change output
player.DeviceNumber = deviceNum;
player.Init(reader);
reader.CurrentTime = currentTime;
if (playback == PlaybackState.Playing)
player.Play();

Trouble Opening Finder Window and Accessing Hardware on MacOS

I have a fairly large project on Unity 2018.4.2 that is failing in two places when I build: connecting to the user's microphone and opening the Finder window. Opening Finder takes up to 30 seconds to actually open it and microphone hangs whenever I try to start it.
We use the code below to open the Finder Window
System.Diagnostics.Process p = System.Diagnostics.Process.Start("open", $"\"{macPath}\"");
It eventually opens the Finder window, but only after 10-30 seconds. Meanwhile, a MacOS process called "tccd" kicks in causing the CPU to spike.
For Microphone, we use Unity's built-in Microphone class and we get hangs that last for 15-50 seconds. Same thing happens where the "tccd" process kicks in and spikes our CPU.
When we try to connect to the microphone the first time the OS asks us once if we want to allow the app to access the microphone, but it always hangs even after confirming. It never asks us about accessing Finder.
It seems like the MacOS is actively trying to slow us down from accessing these, but not completely stopping us, as Finder eventually opens and the microphone eventually connects (sometimes). We do not have these problems on Windows, it's only on MacOS. Any thoughts as to what is happening?
Note: There are no problems in Editor, only in Mac builds
We found the problem. Our code had to be signed in order to use it on a Mac. Now that the app is signed, we have access to everything we need as listed in our entitlements file

C# playing multiple audio files at once from your resources?

I'd like to be able to press a button to play a sound of a button being pressed while music is already playing. SoundPlayer is no help because it stops the music to play the sound.
I have added the sounds to my Resources (WindowsFormsApplication2.Resources.Properties.button) and I don't want to have to type in the file location.
Answer from MerickOWA
You CANNOT play two sounds at once using SoundPlayer.
SoundPlayer is using the native WINAPI PlaySound function to accomplish the task which has no support for playing simultaneous sounds. Creating multiple instances of SoundPlayer won't help.
There are many options most of which involve implementing a lot of the low level API to window's native audio library or DirectSound (note neither are C# and require alot of interop code)
The simplest option would be to depend on windows media player to play the audio for you.
Add a reference to "C:\Windows\System32\wmp.dll"
then use
var player = new WMPLib.WindowsMediaPlayer();
player.URL = #"..\..\bin\debug\tribal dance.wav";
Note: play starts immediately after setting the URL property
The down side of this approach is your reliance on media player for your application to work properly. On the upside, you can use any file format media player supports.

C# Process properties

I'm using win platform and Unity3D game engine to create 3D app. When running, 3d application is in full screen mode. I'm using the following code to call VLC player from this app:
string _path = "C:\\Users\\Saska\\Desktop\\Videi\\intro.mpg --fullscreen";
foo = new Process();
foo.StartInfo.FileName = "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe";
foo.StartInfo.Arguments = _path;
foo.StartInfo.CreateNoWindow = true;
foo.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
foo.Start();
It happens that, when I run VLC, I see VLC window in the beggining (for 2 seconds, until it buffers a movie), then it gets minimized and I see the movie running in full screen mode. When it finishes, I have to close VLC manually, but it happens that my 3D application gets minimized and I have to click on it "to make it normal - fullscreen" again.
Is it possible:
- to avoid appearance of VLC window in the begging, just to see full screen movie play (I assume no, since VLC player reads the movie)
- to make my 3d app window running beneath VLC player in full screen mode so it happens that when VLC finishes I can see 3d app again in full screen mode
- to make VLC shuts down when the movie is finished
I'm new to process programming and don't know which terms to "google". I found process NET library, but I see no useful parameters.
Thank you very much.
Aleksandra
You're better off using the .Net Interface to VLC. It should be quite easy to use.
Here's a complete sample source code : DMediaPlayer - Simple VLC frontend

System.Media.SoundPlayer.Play() freezes GUI

I am trying to implement a simple game in .NET with C#. There is a ball bouncing against objects, and when it bounces I play a sound asynchronously using System.Media:SoundPlayer. The problem is that most of the time (not always) the ball freezes at the time of impact, for as long as the sound plays.
This happens on Windows XP, but not on Windows 7. I use .NET 3.5.
And the weirdest thing is that the problem disappears if I open the application Windows Media Player and play a few seconds of an mp3.
Here's the code where I initialize the SoundPlayer object:
System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("Game.Resources.GameBounce.wav");
_playerBounce = new System.Media.SoundPlayer(s);
_playerBounce.Load();
...and when the ball hits an obstacle, this line is called:
_playerBounce.Play();
I have also tried "Attempt #4" in this post:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
Another desperate attempt, based on some advice I found somewhere on the net, was to save the sound stream to a file, that SoundPlayer works better when initialized from a file.
Neither of those attempts worked.
Any ideas?

Categories