Advertisement

05.18.2008 at 10:25PM PDT, ID: 23412802
[x]
Attachment Details

SDL wav player coding

Asked by RockBaby in C Programming Language

Tags: C

Hi,

I'm not familiar with SDL function which used to create sound player.
Let's say i need to create an application in programming C. The application need to rewind, change pitch, toggle looping and non looping.
How do i get to know all these?

Attached with a sample code i found.Start Free Trial
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
/* Program to load a wave file and loop playing it using SDL sound */
 
/* loopwaves.c is much more robust in handling WAVE files -- 
	This is only for simple WAVEs
*/
#include "SDL_config.h"
 
#include <stdio.h>
#include <stdlib.h>
 
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
 
#include "SDL.h"
#include "SDL_audio.h"
 
static double volume = 1.0f; 
struct {
	SDL_AudioSpec spec;
	Uint8   *sound;			/* Pointer to wave data */
	Uint32   soundlen;		/* Length of wave data */
	int      soundpos;		/* Current play position */
} wave;
 
 
static int done = 0;
void poked(int sig)
{
	done = 1;
}
 
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
	SDL_Quit();
	exit(rc);
}
 
/* Process the audio buffer, here only adjust the volume. */
void process_audio(Uint8 *audio_buf, int buf_size) {
	int i;
    switch (wave.spec.format) {
    case AUDIO_U8: {
        // unsigned 8-bit sample
        Uint8 *ptr = (Uint8 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Uint8)) {
                double tmp = (*ptr) * volume;
                tmp = tmp > 255.0 ? 255.0 : tmp;
                *ptr = (Uint8)tmp;
                ptr++;
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 255.0 ? 255.0 : tmp;
                *ptr = (Uint8)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 255.0 ? 255.0 : tmp;
                *ptr = (Uint8)tmp;
                ptr++;
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    case AUDIO_S8: {
        // signed 8-bit sample
        Sint8 *ptr = (Sint8 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Sint8)) {
                double tmp = (*ptr) * volume;
                tmp = tmp > 127.0 ? 127.0 : tmp;
                tmp = tmp < -128.0 ? -128.0 : tmp;
                *ptr = (Sint8)tmp;
                ptr++; // note here ptr will move to 8 bits higher
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 127.0 ? 127.0 : tmp;
                tmp = tmp < -128.0 ? -128.0 : tmp;
                *ptr = (Sint8)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 127.0 ? 127.0 : tmp;
                tmp = tmp < -128.0 ? -128.0 : tmp;
                *ptr = (Sint8)tmp;
                ptr++;
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    case AUDIO_U16LSB: {
        // unsigned 16-bit sample, little-endian
        Uint16 *ptr = (Uint16 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Uint16)) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
                Uint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++; // note here ptr will move to 16 bits higher
#else
                double tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
#endif
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
                // process left channel
                Uint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
                
                // process right channel
                swap = SDL_Swap16(*ptr);
                tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
#endif
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    case AUDIO_S16LSB: {
        // signed 16-bit sample, little-endian
        Sint16 *ptr = (Sint16 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
                Sint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                double tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
#endif
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
                // process left channel
                Sint16 swap = SDL_Swap(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
                
                // process right channel
                swap = SDL_Swap(*ptr);
                tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
#endif
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    case AUDIO_U16MSB: {
        // unsigned 16-bit sample, big-endian
        Uint16 *ptr = (Uint16 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Uint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
                Uint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++; // note here ptr will move to 16 bits higher
#else
                double tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
#endif
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
                // process left channel
                Uint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
                
                // process right channel
                swap = SDL_Swap16(*ptr);
                tmp = swap * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                swap = (Uint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 65535.0 ? 65535.0 : tmp;
                *ptr = (Uint16)tmp;
                ptr++;
#endif
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    case AUDIO_S16MSB: {
        // signed 16-bit sample, big-endian
        Sint16 *ptr = (Sint16 *)audio_buf;
        if (wave.spec.channels == 1) {
            // process mono audio
            for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
                Sint16 swap = SDL_Swap16(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                double tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
#endif
            }
        } else if (wave.spec.channels == 2) {
            // process stero audio
            for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
                // process left channel
                Sint16 swap = SDL_Swap(*ptr);
                double tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
                
                // process right channel
                swap = SDL_Swap(*ptr);
                tmp = swap * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                swap = (Sint16)tmp;
                *ptr = SDL_Swap16(swap);
                ptr++;
#else
                // process left channel
                double tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
                
                // process right channel
                tmp = (*ptr) * volume;
                tmp = tmp > 32767.0 ? 32767.0 : tmp;
                tmp = tmp < -32768.0 ? -32768.0 : tmp;
                *ptr = (Sint16)tmp;
                ptr++;
#endif
            }
        } else {
            fprintf(stderr, "Doesn't support more than 2 channels!\n");
            exit(1);
        }
        break; }
    }
}
 
void SDLCALL fillerup(void *unused, Uint8 *stream, int len)
{
	Uint8 *waveptr;
	int    waveleft;
 
	/* Set up the pointers */
	waveptr = wave.sound + wave.soundpos;
	waveleft = wave.soundlen - wave.soundpos;
 
	/* Go! */
	while ( waveleft <= len ) {
		/* Process samples */
		Uint8 process_buf[waveleft];
		SDL_memcpy(process_buf, waveptr, waveleft);
		process_audio(process_buf, waveleft);
	
		// play the end of the audio
		SDL_memcpy(stream, process_buf, waveleft);
		stream += waveleft;
		len -= waveleft;
 
		// ready to repeat play the audio
		waveptr = wave.sound;
		waveleft = wave.soundlen;
		wave.soundpos = 0;
	}
	
	/* Process samples */
	Uint8 process_buf[len];
	SDL_memcpy(process_buf, waveptr, len);
	process_audio(process_buf, len);
	
	// play the processed samples
	SDL_memcpy(stream, process_buf, len);
	wave.soundpos += len;
}
 
static const int SCR_WIDTH = 240;
static const int SCR_HEIGHT = 180;
int main(int argc, char *argv[])
{
	char		name[32];
    SDL_Event   event;
    Uint8       *keys;
    SDL_Surface *screen;
 
	/* Load the SDL library */
	if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
		return(1);
	}
	if ( argv[1] == NULL ) {
		argv[1] = "sample.wav";
	}
	
    // Make a screen to put our video
#ifndef __DARWIN__
    screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 0, 0);
#else
    screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 24, 0);
#endif
 
    if (!screen) {
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
        quit(1);
    }
	
	/* Load the wave file into memory */
	if ( SDL_LoadWAV(argv[1],
			&wave.spec, &wave.sound, &wave.soundlen) == NULL ) {
		fprintf(stderr, "Couldn't load %s: %s\n",
						argv[1], SDL_GetError());
		quit(1);
	}
 
	wave.spec.callback = fillerup;
	
#if HAVE_SIGNAL_H
	/* Set the signals */
#ifdef SIGHUP
	signal(SIGHUP, poked);
#endif
	signal(SIGINT, poked);
#ifdef SIGQUIT
	signal(SIGQUIT, poked);
#endif
	signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */
 
	/* Initialize fillerup() variables */
	if ( SDL_OpenAudio(&wave.spec, NULL) < 0 ) {
		fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
		SDL_FreeWAV(wave.sound);
		quit(2);
	}
	// start playing
	SDL_PauseAudio(0);
 
	/* Let the audio run */
	printf("Using audio driver: %s\n", SDL_AudioDriverName(name, 32));
	while ( ! done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) ) {
        // Poll input queue, run keyboard loop
        while ( SDL_PollEvent(&event) ) {
            if ( event.type == SDL_QUIT )
                done = 1;
        }
        keys = SDL_GetKeyState(NULL);
        if (keys[SDLK_q]) {
            done = 1;
        } else if (keys[SDLK_MINUS]) {
			volume /= 2.0f;
		} else if (keys[SDLK_EQUALS]) {
			volume *= 2.0f;
		}
		
		
		SDL_Delay(100);
	}
 
	/* Clean up on signal */
	SDL_CloseAudio();
	SDL_FreeWAV(wave.sound);
	SDL_Quit();
	return(0);
}
[+][-]05.19.2008 at 12:51AM PDT, ID: 21595818

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]05.19.2008 at 01:06AM PDT, ID: 21595879

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]05.19.2008 at 01:16AM PDT, ID: 21595929

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]05.19.2008 at 02:55AM PDT, ID: 21596298

View this solution now by starting your 7-day free trial. Setting up your free trial is quick, easy, and secure. We will return you to this solution, unlocked, when you're done.

 

About this solution

Zone: C Programming Language
Tags: C
Sign Up Now!
Solution Provided By: Infinity08
Participating Experts: 1
Solution Grade: B
 
 
[+][-]05.23.2008 at 05:12AM PDT, ID: 21631281

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
[+][-]05.23.2008 at 05:49AM PDT, ID: 21631556

At Experts Exchange, members can ask their questions to thousands of technology professionals, also known as Experts. Experts compete and collaborate to answer those questions by leaving comments like this one.

Start your 7-day free trial to view this Expert Comment or ask the Experts your question.

 
[+][-]05.23.2008 at 05:50AM PDT, ID: 21631564

Often, when Experts are collaborating with members who have asked questions, they will request additional information about the problem. Askers respond with an author comment like this one.

Start your 7-day free trial to view this Author Comment or ask the Experts your question.

 
 
Loading Advertisement...
20080716-EE-VQP-32 / EE_QW_2_20070628