Giter VIP home page Giter VIP logo

Comments (3)

schellingb avatar schellingb commented on May 30, 2024 1

Hi there!

The 'minisdl_audio.c' that is included in the examples directory is a stripped down SDL2 in a single file which only includes Windows, Mac, Linux platform support.
To run on android you will need to either build with the full SDL2 library or do something with native Android. Here's an example that uses OpenSLES I just made up in 15 minutes which did build and worked on my Android device here:

#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>

#define TSF_IMPLEMENTATION
#include "../tsf.h"

//This is a minimal SoundFont with a single loopin saw-wave sample/instrument/preset (484 bytes)
const static unsigned char MinimalSoundFont[] =
{
	#define TEN0 0,0,0,0,0,0,0,0,0,0
	'R','I','F','F',220,1,0,0,'s','f','b','k',
	'L','I','S','T',88,1,0,0,'p','d','t','a',
	'p','h','d','r',76,TEN0,TEN0,TEN0,TEN0,0,0,0,0,TEN0,0,0,0,0,0,0,0,255,0,255,0,1,TEN0,0,0,0,
	'p','b','a','g',8,0,0,0,0,0,0,0,1,0,0,0,'p','m','o','d',10,TEN0,0,0,0,'p','g','e','n',8,0,0,0,41,0,0,0,0,0,0,0,
	'i','n','s','t',44,TEN0,TEN0,0,0,0,0,0,0,0,0,TEN0,0,0,0,0,0,0,0,1,0,
	'i','b','a','g',8,0,0,0,0,0,0,0,2,0,0,0,'i','m','o','d',10,TEN0,0,0,0,
	'i','g','e','n',12,0,0,0,54,0,1,0,53,0,0,0,0,0,0,0,
	's','h','d','r',92,TEN0,TEN0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,49,0,0,0,34,86,0,0,60,0,0,0,1,TEN0,TEN0,TEN0,TEN0,0,0,0,0,0,0,0,
	'L','I','S','T',112,0,0,0,'s','d','t','a','s','m','p','l',100,0,0,0,86,0,119,3,31,7,147,10,43,14,169,17,58,21,189,24,73,28,204,31,73,35,249,38,46,42,71,46,250,48,150,53,242,55,126,60,151,63,108,66,126,72,207,
		70,86,83,100,72,74,100,163,39,241,163,59,175,59,179,9,179,134,187,6,186,2,194,5,194,15,200,6,202,96,206,159,209,35,213,213,216,45,220,221,223,76,227,221,230,91,234,242,237,105,241,8,245,118,248,32,252
};

// Holds the global instance pointer
static tsf* g_TinySoundFont;

// Global SLES buffers
static char* g_SLESBuffer[2];
static int g_SLESBufferSize, g_SLESBufferNum;

static void SLESPlayerCallback(SLAndroidSimpleBufferQueueItf SLESBufferQueue, void*)
{
	g_SLESBufferNum ^= 1;
	
	int SampleCount = (g_SLESBufferSize / (2 * sizeof(short))); //2 output channels
	tsf_render_short(g_TinySoundFont, (short*)g_SLESBuffer[g_SLESBufferNum], SampleCount, 0);

	(*SLESBufferQueue)->Enqueue(SLESBufferQueue, g_SLESBuffer[g_SLESBufferNum], g_SLESBufferSize);
}

