sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

testmultiaudio.c (5516B)


      1 /*
      2   Copyright (C) 1997-2020 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     SDL_atomic_t 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         SDL_AtomicSet(&cbd->done, 1);
     50     }
     51 }
     52 
     53 void
     54 loop()
     55 {
     56     if (SDL_AtomicGet(&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 (!SDL_AtomicGet(&cbd[0].done)) {
    104                 #ifdef __ANDROID__                
    105                 /* Empty queue, some application events would prevent pause. */
    106                 while (SDL_PollEvent(&event)){}
    107                 #endif                
    108                 SDL_Delay(100);
    109             }
    110             SDL_PauseAudioDevice(cbd[0].dev, 1);
    111 #endif
    112             SDL_Log("done.\n");
    113             SDL_CloseAudioDevice(cbd[0].dev);
    114         }
    115     }
    116 
    117     SDL_memset(cbd, '\0', sizeof(cbd));
    118 
    119     SDL_Log("playing on all devices...\n");
    120     for (i = 0; i < devcount; i++) {
    121         const char *devname = SDL_GetAudioDeviceName(i, 0);
    122         spec.userdata = &cbd[i];
    123         cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
    124         if (cbd[i].dev == 0) {
    125             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError());
    126         }
    127     }
    128 
    129     for (i = 0; i < devcount; i++) {
    130         if (cbd[i].dev) {
    131             SDL_PauseAudioDevice(cbd[i].dev, 0);
    132         }
    133     }
    134 
    135     while (keep_going) {
    136         keep_going = 0;
    137         for (i = 0; i < devcount; i++) {
    138             if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) {
    139                 keep_going = 1;
    140             }
    141         }
    142         #ifdef __ANDROID__        
    143         /* Empty queue, some application events would prevent pause. */
    144         while (SDL_PollEvent(&event)){}
    145         #endif        
    146 
    147         SDL_Delay(100);
    148     }
    149 
    150 #ifndef __EMSCRIPTEN__
    151     for (i = 0; i < devcount; i++) {
    152         if (cbd[i].dev) {
    153             SDL_PauseAudioDevice(cbd[i].dev, 1);
    154             SDL_CloseAudioDevice(cbd[i].dev);
    155         }
    156     }
    157 
    158     SDL_Log("All done!\n");
    159 #endif
    160 }
    161 
    162 
    163 int
    164 main(int argc, char **argv)
    165 {
    166     int devcount = 0;
    167 
    168     /* Enable standard application logging */
    169     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    170 
    171     /* Load the SDL library */
    172     if (SDL_Init(SDL_INIT_AUDIO) < 0) {
    173         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    174         return (1);
    175     }
    176 
    177     SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
    178     
    179     devcount = SDL_GetNumAudioDevices(0);
    180     if (devcount < 1) {
    181         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
    182     } else {
    183         if (argv[1] == NULL) {
    184             argv[1] = "sample.wav";
    185         }
    186 
    187         /* Load the wave file into memory */
    188         if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) {
    189             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1],
    190                     SDL_GetError());
    191         } else {
    192             test_multi_audio(devcount);
    193             SDL_FreeWAV(sound);
    194         }
    195     }
    196 
    197     SDL_Quit();
    198     return 0;
    199 }