How to play sound from C?

How to play sound from C?

Postby PeterX » 05 Nov 2021, 21:46

Hi, fellow developers!

How do I play a sound(file) from a C console program on Linux?

I have a simple textonly program that should play a sound file. (No synchronizing, no music, no reacting to game status.)

I found this, but it is overly complicated and long:
https://stackoverflow.com/questions/265 ... c-on-linux

EDIT: Ok, I could use
{l Code}: {l Select All Code}
system("paplay sound.wav");
But that seems unelegant to me.
And if I use SDL, I can't use printf() anymore?

Greetings
Peter
User avatar
PeterX
 
Posts: 158
Joined: 01 Oct 2020, 21:44

Re: How to play sound from C?

Postby dulsi » 06 Nov 2021, 01:25

libao, mentioned in your link, looks pretty easy. It is available on Fedora.
dulsi
 
Posts: 521
Joined: 18 Feb 2016, 15:24

Re: How to play sound from C?

Postby PeterX » 06 Nov 2021, 05:10

Sorry, I didn't see that. And thanks, at first glance that seems to be exactly what I was looking for. And additionally it is quite portable!

Greetings
Peter
User avatar
PeterX
 
Posts: 158
Joined: 01 Oct 2020, 21:44

Re: How to play sound from C?

Postby bzt » 06 Nov 2021, 14:00

PeterX {l Wrote}:How do I play a sound(file) from a C console program on Linux?
Back in the old days when people were stupid and dumb so couldn't understand how magnificent pulseaudio is, there was a /dev/dsp device file. You could just write the raw data into that file. Like this:
{l Code}: {l Select All Code}
cat sound.wav > /dev/dsp
If your distro ships a kernel that provides the dsp device file, you can still do this.

Sadly these days /dev/dsp is missing, and you must use a library which hides OSS / ALSA / whatever kernel interface details, libao is good. I'd also point out that SDL can handle audio natively just fine with the low-level SDL_OpenAudioDevice interface. The reason why people don't use this directly is because it can only play one audio stream (which is exactly what you want).