int main(int argc, char *argv[])
{
	// Load the SoundFont from the memory block
	g_TinySoundFont = tsf_load_memory(MinimalSoundFont, sizeof(MinimalSoundFont));
	if (!g_TinySoundFont)
	{
		fprintf(stderr, "Could not load soundfont\n");
		return;
	}

	// Set the rendering output mode to 44.1khz and -10 decibel gain
	tsf_set_output(g_TinySoundFont, TSF_STEREO_INTERLEAVED, 44100, -10);

	// Start two notes before starting the audio playback
	tsf_note_on(g_TinySoundFont, 0, 48, 1.0f); //C2
	tsf_note_on(g_TinySoundFont, 0, 52, 1.0f); //E2

	//Initialize OpenSLES
	SLObjectItf SLESEngine = NULL, SLESOutMix = NULL, SLESPlayer = NULL;
	SLEngineItf engineEngine = NULL;
	SLPlayItf playerPlay = NULL;
	SLAndroidSimpleBufferQueueItf bufferQueue = NULL;
	SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
	SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM, 2, SL_SAMPLINGRATE_44_1, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN };
	SLDataSource audioSrc = { &loc_bufq, &format_pcm };
	SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, NULL };
	SLDataSink audioSnk = { &loc_outmix, NULL };
	const SLInterfaceID ids[1] = { SL_IID_BUFFERQUEUE };
	const SLboolean req[1] = { SL_BOOLEAN_TRUE };
	g_SLESBufferSize = 4400; //25ms (4400 bytes)
	g_SLESBuffer[0] = (char*)malloc(g_SLESBufferSize * 2);
	g_SLESBuffer[1] = g_SLESBuffer[0] + g_SLESBufferSize;
	memset(g_SLESBuffer[0], 0, g_SLESBufferSize * 2);
	g_SLESBufferNum = 0;
	bool bSLESSuccess = ((SL_RESULT_SUCCESS == slCreateEngine(&SLESEngine, 0, NULL, 0, NULL, NULL))
	     && (SL_RESULT_SUCCESS == (*SLESEngine)->Realize(SLESEngine, SL_BOOLEAN_FALSE))
	     && (SL_RESULT_SUCCESS == (*SLESEngine)->GetInterface(SLESEngine, SL_IID_ENGINE, &engineEngine))
	     && (SL_RESULT_SUCCESS == (*engineEngine)->CreateOutputMix(engineEngine, &SLESOutMix, 0, 0, 0))
	     && (SL_RESULT_SUCCESS == (*SLESOutMix)->Realize(SLESOutMix, SL_BOOLEAN_FALSE))
	     && (NULL != (loc_outmix.outputMix = SLESOutMix))
	     && (SL_RESULT_SUCCESS == (*engineEngine)->CreateAudioPlayer(engineEngine, &SLESPlayer, &audioSrc, &audioSnk, 1, ids, req))
	     && (SL_RESULT_SUCCESS == (*SLESPlayer)->Realize(SLESPlayer, SL_BOOLEAN_FALSE))
	     && (SL_RESULT_SUCCESS == (*SLESPlayer)->GetInterface(SLESPlayer, SL_IID_PLAY, &playerPlay))
	     && (SL_RESULT_SUCCESS == (*SLESPlayer)->GetInterface(SLESPlayer, SL_IID_BUFFERQUEUE, &bufferQueue))
	     && (SL_RESULT_SUCCESS == (*bufferQueue)->RegisterCallback(bufferQueue, SLESPlayerCallback, NULL))
	     && (SL_RESULT_SUCCESS == (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING))
	     && (SL_RESULT_SUCCESS == (*bufferQueue)->Enqueue(bufferQueue, g_SLESBuffer[0], g_SLESBufferSize))
	     && (SL_RESULT_SUCCESS == (*bufferQueue)->Enqueue(bufferQueue, g_SLESBuffer[1], g_SLESBufferSize)));
	if (!bSLESSuccess)
	{
		fprintf(stderr, "SLES init failed\n");
	}
	else
	{
		//Let the audio play for 3 seconds
		timespec sleep3seconds { 3, 0 };
		nanosleep(&sleep3seconds, NULL);
	}

	//Shutdown OpenSLES
	free(g_SLESBuffer[0]);
	if (SLESPlayer) (*SLESPlayer)->Destroy(SLESPlayer);
	if (SLESOutMix) (*SLESOutMix)->Destroy(SLESOutMix);
	if (SLESEngine) (*SLESEngine)->Destroy(SLESEngine);
}

I'm not sure if the function main can run just like that on Android and/or with your build system. For the test I did I kept the test in a JNI library which had some jump-in point from the Java app world.

Good luck :-)
\ Bernhard

from tinysoundfont.

KnIfER avatar KnIfER commented on May 30, 2024

It works on c4droid! I have to add "return 0" in "main".thank you schellingb!

from tinysoundfont.

schellingb avatar schellingb commented on May 30, 2024

Oh, sure, yeah, sorry for forgetting the return.
Awesome that you could get it to work just like that :-)

from tinysoundfont.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.