Sound performance in Haiku. Which library to use?

Hi,

The question is in the title. Wich library give better sound “quality” and performance in Haiku?

I heard about OpenAL, SLD_Mixer (I don’t think is it)? Or investigate the native API for it?

Native mixer kit is under construction, and provides good performance, not ready for real time audio atm

2 Likes

BSoundPlayer

https://www.haiku-os.org/legacy-docs/bebook/BSoundPlayer.html

Example:
https://www.haiku-os.org/legacy-docs/benewsletter/Issue3-45.html

The package “BeOS sample code” has excellent simple BSoundPlayer examples.

A more complicated example is in Medo (https://github.com/smallstepforman/Medo)
Have a peek at AudioCache.cpp, AudioManager.cpp and AudioManager_Output.cpp, but it’s probably a lot heavier code since it caches many tracks for performance reasons (seeking/scrubbing)

6 Likes

Everything else (including BSoundPlayer) is built on top of the native Media Kit API. If you want very file control on everything (set your own latency, etc), using the Media Kit API will remove as much overhead as possible. But it is not easy to use.

BSoundPlayer is a simpler API built on top of it and will be reasonable for most use cases.

Most 3rd party libraries (to my knowledge) are ported using BSoundPlayer and add yet another layer of code. But some of them do provide useful additional services (spatialization of sounds in a 3D space and not just a simple left/right balance, for example, but there can be many other things).

9 Likes

Barret iirc, was looking at implementing jack alongside or below the native api. Whatever became of that

Hi,

I search an example about BSoundPlayer but I don’t find it.

I search it here:
https://github.com/HaikuArchives/BeSampleCode

Thanks for reply.

You can review OpenAL and the native Haiku audio backend implementation used for it.

Read these files for examples:

1 Like

Haiku’s Soundrecorder app uses BSoundPlayer.

In the BeSampleCode, a search shows BSoundPlayer in

  • Intro / xmas
  • MediaKit / MediaFile / mplay

I also found it in Bong, Becasso, Medo, Resourcer, Clue, StreamRadio, and Toner. All I think at HaikuArchives.

2 Likes

Also, look at the VLC and MPlayer audio patches provided in HaikuPorts.

2 Likes

I have find this, but when I compile it I have no sound playback (silent)

//Playing 3D sound with OpenAL, and loading a wav file manually
#include <iostream>
#include <fstream>
#include <cstring>
#include <AL/al.h>
#include <AL/alc.h>

bool isBigEndian()
{
    int a = 1;
    return !((char*)&a)[0];
}

int convertToInt(char* buffer, int len)
{
    int a = 0;
    if (!isBigEndian())
        for (int i = 0; i<len; i++)
            ((char*)&a)[i] = buffer[i];
    else
        for (int i = 0; i<len; i++)
            ((char*)&a)[3 - i] = buffer[i];
    return a;
}

char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size)
{
    char buffer[4];
    std::ifstream in(fn, std::ios::binary);
    in.read(buffer, 4);
    if (strncmp(buffer, "RIFF", 4) != 0)
    {
        std::cout << "this is not a valid WAVE file" << std::endl;
        return NULL;
    }
    in.read(buffer, 4);
    in.read(buffer, 4);      //WAVE
    in.read(buffer, 4);      //fmt
    in.read(buffer, 4);      //16
    in.read(buffer, 2);      //1
    in.read(buffer, 2);
    chan = convertToInt(buffer, 2);
    in.read(buffer, 4);
    samplerate = convertToInt(buffer, 4);
    in.read(buffer, 4);
    in.read(buffer, 2);
    in.read(buffer, 2);
    bps = convertToInt(buffer, 2);
    in.read(buffer, 4);      //data
    in.read(buffer, 4);
    size = convertToInt(buffer, 4);
    char* data = new char[size];
    in.read(data, size);
    return data;
}

