Music & Sound With C++ - c++

Problem:
I need music that repeats/loops in the background while I am running my program. Then, when I get to another part of my program, that background music needs to pause, play another sound file, then resume the background music.
Example Of Problem:
For example, I have a Blackjack program that plays the background music when you run it. Then, when you actually log in or create an account it plays a sound file that says "Welcome". Or if i get to a function that shuffles my vector(deck of cards), it plays a sound effect that sounds like a deck of cards shuffling.
What I Have Tried:
Playsound() - It loops/repeats but does not allow me to pause, resume, etc. My code is:
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib") // Link to the winmm library
PlaySound(TEXT("86876__milton__title-screen.wav"), NULL, SND_LOOP | SND_ASYNC); // Background music
MCI - Can't figure out how to get it to loop/repeat, pause, or resume. All I can get is the following code:
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib") // Link to the winmm library
MCIERROR me = mciSendString("open 86876__milton__title-screen.wav type waveaudio alias song1",NULL, 0, 0);
if (me == 0)
{
me = mciSendString("play song1", NULL, 0, 0);
}
I keep reading that I need to stay away from 3rd party stuff when working with Visual Studio, or anything Microsoft. But, if you can suggest something that is nice and easy, then please.
Other:
I am a beginner so I need it to be as simple as possible. For Python Pygame mixer, it is literally 1 line to play, pause, resume etc. I need something like that!

Related

Correct use of PlaySound function in C++

I'm having some issues utilizing the built-in function PlaySound. I continuously receive two errors, the first being:
argument of type "const char *" is incompatible with parameter of type "LPCWSTR",
and the second being:
'BOOL PlaySoundW(LPCWSTR,HMODULE,DWORD)': cannot convert argument 1 from 'const char [35]' to 'LPCWSTR'.
I can't seem to resolve these issues on my own, and would like some help with figuring out how to get rid of the errors. Here's a section of my source code, including what I believe to be causing the error.
#include <iostream>
#include <string>
#include <iomanip>
#include <dos.h>
#include <windows.h>
#include <playsoundapi.h>
#include <mmsystem.h>
using namespace std;
int main()
{
PlaySound("C:\\Users\\Cristian\\Desktop\\cafe.mp3", NULL, SND_FILENAME | SND_ASYNC);
return 0;
}
If I am using the PlaySound function incorrectly,please point me to the correct direction.
LPCWSTR is a macro for const wchar_t * - so you need to use a wide-character wchar_t string L"" instead of a normal char string "".
const wchar_t* path = L"C:\\Users\\Cristian\\Desktop\\cafe.mp3";
PlaySound( path , NULL, SND_FILENAME | SND_ASYNC );
The old-school Win32 way would be to use TCHAR with optional #define UNICODE but this is considered an anachronism as the "ANSI" Win32 functions don't support UCS-2/UTF-16 (and MBCS does not refer to UTF-8, surprisingly).
Note that you probably want to use SND_SYNC instead of SND_ASYNC because your program will terminate before the sound finishes plaiyng.
Finally, PlaySound does not support MP3 files - only Wave files - so your code won't work regardless.
To play MP3 files in Win32 you need to use either:
MCI (Media Control Interface - an ancient API from the Win3x days, yet surprisingly is the simplest - needing only a two function calls):
mciSendString("open \"fileName.mp3\" type mpegvideo alias mp3", NULL, 0, NULL);
mciSendString("play mp3", NULL, 0, NULL);
DirectShow - This is the official Windows multimedia API, but it's based on COM and requires you to create a component-graph (file parser, decoders, output devices, etc) so it has a steep learning curve. See here for the minimum code required - almost 60 lines ( https://msdn.microsoft.com/en-us/library/windows/desktop/dd389098.aspx )
Windows Vista introduced MediaFoundation to replace DirectShow, but in my experience it's not much better than DirectShow in terms of programmer-ergonomics: https://msdn.microsoft.com/en-us/library/windows/desktop/ms703190(v=vs.85).aspx
For Windows 10, there is a WinRT API for playback - but I haven't done much research and I don't know if you can call it from "real" Win32 programs or if it's reserved only for sandboxed UWP applications: https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/media-playback

c++ - beep not working (linux)

I'm trying to beep, but I simply can't. I've already tried:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << '\a' << flush;
return 0;
}
I have also tried using this: http://www.johnath.com/beep/
But simply doesn't beep.
(If I run $ speaker-test -t sine -f 500 -l 2 2>&1 on the terminal, it beeps, but I would like to beep with c++ to study low-level sound programming)
And I would like to be able to control frequency and duration.
Unless you're logged in from the console, cout will not refer to the system console. You need to open /dev/console and send the \a there.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int s = open ("/dev/console", O_WRONLY);
if (s < 0)
perror ("unable to open console");
else
{
if (write (s, "\a", 1) != 1)
perror ("unable to beep");
}
}
This depends on terminal emulator are you using. KDE's Konsole, for example, doesn't support beeping with buzzer at all AFAICT. First check that echo -e \\a works in your shell. If it doesn't, your C++ code won't work too. You can use xterm — it does support this.
But even in xterm it may not work if you don't have pcspkr (or snd_pcsp) kernel module loaded. This is often the case when distros blacklist it by default. In this case your bet is looking for a terminal which uses your sound card to emit beeps, not PC speaker AKA buzzer.
You're asking about "low level sound generation", typically, the lowest level of sound generation would involve constructing a wave form and passing it to the audio device in an appropriate format. Of course, then it comes out from your sound card rather than the PC speaker. The best advice I can give would be to read up on the APIs associated with pulse audio, alsa, or even the kernel sound drivers. Last time I played with this (~1996), it basically meant allocating an array of samples, and then computing values to put in there that approximated a sine wave with the appropriate frequency and amplitude, then writing that buffer to the output device. There may have even been some calls to ioctl to set the parameters on the device (sample rate, stereo vs. mono, bit rate, etc). If your audio device supports midi commands, it may be easier to send those in some form that is closer to "play these notes for this long using this instrument".
You may find these articles helpful:
https://jan.newmarch.name/LinuxSound/
http://www.linuxjournal.com/article/6735
Have you tried system call in your application?
system("echo -e '\a'");

