add SDL_mixer
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
PLAYMUS: A test application for the SDL mixer library.
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* Quiet windows compiler warnings */
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef unix
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3_mixer/SDL_mixer.h>
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
|
||||
static int audio_open = 0;
|
||||
static Mix_Music *music = NULL;
|
||||
static int next_track = 0;
|
||||
|
||||
static void CleanUp(int exitcode)
|
||||
{
|
||||
if(Mix_PlayingMusic()) {
|
||||
Mix_FadeOutMusic(1500);
|
||||
SDL_Delay(1500);
|
||||
}
|
||||
if (music) {
|
||||
Mix_FreeMusic(music);
|
||||
music = NULL;
|
||||
}
|
||||
if (audio_open) {
|
||||
Mix_CloseAudio();
|
||||
audio_open = 0;
|
||||
}
|
||||
SDL_Quit();
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
static void Usage(char *argv0)
|
||||
{
|
||||
SDL_Log("Usage: %s [-i] [-l] [-8] [-f32] [-r rate] [-c channels] [-b buffers] [-v N] [-io] <musicfile>\n", argv0);
|
||||
}
|
||||
|
||||
/*#define SEEK_TEST */
|
||||
static void Menu(void)
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
printf("Available commands: (p)ause (r)esume (h)alt volume(v#) > ");
|
||||
if (fgets(buf, sizeof(buf), stdin)) {
|
||||
switch(buf[0]) {
|
||||
#if defined(SEEK_TEST)
|
||||
case '0': Mix_SetMusicPosition(0); break;
|
||||
case '1': Mix_SetMusicPosition(10);break;
|
||||
case '2': Mix_SetMusicPosition(20);break;
|
||||
case '3': Mix_SetMusicPosition(30);break;
|
||||
case '4': Mix_SetMusicPosition(40);break;
|
||||
#endif /* SEEK_TEST */
|
||||
case 'p': case 'P':
|
||||
Mix_PauseMusic();
|
||||
break;
|
||||
case 'r': case 'R':
|
||||
Mix_ResumeMusic();
|
||||
break;
|
||||
case 'h': case 'H':
|
||||
Mix_HaltMusic();
|
||||
break;
|
||||
case 'v': case 'V':
|
||||
Mix_VolumeMusic(SDL_atoi(buf+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Music playing: %s Paused: %s\n", Mix_PlayingMusic() ? "yes" : "no",
|
||||
Mix_PausedMusic() ? "yes" : "no");
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
static void IntHandler(int sig)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGINT:
|
||||
next_track++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int audio_volume = MIX_MAX_VOLUME;
|
||||
int looping = 0;
|
||||
bool interactive = false;
|
||||
bool use_io = false;
|
||||
int i;
|
||||
const char *typ;
|
||||
const char *tag_title = NULL;
|
||||
const char *tag_artist = NULL;
|
||||
const char *tag_album = NULL;
|
||||
const char *tag_copyright = NULL;
|
||||
double loop_start, loop_end, loop_length, current_position;
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
(void) argc;
|
||||
|
||||
/* Initialize variables */
|
||||
spec.freq = MIX_DEFAULT_FREQUENCY;
|
||||
spec.format = MIX_DEFAULT_FORMAT;
|
||||
spec.channels = MIX_DEFAULT_CHANNELS;
|
||||
|
||||
/* Check command line usage */
|
||||
for (i = 1; argv[i] && (*argv[i] == '-'); ++i) {
|
||||
if ((SDL_strcmp(argv[i], "-r") == 0) && argv[i+1]) {
|
||||
++i;
|
||||
spec.freq = SDL_atoi(argv[i]);
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-m") == 0) {
|
||||
spec.channels = 1;
|
||||
} else
|
||||
if ((SDL_strcmp(argv[i], "-c") == 0) && argv[i+1]) {
|
||||
++i;
|
||||
spec.channels = SDL_atoi(argv[i]);
|
||||
} else
|
||||
if ((SDL_strcmp(argv[i], "-b") == 0) && argv[i+1]) {
|
||||
++i;
|
||||
/*ignored now. audio_buffers = SDL_atoi(argv[i]); */
|
||||
} else
|
||||
if ((SDL_strcmp(argv[i], "-v") == 0) && argv[i+1]) {
|
||||
++i;
|
||||
audio_volume = SDL_atoi(argv[i]);
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-l") == 0) {
|
||||
looping = -1;
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-i") == 0) {
|
||||
interactive = true;
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-8") == 0) {
|
||||
spec.format = SDL_AUDIO_U8;
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-f32") == 0) {
|
||||
spec.format = SDL_AUDIO_F32;
|
||||
} else
|
||||
if (SDL_strcmp(argv[i], "-io") == 0) {
|
||||
use_io = 1;
|
||||
} else {
|
||||
Usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!argv[i]) {
|
||||
Usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize the SDL library */
|
||||
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s\n",SDL_GetError());
|
||||
return 255;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
signal(SIGINT, IntHandler);
|
||||
signal(SIGTERM, CleanUp);
|
||||
#endif
|
||||
|
||||
/* Open the audio device */
|
||||
if (!Mix_OpenAudio(0, &spec)) {
|
||||
SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
|
||||
return 2;
|
||||
} else {
|
||||
Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels);
|
||||
SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq,
|
||||
(spec.format&0xFF),
|
||||
(SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""),
|
||||
(spec.channels > 2) ? "surround" : (spec.channels > 1) ? "stereo" : "mono");
|
||||
}
|
||||
audio_open = 1;
|
||||
|
||||
/* Set the music volume */
|
||||
Mix_VolumeMusic(audio_volume);
|
||||
|
||||
while (argv[i]) {
|
||||
next_track = 0;
|
||||
|
||||
/* Load the requested music file */
|
||||
if (use_io) {
|
||||
music = Mix_LoadMUS_IO(SDL_IOFromFile(argv[i], "rb"), true);
|
||||
} else {
|
||||
music = Mix_LoadMUS(argv[i]);
|
||||
}
|
||||
if (music == NULL) {
|
||||
SDL_Log("Couldn't load %s: %s\n", argv[i], SDL_GetError());
|
||||
CleanUp(2);
|
||||
}
|
||||
|
||||
switch (Mix_GetMusicType(music)) {
|
||||
case MUS_WAV:
|
||||
typ = "WAV";
|
||||
break;
|
||||
case MUS_MOD:
|
||||
typ = "MOD";
|
||||
break;
|
||||
case MUS_FLAC:
|
||||
typ = "FLAC";
|
||||
break;
|
||||
case MUS_MID:
|
||||
typ = "MIDI";
|
||||
break;
|
||||
case MUS_OGG:
|
||||
typ = "OGG Vorbis";
|
||||
break;
|
||||
case MUS_MP3:
|
||||
typ = "MP3";
|
||||
break;
|
||||
case MUS_OPUS:
|
||||
typ = "OPUS";
|
||||
break;
|
||||
case MUS_WAVPACK:
|
||||
typ = "WavPack";
|
||||
break;
|
||||
case MUS_NONE:
|
||||
default:
|
||||
typ = "NONE";
|
||||
break;
|
||||
}
|
||||
SDL_Log("Detected music type: %s", typ);
|
||||
|
||||
tag_title = Mix_GetMusicTitleTag(music);
|
||||
if (tag_title && SDL_strlen(tag_title) > 0) {
|
||||
SDL_Log("Title: %s", tag_title);
|
||||
}
|
||||
|
||||
tag_artist = Mix_GetMusicArtistTag(music);
|
||||
if (tag_artist && SDL_strlen(tag_artist) > 0) {
|
||||
SDL_Log("Artist: %s", tag_artist);
|
||||
}
|
||||
|
||||
tag_album = Mix_GetMusicAlbumTag(music);
|
||||
if (tag_album && SDL_strlen(tag_album) > 0) {
|
||||
SDL_Log("Album: %s", tag_album);
|
||||
}
|
||||
|
||||
tag_copyright = Mix_GetMusicCopyrightTag(music);
|
||||
if (tag_copyright && SDL_strlen(tag_copyright) > 0) {
|
||||
SDL_Log("Copyright: %s", tag_copyright);
|
||||
}
|
||||
|
||||
loop_start = Mix_GetMusicLoopStartTime(music);
|
||||
loop_end = Mix_GetMusicLoopEndTime(music);
|
||||
loop_length = Mix_GetMusicLoopLengthTime(music);
|
||||
|
||||
/* Play and then exit */
|
||||
SDL_Log("Playing %s, duration %f\n", argv[i], Mix_MusicDuration(music));
|
||||
if (loop_start > 0.0 && loop_end > 0.0 && loop_length > 0.0) {
|
||||
SDL_Log("Loop points: start %g s, end %g s, length %g s\n", loop_start, loop_end, loop_length);
|
||||
}
|
||||
Mix_FadeInMusic(music,looping,2000);
|
||||
while (!next_track && (Mix_PlayingMusic() || Mix_PausedMusic())) {
|
||||
if (interactive) {
|
||||
Menu();
|
||||
} else {
|
||||
current_position = Mix_GetMusicPosition(music);
|
||||
if (current_position >= 0.0) {
|
||||
printf("Position: %g seconds \r", current_position);
|
||||
fflush(stdout);
|
||||
}
|
||||
SDL_Delay(100);
|
||||
}
|
||||
}
|
||||
Mix_FreeMusic(music);
|
||||
music = NULL;
|
||||
|
||||
/* If the user presses Ctrl-C more than once, exit. */
|
||||
SDL_Delay(500);
|
||||
if (next_track > 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
CleanUp(0);
|
||||
|
||||
/* Not reached, but fixes compiler warnings */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
PLAYWAVE: A test application for the SDL mixer library.
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3_mixer/SDL_mixer.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef unix
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
static int audio_open = 0;
|
||||
static Mix_Chunk *g_wave = NULL;
|
||||
static bool verbose = false;
|
||||
static bool test_position = false;
|
||||
static bool test_distance = false;
|
||||
static bool test_panning = false;
|
||||
|
||||
static void report_decoders(void)
|
||||
{
|
||||
int i, total;
|
||||
|
||||
SDL_Log("Supported decoders...\n");
|
||||
total = Mix_GetNumChunkDecoders();
|
||||
for (i = 0; i < total; i++) {
|
||||
SDL_Log(" - chunk decoder: %s\n", Mix_GetChunkDecoder(i));
|
||||
}
|
||||
|
||||
total = Mix_GetNumMusicDecoders();
|
||||
for (i = 0; i < total; i++) {
|
||||
SDL_Log(" - music decoder: %s\n", Mix_GetMusicDecoder(i));
|
||||
}
|
||||
}
|
||||
|
||||
static void output_versions(const char *libname, int compiled, int linked)
|
||||
{
|
||||
SDL_Log("This program was compiled against %s %d.%d.%d,\n"
|
||||
" and is dynamically linked to %d.%d.%d.\n", libname,
|
||||
SDL_VERSIONNUM_MAJOR(compiled),
|
||||
SDL_VERSIONNUM_MINOR(compiled),
|
||||
SDL_VERSIONNUM_MICRO(compiled),
|
||||
SDL_VERSIONNUM_MAJOR(linked),
|
||||
SDL_VERSIONNUM_MINOR(linked),
|
||||
SDL_VERSIONNUM_MICRO(linked));
|
||||
}
|
||||
|
||||
static void test_versions(void)
|
||||
{
|
||||
output_versions("SDL", SDL_VERSION, SDL_GetVersion());
|
||||
output_versions("SDL_mixer", SDL_MIXER_VERSION, Mix_Version());
|
||||
}
|
||||
|
||||
static int channel_is_done = 0;
|
||||
static void SDLCALL channel_complete_callback (int chan)
|
||||
{
|
||||
if (verbose) {
|
||||
Mix_Chunk *done_chunk = Mix_GetChunk(chan);
|
||||
SDL_Log("We were just alerted that Mixer channel #%d is done.\n", chan);
|
||||
SDL_Log("Channel's chunk pointer is (%p).\n", (void *) done_chunk);
|
||||
SDL_Log(" Which %s correct.\n", (g_wave == done_chunk) ? "is" : "is NOT");
|
||||
}
|
||||
channel_is_done = 1;
|
||||
}
|
||||
|
||||
/* rcg06192001 abstract this out for testing purposes. */
|
||||
static int still_playing(void)
|
||||
{
|
||||
return Mix_Playing(0);
|
||||
}
|
||||
|
||||
static void do_panning_update(void)
|
||||
{
|
||||
static Uint8 leftvol = 128;
|
||||
static Uint8 rightvol = 128;
|
||||
static Sint8 leftincr = -1;
|
||||
static Sint8 rightincr = 1;
|
||||
static int panningok = 1;
|
||||
static Uint64 next_panning_update = 0;
|
||||
|
||||
if (panningok && (SDL_GetTicks() >= next_panning_update)) {
|
||||
panningok = Mix_SetPanning(0, leftvol, rightvol);
|
||||
if (!panningok) {
|
||||
SDL_Log("Mix_SetPanning(0, %d, %d) failed!\n",
|
||||
(int) leftvol, (int) rightvol);
|
||||
SDL_Log("Reason: [%s].\n", SDL_GetError());
|
||||
}
|
||||
|
||||
if ((leftvol == 255) || (leftvol == 0)) {
|
||||
if (leftvol == 255) {
|
||||
SDL_Log("All the way in the left speaker.\n");
|
||||
}
|
||||
leftincr *= -1;
|
||||
}
|
||||
|
||||
if ((rightvol == 255) || (rightvol == 0)) {
|
||||
if (rightvol == 255) {
|
||||
SDL_Log("All the way in the right speaker.\n");
|
||||
}
|
||||
rightincr *= -1;
|
||||
}
|
||||
|
||||
leftvol += leftincr;
|
||||
rightvol += rightincr;
|
||||
next_panning_update = SDL_GetTicks() + 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_distance_update(void)
|
||||
{
|
||||
static Uint8 distance = 1;
|
||||
static Sint8 distincr = 1;
|
||||
static int distanceok = 1;
|
||||
static Uint64 next_distance_update = 0;
|
||||
|
||||
if ((distanceok) && (SDL_GetTicks() >= next_distance_update)) {
|
||||
distanceok = Mix_SetDistance(0, distance);
|
||||
if (!distanceok) {
|
||||
SDL_Log("Mix_SetDistance(0, %d) failed!\n", (int) distance);
|
||||
SDL_Log("Reason: [%s].\n", SDL_GetError());
|
||||
}
|
||||
|
||||
if (distance == 0) {
|
||||
SDL_Log("Distance at nearest point.\n");
|
||||
distincr *= -1;
|
||||
}
|
||||
else if (distance == 255) {
|
||||
SDL_Log("Distance at furthest point.\n");
|
||||
distincr *= -1;
|
||||
}
|
||||
|
||||
distance += distincr;
|
||||
next_distance_update = SDL_GetTicks() + 15;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_position_update(void)
|
||||
{
|
||||
static Sint16 distance = 1;
|
||||
static Sint8 distincr = 1;
|
||||
static Sint16 angle = 0;
|
||||
static Sint8 angleincr = 1;
|
||||
static int positionok = 1;
|
||||
static Uint64 next_position_update = 0;
|
||||
|
||||
if (positionok && (SDL_GetTicks() >= next_position_update)) {
|
||||
positionok = Mix_SetPosition(0, angle, (Uint8)distance);
|
||||
if (!positionok) {
|
||||
SDL_Log("Mix_SetPosition(0, %d, %d) failed!\n",
|
||||
(int) angle, (int) distance);
|
||||
SDL_Log("Reason: [%s].\n", SDL_GetError());
|
||||
}
|
||||
|
||||
if (angle == 0) {
|
||||
SDL_Log("Due north; now rotating clockwise...\n");
|
||||
angleincr = 1;
|
||||
}
|
||||
|
||||
else if (angle == 360) {
|
||||
SDL_Log("Due north; now rotating counter-clockwise...\n");
|
||||
angleincr = -1;
|
||||
}
|
||||
|
||||
distance += distincr;
|
||||
if (distance < 0) {
|
||||
distance = 0;
|
||||
distincr = 3;
|
||||
SDL_Log("Distance is very, very near. Stepping away by threes...\n");
|
||||
} else if (distance > 255) {
|
||||
distance = 255;
|
||||
distincr = -3;
|
||||
SDL_Log("Distance is very, very far. Stepping towards by threes...\n");
|
||||
}
|
||||
|
||||
angle += angleincr;
|
||||
next_position_update = SDL_GetTicks() + 30;
|
||||
}
|
||||
}
|
||||
|
||||
static void CleanUp(int exitcode)
|
||||
{
|
||||
if (g_wave) {
|
||||
Mix_FreeChunk(g_wave);
|
||||
g_wave = NULL;
|
||||
}
|
||||
if (audio_open) {
|
||||
Mix_CloseAudio();
|
||||
audio_open = 0;
|
||||
}
|
||||
SDL_Quit();
|
||||
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/*
|
||||
* rcg06182001 This is sick, but cool.
|
||||
*
|
||||
* Actually, it's meant to be an example of how to manipulate a voice
|
||||
* without having to use the mixer effects API. This is more processing
|
||||
* up front, but no extra during the mixing process. Also, in a case like
|
||||
* this, when you need to touch the whole sample at once, it's the only
|
||||
* option you've got. And, with the effects API, you are altering a copy of
|
||||
* the original sample for each playback, and thus, your changes aren't
|
||||
* permanent; here, you've got a reversed sample, and that's that until
|
||||
* you either reverse it again, or reload it.
|
||||
*/
|
||||
static void flip_sample(Mix_Chunk *wave)
|
||||
{
|
||||
SDL_AudioFormat format;
|
||||
int channels, i, incr;
|
||||
Uint8 *start = wave->abuf;
|
||||
Uint8 *end = wave->abuf + wave->alen;
|
||||
|
||||
Mix_QuerySpec(NULL, &format, &channels);
|
||||
incr = SDL_AUDIO_BITSIZE(format) * channels;
|
||||
|
||||
end -= incr;
|
||||
|
||||
switch (incr) {
|
||||
case 8:
|
||||
for (i = wave->alen / 2; i >= 0; i -= 1) {
|
||||
Uint8 tmp = *start;
|
||||
*start = *end;
|
||||
*end = tmp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
for (i = wave->alen / 2; i >= 0; i -= 2) {
|
||||
Uint16 tmp = *start;
|
||||
*((Uint16 *) start) = *((Uint16 *) end);
|
||||
*((Uint16 *) end) = tmp;
|
||||
start += 2;
|
||||
end -= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
for (i = wave->alen / 2; i >= 0; i -= 4) {
|
||||
Uint32 tmp = *start;
|
||||
*((Uint32 *) start) = *((Uint32 *) end);
|
||||
*((Uint32 *) end) = tmp;
|
||||
start += 4;
|
||||
end -= 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 64:
|
||||
for (i = wave->alen / 2; i >= 0; i -= 8) {
|
||||
Uint64 tmp = *start;
|
||||
*((Uint64 *) start) = *((Uint64 *) end);
|
||||
*((Uint64 *) end) = tmp;
|
||||
start += 8;
|
||||
end -= 8;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_Log("Unhandled format in sample flipping.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
int loops = 0;
|
||||
int i;
|
||||
int reverse_stereo = 0;
|
||||
int reverse_sample = 0;
|
||||
const char *filename = NULL;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
#ifdef HAVE_SETBUF
|
||||
setbuf(stdout, NULL); /* rcg06132001 for debugging purposes. */
|
||||
setbuf(stderr, NULL); /* rcg06192001 for debugging purposes, too. */
|
||||
#endif
|
||||
|
||||
/* Initialize variables */
|
||||
spec.freq = MIX_DEFAULT_FREQUENCY;
|
||||
spec.format = MIX_DEFAULT_FORMAT;
|
||||
spec.channels = MIX_DEFAULT_CHANNELS;
|
||||
|
||||
/* Parse commandline */
|
||||
for (i = 1; i < argc;) {
|
||||
int consumed = 0;
|
||||
|
||||
if (SDL_strcmp("-r", argv[i]) == 0) {
|
||||
spec.freq = SDL_atoi(argv[i + 1]);
|
||||
consumed = 2;
|
||||
} else if (SDL_strcmp("-m", argv[i]) == 0) {
|
||||
spec.channels = 1;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("-c", argv[i]) == 0) {
|
||||
spec.channels = SDL_atoi(argv[i + 1]);
|
||||
consumed = 2;
|
||||
} else if (SDL_strcmp("-l", argv[i]) == 0) {
|
||||
loops = -1;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("-8", argv[i]) == 0) {
|
||||
spec.format = SDL_AUDIO_U8;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("-f32", argv[i]) == 0) {
|
||||
spec.format = SDL_AUDIO_F32;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("-f", argv[i]) == 0) {
|
||||
reverse_stereo = 1;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("-F", argv[i]) == 0) {
|
||||
reverse_sample = 1;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("--panning", argv[i]) == 0) {
|
||||
test_panning = true;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("--distance", argv[i]) == 0) {
|
||||
test_distance = true;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("--position", argv[i]) == 0) {
|
||||
test_position = true;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("--version", argv[i]) == 0) {
|
||||
test_versions();
|
||||
CleanUp(0);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp("--verbose", argv[i]) == 0) {
|
||||
verbose = true;
|
||||
consumed = 1;
|
||||
} else if (argv[i][0] != '-' && !filename) {
|
||||
filename = argv[i];
|
||||
consumed = 1;
|
||||
}
|
||||
if (consumed <= 0) {
|
||||
SDL_Log("Usage: %s [-r rate] [-m] [-c channels] [-l] [-8] [-f32] [-f] [-F] [--distance] [--panning] [--position] [--version] <wavefile>", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
i += consumed;
|
||||
}
|
||||
if (test_position && (test_distance || test_panning)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "position cannot be combined with distance or panning");
|
||||
CleanUp(1);
|
||||
}
|
||||
|
||||
/* Initialize the SDL library */
|
||||
if (!SDL_Init(SDL_INIT_AUDIO)) {
|
||||
SDL_Log("Couldn't initialize SDL: %s\n",SDL_GetError());
|
||||
return 255;
|
||||
}
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
signal(SIGINT, CleanUp);
|
||||
signal(SIGTERM, CleanUp);
|
||||
#endif
|
||||
|
||||
/* Open the audio device */
|
||||
if (!Mix_OpenAudio(0, &spec)) {
|
||||
SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
|
||||
CleanUp(2);
|
||||
} else {
|
||||
Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels);
|
||||
SDL_Log("Opened audio at %d Hz %d bit%s %s", spec.freq,
|
||||
(spec.format&0xFF),
|
||||
(SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""),
|
||||
(spec.channels > 2) ? "surround" :
|
||||
(spec.channels > 1) ? "stereo" : "mono");
|
||||
if (loops) {
|
||||
SDL_Log(" (looping)\n");
|
||||
} else {
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
audio_open = 1;
|
||||
|
||||
if (verbose) {
|
||||
report_decoders();
|
||||
}
|
||||
|
||||
/* Load the requested wave file */
|
||||
g_wave = Mix_LoadWAV(filename);
|
||||
if (g_wave == NULL) {
|
||||
SDL_Log("Couldn't load %s: %s\n", filename, SDL_GetError());
|
||||
CleanUp(2);
|
||||
}
|
||||
|
||||
if (reverse_sample) {
|
||||
flip_sample(g_wave);
|
||||
}
|
||||
|
||||
Mix_ChannelFinished(channel_complete_callback);
|
||||
|
||||
if ((!Mix_SetReverseStereo(MIX_CHANNEL_POST, reverse_stereo)) &&
|
||||
(reverse_stereo))
|
||||
{
|
||||
SDL_Log("Failed to set up reverse stereo effect!\n");
|
||||
SDL_Log("Reason: [%s].\n", SDL_GetError());
|
||||
}
|
||||
|
||||
/* Play and then exit */
|
||||
Mix_PlayChannel(0, g_wave, loops);
|
||||
|
||||
while (still_playing()) {
|
||||
|
||||
if (test_panning) {
|
||||
do_panning_update();
|
||||
}
|
||||
|
||||
if (test_distance) {
|
||||
do_distance_update();
|
||||
}
|
||||
|
||||
if (test_position) {
|
||||
do_position_update();
|
||||
}
|
||||
|
||||
SDL_Delay(1);
|
||||
|
||||
} /* while still_playing() loop... */
|
||||
|
||||
CleanUp(0);
|
||||
|
||||
/* Not reached, but fixes compiler warnings */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* end of playwave.c ... */
|
||||
Reference in New Issue
Block a user