int main(int argc, char** argv)
{
    int channel, sampleRate, bps, size;
    char* data = loadWAV("test.wav", channel, sampleRate, bps, size);
    ALCdevice* device = alcOpenDevice(NULL);
    if (device == NULL)
    {
        std::cout << "cannot open sound card" << std::endl;
        return 0;
    }
    ALCcontext* context = alcCreateContext(device, NULL);
    if (context == NULL)
    {
        std::cout << "cannot open context" << std::endl;
        return 0;
    }
    alcMakeContextCurrent(context);

    unsigned int bufferid, format;
    alGenBuffers(1, &bufferid);
    if (channel == 1)
    {
        if (bps == 8)
        {
            format = AL_FORMAT_MONO8;
        }
        else {
            format = AL_FORMAT_MONO16;
        }
    }
    else {
        if (bps == 8)
        {
            format = AL_FORMAT_STEREO8;
        }
        else {
            format = AL_FORMAT_STEREO16;
        }
    }
    alBufferData(bufferid, format, data, size, sampleRate);
    unsigned int sourceid;
    alGenSources(1, &sourceid);
    alSourcei(sourceid, AL_BUFFER, bufferid);
    alSourcePlay(sourceid);

    while (true)
    {

    }

    alDeleteSources(1, &sourceid);
    alDeleteBuffers(1, &bufferid);

    alcDestroyContext(context);
    alcCloseDevice(device);
    delete[] data;
    return 0;
}

The wav file is test.wav
for compiling:
g++ main.cpp -o main -lopenal

I also tried an other source for OpenAl and SDL but same trouble about silent.

Can you solve it?

Also I have this trouble while compiling Mplay:

