test/testmultiaudio.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Wed, 25 Nov 2015 21:39:28 +0100
changeset 9922 b066d5fd5fa7
parent 9619 b94b6d0bff0f
child 9998 f67cf37e9cd4
permissions -rw-r--r--
Replaced tabs with spaces in test programs.
     1 /*
     2   Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
     3 
     4   This software is provided 'as-is', without any express or implied
     5   warranty.  In no event will the authors be held liable for any damages
     6   arising from the use of this software.
     7 
     8   Permission is granted to anyone to use this software for any purpose,
     9   including commercial applications, and to alter it and redistribute it
    10   freely.
    11 */
    12 #include "SDL.h"
    13 
    14 #include <stdio.h> /* for fflush() and stdout */
    15 
    16 #ifdef __EMSCRIPTEN__
    17 #include <emscripten/emscripten.h>
    18 #endif
    19 
    20 static SDL_AudioSpec spec;
    21 static Uint8 *sound = NULL;     /* Pointer to wave data */
    22 static Uint32 soundlen = 0;     /* Length of wave data */
    23 
    24 typedef struct
    25 {
    26     SDL_AudioDeviceID dev;
    27     int soundpos;
    28     volatile int done;
    29 } callback_data;
    30 
    31 callback_data cbd[64];
    32 
    33 void SDLCALL
    34 play_through_once(void *arg, Uint8 * stream, int len)
    35 {
    36     callback_data *cbd = (callback_data *) arg;
    37     Uint8 *waveptr = sound + cbd->soundpos;
    38     int waveleft = soundlen - cbd->soundpos;
    39     int cpy = len;
    40     if (cpy > waveleft)
    41         cpy = waveleft;
    42 
    43     SDL_memcpy(stream, waveptr, cpy);
    44     len -= cpy;
    45     cbd->soundpos += cpy;
    46     if (len > 0) {
    47         stream += cpy;
    48         SDL_memset(stream, spec.silence, len);
    49         cbd->done++;
    50     }
    51 }
    52 
    53 void
    54 loop()
    55 {
    56     if(cbd[0].done) {
    57 #ifdef __EMSCRIPTEN__
    58         emscripten_cancel_main_loop();
    59 #endif
    60         SDL_PauseAudioDevice(cbd[0].dev, 1);
    61         SDL_CloseAudioDevice(cbd[0].dev);
    62         SDL_FreeWAV(sound);
    63         SDL_Quit();
    64     }
    65 }
    66 
    67 static void
    68 test_multi_audio(int devcount)
    69 {
    70     int keep_going = 1;
    71     int i;
    72     
    73 #ifdef __ANDROID__  
    74     SDL_Event event;
    75   
    76     /* Create a Window to get fully initialized event processing for testing pause on Android. */
    77     SDL_CreateWindow("testmultiaudio", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
    78 #endif
    79 
    80     if (devcount > 64) {
    81         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n",
    82                 devcount);
    83         devcount = 64;
    84     }
    85 
    86     spec.callback = play_through_once;
    87 
    88     for (i = 0; i < devcount; i++) {
    89         const char *devname = SDL_GetAudioDeviceName(i, 0);
    90         SDL_Log("playing on device #%d: ('%s')...", i, devname);
    91         fflush(stdout);
    92 
    93         SDL_memset(&cbd[0], '\0', sizeof(callback_data));
    94         spec.userdata = &cbd[0];
    95         cbd[0].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
    96         if (cbd[0].dev == 0) {
    97             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError());
    98         } else {
    99             SDL_PauseAudioDevice(cbd[0].dev, 0);
   100 #ifdef __EMSCRIPTEN__
   101             emscripten_set_main_loop(loop, 0, 1);
   102 #else
   103             while (!cbd[0].done)
   104             {
   105                 #ifdef __ANDROID__                
   106                 /* Empty queue, some application events would prevent pause. */
   107                 while (SDL_PollEvent(&event)){}
   108                 #endif                
   109                 SDL_Delay(100);
   110             }
   111             SDL_PauseAudioDevice(cbd[0].dev, 1);
   112 #endif
   113             SDL_Log("done.\n");
   114             SDL_CloseAudioDevice(cbd[0].dev);
   115         }
   116     }
   117 
   118     SDL_memset(cbd, '\0', sizeof(cbd));
   119 
   120     SDL_Log("playing on all devices...\n");
   121     for (i = 0; i < devcount; i++) {
   122         const char *devname = SDL_GetAudioDeviceName(i, 0);
   123         spec.userdata = &cbd[i];
   124         cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
   125         if (cbd[i].dev == 0) {
   126             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError());
   127         }
   128     }
   129 
   130     for (i = 0; i < devcount; i++) {
   131         if (cbd[i].dev) {
   132             SDL_PauseAudioDevice(cbd[i].dev, 0);
   133         }
   134     }
   135 
   136     while (keep_going) {
   137         keep_going = 0;
   138         for (i = 0; i < devcount; i++) {
   139             if ((cbd[i].dev) && (!cbd[i].done)) {
   140                 keep_going = 1;
   141             }
   142         }
   143         #ifdef __ANDROID__        
   144         /* Empty queue, some application events would prevent pause. */
   145         while (SDL_PollEvent(&event)){}
   146         #endif        
   147 
   148         SDL_Delay(100);
   149     }
   150 
   151 #ifndef __EMSCRIPTEN__
   152     for (i = 0; i < devcount; i++) {
   153         if (cbd[i].dev) {
   154             SDL_PauseAudioDevice(cbd[i].dev, 1);
   155             SDL_CloseAudioDevice(cbd[i].dev);
   156         }
   157     }
   158 
   159     SDL_Log("All done!\n");
   160 #endif
   161 }
   162 
   163 
   164 int
   165 main(int argc, char **argv)
   166 {
   167     int devcount = 0;
   168 
   169     /* Enable standard application logging */
   170     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
   171 
   172     /* Load the SDL library */
   173     if (SDL_Init(SDL_INIT_AUDIO) < 0) {
   174         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
   175         return (1);
   176     }
   177 
   178     SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
   179     
   180     devcount = SDL_GetNumAudioDevices(0);
   181     if (devcount < 1) {
   182         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
   183     } else {
   184         if (argv[1] == NULL) {
   185             argv[1] = "sample.wav";
   186         }
   187 
   188         /* Load the wave file into memory */
   189         if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) {
   190             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1],
   191                     SDL_GetError());
   192         } else {
   193             test_multi_audio(devcount);
   194             SDL_FreeWAV(sound);
   195         }
   196     }
   197 
   198     SDL_Quit();
   199     return 0;
   200 }