Skip to content

Commit

Permalink
samples: Add openal
Browse files Browse the repository at this point in the history
  • Loading branch information
JayFoxRox committed Apr 14, 2020
1 parent 8a603b1 commit 59b001a
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 0 deletions.
6 changes: 6 additions & 0 deletions samples/openal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
XBE_TITLE = openal
GEN_XISO = $(XBE_TITLE).iso
SRCS += $(wildcard $(CURDIR)/*.c)
NXDK_DIR = $(CURDIR)/../..
NXDK_SDL = y
include $(NXDK_DIR)/Makefile
116 changes: 116 additions & 0 deletions samples/openal/alhelpers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* OpenAL Helpers
*
* Copyright (c) 2011 by Chris Robinson <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/* This file contains routines to help with some menial OpenAL-related tasks,
* such as opening a device and setting up a context, closing the device and
* destroying its context, converting between frame counts and byte lengths,
* finding an appropriate buffer format, and getting readable strings for
* channel configs and sample types. */

#include <stdio.h>
#include <string.h>

#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"

#include "alhelpers.h"


/* InitAL opens a device and sets up a context using default attributes, making
* the program ready to call OpenAL functions. */
int InitAL(char ***argv, int *argc)
{
const ALCchar *name;
ALCdevice *device;
ALCcontext *ctx;

/* Open and initialize a device */
device = NULL;
if(argc && argv && *argc > 1 && strcmp((*argv)[0], "-device") == 0)
{
device = alcOpenDevice((*argv)[1]);
if(!device)
fprintf(stderr, "Failed to open \"%s\", trying default\n", (*argv)[1]);
(*argv) += 2;
(*argc) -= 2;
}
if(!device)
device = alcOpenDevice(NULL);
if(!device)
{
fprintf(stderr, "Could not open a device!\n");
return 1;
}

ctx = alcCreateContext(device, NULL);
if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
{
if(ctx != NULL)
alcDestroyContext(ctx);
alcCloseDevice(device);
fprintf(stderr, "Could not set a context!\n");
return 1;
}

name = NULL;
if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT"))
name = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
if(!name || alcGetError(device) != AL_NO_ERROR)
name = alcGetString(device, ALC_DEVICE_SPECIFIER);
printf("Opened \"%s\"\n", name);

return 0;
}

/* CloseAL closes the device belonging to the current context, and destroys the
* context. */
void CloseAL(void)
{
ALCdevice *device;
ALCcontext *ctx;

ctx = alcGetCurrentContext();
if(ctx == NULL)
return;

device = alcGetContextsDevice(ctx);

alcMakeContextCurrent(NULL);
alcDestroyContext(ctx);
alcCloseDevice(device);
}


const char *FormatName(ALenum format)
{
switch(format)
{
case AL_FORMAT_MONO8: return "Mono, U8";
case AL_FORMAT_MONO16: return "Mono, S16";
case AL_FORMAT_STEREO8: return "Stereo, U8";
case AL_FORMAT_STEREO16: return "Stereo, S16";
}
return "Unknown Format";
}
25 changes: 25 additions & 0 deletions samples/openal/alhelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef ALHELPERS_H
#define ALHELPERS_H

#include "AL/alc.h"
#include "AL/al.h"
#include "AL/alext.h"

#include "threads.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* Some helper functions to get the name from the format enums. */
const char *FormatName(ALenum type);

/* Easy device init/deinit functions. InitAL returns 0 on success. */
int InitAL(char ***argv, int *argc);
void CloseAL(void);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* ALHELPERS_H */
154 changes: 154 additions & 0 deletions samples/openal/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* OpenAL Source Play Example
*
* Copyright (c) 2017 by Chris Robinson <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/* This file contains an example for playing a sound buffer. */

#include <stdio.h>
#include <assert.h>

#include <SDL.h>

#include "AL/al.h"
#include "AL/alc.h"

#include "alhelpers.h"


/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
* returns the new buffer ID.
*/
static ALuint LoadSound(const char *filename)
{
SDL_AudioSpec wav_spec;
Uint32 wav_length;
Uint8 *wav_buffer;
ALenum err, format;
ALuint buffer;

/* Load the WAV */
if (SDL_LoadWAV("test.wav", &wav_spec, &wav_buffer, &wav_length) == NULL) {
fprintf(stderr, "Could not open audio in %s: %s\n", filename, SDL_GetError());
return 0;
}

/* Get the sound format, and figure out the OpenAL format */
if(wav_spec.channels == 1)
{
if(wav_spec.format == AUDIO_U8)
format = AL_FORMAT_MONO8;
else if(wav_spec.format == AUDIO_S16SYS)
format = AL_FORMAT_MONO16;
else
{
fprintf(stderr, "Unsupported sample format: 0x%04x\n", wav_spec.format);
SDL_FreeWAV(wav_buffer);
return 0;
}
}
else if(wav_spec.channels == 2)
{
if(wav_spec.format == AUDIO_U8)
format = AL_FORMAT_STEREO8;
else if(wav_spec.format == AUDIO_S16SYS)
format = AL_FORMAT_STEREO16;
else
{
fprintf(stderr, "Unsupported sample format: 0x%04x\n", wav_spec.format);
SDL_FreeWAV(wav_buffer);
return 0;
}
}
else
{
fprintf(stderr, "Unsupported channel count: %d\n", wav_spec.channels);
SDL_FreeWAV(wav_buffer);
return 0;
}

/* Buffer the audio data into a new buffer object, then free the data and
* close the file. */
buffer = 0;
alGenBuffers(1, &buffer);
alBufferData(buffer, format, wav_buffer, wav_length, wav_spec.freq);
SDL_FreeWAV(wav_buffer);

/* Check if an error occured, and clean up if so. */
err = alGetError();
if(err != AL_NO_ERROR)
{
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
if(buffer && alIsBuffer(buffer))
alDeleteBuffers(1, &buffer);
return 0;
}

return buffer;
}


int main(int argc, char **argv)
{
ALuint source, buffer;
ALfloat offset;
ALenum state;

/* Initialize OpenAL. */
if(InitAL(&argv, &argc) != 0)
return 1;

/* Load the sound into a buffer. */
buffer = LoadSound("D:\\sound.wav");
if(!buffer)
{
CloseAL();
return 1;
}

/* Create the source to play the sound with. */
source = 0;
alGenSources(1, &source);
alSourcei(source, AL_BUFFER, buffer);
assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");

/* Play the sound until it finishes. */
alSourcePlay(source);
do {
al_nssleep(10000000);
alGetSourcei(source, AL_SOURCE_STATE, &state);

/* Get the source offset. */
alGetSourcef(source, AL_SEC_OFFSET, &offset);
printf("\rOffset: %f ", offset);
fflush(stdout);
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
printf("\n");

/* All done. Delete resources, and close down OpenAL. */
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);

CloseAL();

return 0;
}

0 comments on commit 59b001a

Please sign in to comment.