How do i play sound in my C++ Windows Game?

Windows 7 Ultimate 64Bit, I am using CodeBlocks 16.01. I am working on my OpenGL college project, I'm trying to add a gun sound effect when the player shoots using the 'spacebar' key.
The sound only works when i create a console project or empty project and the sound plays just fine, I am aware of the library "winmm.lib" that i have to link, and it works just fine as a CONSOLE PROJECT, here is the code for this.
#include <iostream>
#include <windows.h>
#include <mmsystem.h>
using namespace std;
int main()
{
PlaySound("shotgun.wav",NULL,SND_SYNC);
return 0;
}
The problem begins when i now use this code in my Glut Project, what happens is instead of playing "shotgun.wav" it plays one of the windows system sounds called "Default Beep", When the shooting button "spacebar" is pressed. The game was freezing a few seconds until the sound has completed, however i fixed this issue by replacing thw above line with this one :
PlaySound(TEXT("shotgun.wav"), NULL, SND_FILENAME | SND_ASYNC);
It doesn't freeze anymore, But Still, It continues to play that Windows System sound instead of the shotgun.wav. The .wav file is IN the project, i'm pretty sure it's in the right place. here is the sample for shoot code from my Glut project (i only copied the relevant piece of code) :
void Keys(unsigned char key, int x, int y) {
key = tolower(key); //Just in case CAPS LOCK is ON.
if(key==27)
exit(0); //Escape key, Exit the game
switch(key){
case ' ': //SPACE BAR
/* some code here */
PlaySound(TEXT("shotgun.wav"), NULL, SND_FILENAME | SND_ASYNC);
break; //.....Code continues to the next case....
To force the gun sound effect, i had to go to Windows Sound settings and "Change System sounds", lol yep i actually had to replace "Default Beep" with my "Shotgun.wav", i then returned to the game and compiled, and wala ! It was working. BUT of course this is NOT what i want, cause obviously this will only work on my PC and we don't want that.
You need to specify the full file path. Use double slash \\ in between. For example:
sndPlaySound("D:\\New folder(2)\\poiuy\\sound.wav",SND_ASYNC|SND_LOOP);

Play Music File in C++

I'm working on creating my own alarm, and I would like to play my own music files using c/c++. The only C++ function I could find that plays anything is PlaySound(), but I can't seem to get that to work and I'm not sure what I'm doing wrong. I have included Winmm.lib, which lets me play the default sound, but now i'm trying to play my music file. (in wma format).
This is my code so far:
#include <Windows.h>
int main(){
PlaySound(TEXT("test.wma"), NULL, SND_FILENAME);
return 0;
}
I've also added the SND_NODEFAULT flag in there as well so I could stop hearing the default sound.
As far as I know PlaySound supports only .wav files.
If you want to play .wma you need either to use Audio Compression Manager or one of the third party audio libraries.
Try with simple c++ code in VC++.
#include <windows.h>
#include <iostream>
#pragma comment(lib, "winmm.lib")
int main(int argc, char* argv[])
{
std::cout<<"Sound playing... enjoy....!!!";
PlaySound("C:\\temp\\sound_test.wav", NULL, SND_FILENAME); //SND_FILENAME or SND_LOOP
return 0;
}

Problem setting desktop wallpaper using SystemParametersInfo Function

I am just learning C++ and am trying to write a small program to change the desktop wallpaper. Using the documentation here, I wrote this program:
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
void main(){
BOOL success = SystemParametersInfo(
SPI_SETDESKWALLPAPER, //iuAction
0, //uiParam
"C:\\test.jpg", //pvParam
SPIF_SENDCHANGE //fWinIni
);
if (success){
printf("Success!\n");
}else
printf("Failure =(\n");
}
The program always fails when I try to specify a file path for pvParam. It will correctly clear the wallpaper if I set pvParam to "". What am I doing wrong?
Thanks
-Abhorsen
It addition to Dennis' comment about JPEG files, it is also important whether or not you compile with UNICODE in effect. If you do then you'll have to specify the file as L"C:\test.jpg". Note the L in front of the string, that makes it a wide string. Or use SystemParametersInfoA(), note the A (but it's archaic).
Depending on the OS version, pvParam might not work.
If you are using Windows XP coupled with a JPEG file you are trying to assign as a wallpaper, notice the comment in the docs:
Windows Server 2003 and Windows
XP/2000: The pvParam parameter cannot
specify a .jpg file.