In file included from /boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.cpp:10:
/boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.h:23: syntax error before `*'
/boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.cpp: In method `DrawApp::DrawApp()':
/boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.cpp:23: `fOpenPanel' undeclared (first use this function)
/boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.cpp:23: (Each undeclared identifier is reported only once
/boot/home/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay/draw.cpp:23: for each function it appears in.)
~/Desktop/BeSampleCode/BeSampleCode-haiku/media_kit/MediaFile/mplay> 

draw.h

#ifndef DRAW_H
#define DRAW_H

#include <Application.h>


const uint32 msg_WindowClosed = 'Mwcl';


class DrawApp : public BApplication {
public:
					DrawApp();
	virtual			~DrawApp();

	void			OpenOpenPanel();

	virtual void	ReadyToRun();
	virtual void	ArgvReceived(int32 argc, char **argv);
	virtual void	MessageReceived(BMessage *message);
	virtual	void	RefsReceived(BMessage *message);

private:
	BFilePanel*	fOpenPanel;

	static int32	sNumWindows;
};


#endif //DRAW_H

That generate an error in BFilePanel * line
Thanks.

I am not sure if OpenAL has any audio output support on Haiku yet?

As said earlier in this thread, it is probably best to start by directly using BGameSound or BFileGameSound. If you still have problem then, it means it is a problem in Haiku and we can investigate here. Personally I have no idea about OpenAL and only limited knowledge of sound APIs in SDL. I cannot help with these libraries.

1 Like

OpenAL pipes directly to mixer (verified that it works under Haiku, with spatial sound), however the bit that doesn’t work is output to a user buffer. I would have used that functionality with Medo if it worked.

2 Likes

Hi,

I try to compile some of the HaikuArchives apps but I can’t compiling it.
Have trouble when compiling streamRadio and mplay as example.

If you have a portable lib on Haiku that make decend performances for sound that interesting me.
I search something that can play mp3 in a GUI or with SDL/OpenGL. I have tested mpg123 devel but that seem limited to command line.

Also I try to run some SDL2 project that use SDL2Mixer but I don’t have audio output. Is it a know bug?

Then work with sound with Haiku seem difficult.

Mainly, use the low-level native BeOS/Haiku ‘-lmedia’ library and Media Kit headers.
Haiku’s audio mixer component is still a work-in-progress (i.e. may crash media add-on server).

Haiku’s OpenAL and SDL2 ports use the Media Kit.

1 Like

I get this name about the driver SDL2 used “haikudiskdummy” when I place SDL_GetAudioDriver(0)
This give silent sound…Is there a special command for making sound work with SDL2?

This was:
haiku
disk
dummy

Impossible to get some sound with SDL 1 and 2. Don’t know why, I have tested multiple sources codes.

What is the problem with using system audio mixer?

See: https://github.com/haikuports/haikuports/search?q=mixer&type=issues

Some reworking went unfinished:

  1. Linear interpolation
  2. Mixer input functionaility
  3. buffer management (overflow/error handling)
  4. Media destination data status validation
  5. looping bug (midi)

I solved my trouble about sound in SDL2:

here is the code *that work

#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>

/* prototypes */
int MusicPlay(void);

		SDL_Event event;
int main(int argc, char *argv[])
{
	MusicPlay();
	return 0;
}



int MusicPlay(void)
{

	int continuer = 1;

	/* Initialisation de SDL2 */
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
/* *************************************************************** */

	/* Initialisations de fenetre + image RickRoll */
	SDL_Window *window = NULL;
	window = SDL_CreateWindow("Never Gonna Give You Up !", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 850, 678, SDL_WINDOW_SHOWN);

	SDL_Renderer *renderer = NULL;
	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

	SDL_Surface *img = NULL;
	img = SDL_LoadBMP("/boot/home/Desktop/background.bmp");

	SDL_Texture *textureIMG = NULL;
	textureIMG = SDL_CreateTextureFromSurface(renderer,img);

	SDL_FreeSurface(img);


	if (img == NULL)
	{
		fprintf(stderr, "Erreur SDL_LoadBMP: '%s'\n",SDL_GetError());
		continuer = 0;
	}

	if (textureIMG == NULL)
	{
		fprintf(stderr, "Erreur SDL_CreateTextureFromSurface: '%s'\n", SDL_GetError());
		continuer = 0;
	}

/* *************************************************************** */
	/* Charger la musique du RickRoll (refraint) */
	if (Mix_OpenAudio(44100, AUDIO_S16, 2, 2048) < 0)
	{
		fprintf(stderr, "Erreur Mix_OpenAudio: '%s'\n", SDL_GetError());
		continuer = 0;
	}
	Mix_Music *bgm = Mix_LoadMUS("movin.mp3");
	if (bgm != NULL)
		printf("Loaded the file\n");
	else
		printf("Mix_LoadMUS: %s\n", Mix_GetError());


	if(Mix_PlayMusic(bgm, -1)==-1)
		printf("Mix_PlayMusic: %s\n",Mix_GetError());



/* *************************************************************** */


	/* boucle programme */
	    SDL_RenderClear(renderer);
		SDL_RenderCopy(renderer, textureIMG, NULL, NULL);
		SDL_RenderPresent(renderer);
	while(continuer)
	{
		SDL_WaitEvent(&event);
		switch(event.type)
		{
			case SDL_QUIT:
            continuer = 0;
            break;
		}
   }
	

/* *************************************************************** */

	/* On détruit le renderer, la fenêtre, quitte SDL2, et libère de la RAM */
	SDL_DestroyTexture(textureIMG);
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	Mix_FreeMusic(bgm);

	Mix_Quit();
	SDL_Quit();
	return EXIT_SUCCESS;
}

That load movin.mp3 and background.bmp to launch from a Terminal.

Yet an other code in SDL1 here that load a wav file “sample2.wav” placed on Desktop.

#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
   int continuer = 1;
   SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
   SDL_Surface *ecran = NULL;
   ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
   SDL_Event event;
   SDL_WM_SetCaption("SDL_Mixer", NULL);
   SDL_Flip(ecran);
   if(Mix_OpenAudio(44100, AUDIO_S16, 2, 1024) == -1) //Initialisation de l'API Mixer
   {
      printf("%s", Mix_GetError());
   }
   Mix_Chunk *musique = Mix_LoadWAV("/boot/home/Desktop/sample2.wav"); //Chargement de la musique
	if(musique !=NULL)
		printf("Loaded the music file\n");
	else
		printf("Mix_LoadMUS: %s\n",Mix_GetError());

	if(Mix_PlayChannel(-1,musique, 0 )==-1)
		printf("Mix_PlayMusic: %s\n",Mix_GetError());
   while(continuer)
	{
      SDL_WaitEvent(&event);
      switch(event.type)
      {
         case SDL_QUIT:
            continuer = 0;
            break;
      }
   }
   Mix_FreeChunk(musique); //Libération de la musique
   Mix_CloseAudio(); //Fermeture de l'API
   SDL_Quit();
   return EXIT_SUCCESS;
}

That work but I have some lags in sound output.

2 Likes

Ok. Using just native Haiku Media (and/or Game) kit (i.e. versus SDL2, OpenAL, etc) - can we use less code with adequate audio and mixer performance…

1 Like

I don’t really understand mediakit from sources I have see before. Not so easy than SDL it seem. I have try to compile some projects as mentioned before but these fail to compile. I searching for a minimal source file for understand the mediakit music loading and playing but no so easy to find it too.

But yes use native implementation can speed up performances.

1 Like