For playing multiple sounds at once, one have to mix those streams into a single stream first. Basically that's all what SDL_mixer does, but that library's source is relatively complicated and complex. Here's a simple mixer library that does that too, but it is useful to learn how to use SDL's low-level audio interface (NOTE: since this is the simplest possible mixer with the simplest code base, its features are very limited, but, single C file, easy to learn from it, and you'll only need one sound anyway).

PeterX {l Wrote}:I have a simple textonly program that should play a sound file. (No synchronizing, no music, no reacting to game status.)
That would be as simple as
{l Code}: {l Select All Code}
playSound("sound.wav", SDL_MIX_MAXVOLUME);
Without a mixer library, using only SDL's low-level interface, see this gist. It plays an ogg file (with stb_vorbis), but you could fill up the audiodata[] buffer using the native SDL_LoadWav() function too if you only need .wav sounds.

PeterX {l Wrote}:And if I use SDL, I can't use printf() anymore?
Nope, you can. Here's an example console app that plays some music and sounds from command line, it has no issues with printf at all. Try it out, add some printf in that code. The gist link above also contains some printf calls.

Cheers,
bzt
User avatar
bzt
 
Posts: 129
Joined: 23 May 2021, 21:46

Re: How to play sound from C?

Postby smcameron » 06 Nov 2021, 18:53

Portaudio is not too bad. http://www.portaudio.com/ though you do have to write your own mixer code.

I use it in Space Nerds in Space with a little library I built on top of it to make things easier + for some special crap I needed for voice chat.

header file: https://github.com/smcameron/space-nerd ... wviaudio.h
implementation: https://github.com/smcameron/space-nerd ... wviaudio.c
smcameron
 
Posts: 375
Joined: 29 Oct 2010, 23:44

Re: How to play sound from C?

Postby bzt » 07 Nov 2021, 14:08

So to summarize, you have to use some kind of library, but as a silver lining, that opens up the way for portability.
Here are some useful links for audio programming (I've tried to link tutorials with example code for each library. Some examples are C++, but the library works with C no probs):
  • PortAudio, no mixer, portable, relatively simple (additional ogg mixer example)
  • SDL, no mixer, portable, simple to use (additional mixer libraries SDL_mixer, Simple-SDL2-Audio)
  • libao, has a mixer, portable, simple to use (probably the most portable of these)
  • libasound2, has a mixer, semi-portable (built on ALSA, so: Linux, Android, some BSDs, but no Win), quite complex API
  • libpulse, has a mixer, portable, very complex API and complex running environment (but provides a simplified API too)
  • OpenAL, has a mixer, portable, very complex API, proprietary (but there's an Open Source software-only implementation too)
Cheers,
bzt
User avatar
bzt
 
Posts: 129
Joined: 23 May 2021, 21:46

Re: How to play sound from C?

Postby drummyfish » 09 Nov 2021, 18:41

Hey, I just quickly smashed together this code that plays any array of bytes, it isn't using any library, just the aplay utility:

{l Code}: {l Select All Code}
#include <stdio.h>
#include <stdlib.h>
 
#define SAMPLES 1024
#define N (SAMPLES * 4 + 18)
 
char command[N] = "echo -e \'\' | aplay";

char valToHex(int v)
{
  return (v < 10 ? '0' : ('a' - 10)) + v;
}

int main(void)
{
  for (int i = 0; i < 10; ++i)
    command[N - i] = command[18 - i];

  char *p = command + 9;

  for (int i = 0; i < SAMPLES; ++i)
  {
    unsigned char val = i;

    *p = '\\';
    p++;
    *p = 'x';
    p++;
    *p = valToHex(val / 16);
    p++;
    *p = valToHex(val % 16);
    p++;
  }

  puts(command);
  system(command);

  return 0;
}
socialist anarcho-pacifist
Abolish all IP laws. Use CC0. Let's write less retarded software.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 416
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: How to play sound from C?

Postby bzt » 09 Nov 2021, 22:06

drummyfish {l Wrote}:Hey, I just quickly smashed together this code that plays any array of bytes, it isn't using any library, just the aplay utility:
This technically isn't "playing sound from C", rather just executing a 3rd party tool (which might not be installed). That, and you have missed this sentence in the OP:
PeterX {l Wrote}:Ok, I could use [...] system [...] But that seems unelegant to me.
So solutions which use "system()" aren't the ones he's after.

Cheers,
bzt
User avatar
bzt
 
Posts: 129
Joined: 23 May 2021, 21:46

Re: How to play sound from C?

Postby drummyfish » 10 Nov 2021, 15:51

C can't play sounds, you always have to use 3rd party tools, libraries are completely the same in this -- a library or it's dependency may also be missing from the user's system.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0. Let's write less retarded software.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 416
Joined: 29 Jul 2018, 20:30
Location: Moravia

Re: How to play sound from C?

Postby PeterX » 10 Nov 2021, 16:21

drummyfish {l Wrote}:C can't play sounds, you always have to use 3rd party tools, libraries are completely the same in this -- a library or it's dependency may also be missing from the user's system.

You are right, but I think it's okay to use libraries, I just want to be careful to not pull in dozens of obscure and bloated libraries. And it's still C, just with a library.

Thanks to everybody for the suggestions. I think, I'll use libao. It's portable and it seems to be easy to use.

Greetings
Peter
User avatar
PeterX
 
Posts: 158
Joined: 01 Oct 2020, 21:44

Re: How to play sound from C?

Postby drummyfish » 10 Nov 2021, 18:26

Yeah, the /dev/esp would be the best, most beautiful way, the Unix way, but sometimes we just need to adapt to current systems I guess.
socialist anarcho-pacifist
Abolish all IP laws. Use CC0. Let's write less retarded software.
http://www.tastyfish.cz
User avatar
drummyfish
 
Posts: 416
Joined: 29 Jul 2018, 20:30
Location: Moravia

Who is online

Users browsing this forum: No registered users and 1 guest