Add 'restrict' to another parameter
[openal-soft.git] / examples / common / sdl_sound.c
blob79a5bf329044f01d5fc797a73c91ef68fd819f0b
1 /*
2 * SDL_sound Decoder Helpers
4 * Copyright (c) 2013 by Chris Robinson <chris.kcat@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 /* This file contains routines for helping to decode audio using SDL_sound.
26 * There's very little OpenAL-specific code here.
28 #include "sdl_sound.h"
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <signal.h>
34 #include <assert.h>
36 #include <SDL_sound.h>
38 #include "AL/al.h"
39 #include "AL/alc.h"
40 #include "AL/alext.h"
42 #include "alhelpers.h"
45 static int done_init = 0;
47 FilePtr openAudioFile(const char *fname, size_t buftime_ms)
49 FilePtr file;
50 ALuint rate;
51 Uint32 bufsize;
52 ALenum chans, type;
54 /* We need to make sure SDL_sound is initialized. */
55 if(!done_init)
57 Sound_Init();
58 done_init = 1;
61 file = Sound_NewSampleFromFile(fname, NULL, 0);
62 if(!file)
64 fprintf(stderr, "Failed to open %s: %s\n", fname, Sound_GetError());
65 return NULL;
68 if(getAudioInfo(file, &rate, &chans, &type) != 0)
70 Sound_FreeSample(file);
71 return NULL;
74 bufsize = FramesToBytes((ALsizei)(buftime_ms/1000.0*rate), chans, type);
75 if(Sound_SetBufferSize(file, bufsize) == 0)
77 fprintf(stderr, "Failed to set buffer size to %u bytes: %s\n", bufsize, Sound_GetError());
78 Sound_FreeSample(file);
79 return NULL;
82 return file;
85 void closeAudioFile(FilePtr file)
87 if(file)
88 Sound_FreeSample(file);
92 int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type)
94 if(file->actual.channels == 1)
95 *channels = AL_MONO_SOFT;
96 else if(file->actual.channels == 2)
97 *channels = AL_STEREO_SOFT;
98 else
100 fprintf(stderr, "Unsupported channel count: %d\n", file->actual.channels);
101 return 1;
104 if(file->actual.format == AUDIO_U8)
105 *type = AL_UNSIGNED_BYTE_SOFT;
106 else if(file->actual.format == AUDIO_S8)
107 *type = AL_BYTE_SOFT;
108 else if(file->actual.format == AUDIO_U16LSB || file->actual.format == AUDIO_U16MSB)
109 *type = AL_UNSIGNED_SHORT_SOFT;
110 else if(file->actual.format == AUDIO_S16LSB || file->actual.format == AUDIO_S16MSB)
111 *type = AL_SHORT_SOFT;
112 else
114 fprintf(stderr, "Unsupported sample format: 0x%04x\n", file->actual.format);
115 return 1;
118 *rate = file->actual.rate;
120 return 0;
124 uint8_t *getAudioData(FilePtr file, size_t *length)
126 *length = Sound_Decode(file);
127 if(*length == 0)
128 return NULL;
129 if((file->actual.format == AUDIO_U16LSB && AUDIO_U16LSB != AUDIO_U16SYS) ||
130 (file->actual.format == AUDIO_U16MSB && AUDIO_U16MSB != AUDIO_U16SYS) ||
131 (file->actual.format == AUDIO_S16LSB && AUDIO_S16LSB != AUDIO_S16SYS) ||
132 (file->actual.format == AUDIO_S16MSB && AUDIO_S16MSB != AUDIO_S16SYS))
134 /* Swap bytes if the decoded endianness doesn't match the system. */
135 char *buffer = file->buffer;
136 size_t i;
137 for(i = 0;i < *length;i+=2)
139 char b = buffer[i];
140 buffer[i] = buffer[i+1];
141 buffer[i+1] = b;
144 return file->buffer;
147 void *decodeAudioStream(FilePtr file, size_t *length)
149 Uint32 got;
150 char *mem;
152 got = Sound_DecodeAll(file);
153 if(got == 0)
155 *length = 0;
156 return NULL;
159 mem = malloc(got);
160 memcpy(mem, file->buffer, got);
162 *length = got;
163 return mem;