sdl

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

testaudiohotplug.c (5579B)


      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 
     13 /* Program to test hotplugging of audio devices */
     14 
     15 #include "SDL_config.h"
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 
     20 #if HAVE_SIGNAL_H
     21 #include <signal.h>
     22 #endif
     23 
     24 #ifdef __EMSCRIPTEN__
     25 #include <emscripten/emscripten.h>
     26 #endif
     27 
     28 #include "SDL.h"
     29 
     30 static SDL_AudioSpec spec;
     31 static Uint8 *sound = NULL;     /* Pointer to wave data */
     32 static Uint32 soundlen = 0;     /* Length of wave data */
     33 
     34 static int posindex = 0;
     35 static Uint32 positions[64];
     36 
     37 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
     38 static void
     39 quit(int rc)
     40 {
     41     SDL_Quit();
     42     exit(rc);
     43 }
     44 
     45 void SDLCALL
     46 fillerup(void *_pos, Uint8 * stream, int len)
     47 {
     48     Uint32 pos = *((Uint32 *) _pos);
     49     Uint8 *waveptr;
     50     int waveleft;
     51 
     52     /* Set up the pointers */
     53     waveptr = sound + pos;
     54     waveleft = soundlen - pos;
     55 
     56     /* Go! */
     57     while (waveleft <= len) {
     58         SDL_memcpy(stream, waveptr, waveleft);
     59         stream += waveleft;
     60         len -= waveleft;
     61         waveptr = sound;
     62         waveleft = soundlen;
     63         pos = 0;
     64     }
     65     SDL_memcpy(stream, waveptr, len);
     66     pos += len;
     67     *((Uint32 *) _pos) = pos;
     68 }
     69 
     70 static int done = 0;
     71 void
     72 poked(int sig)
     73 {
     74     done = 1;
     75 }
     76 
     77 static const char*
     78 devtypestr(int iscapture)
     79 {
     80     return iscapture ? "capture" : "output";
     81 }
     82 
     83 static void
     84 iteration()
     85 {
     86     SDL_Event e;
     87     SDL_AudioDeviceID dev;
     88     while (SDL_PollEvent(&e)) {
     89         if (e.type == SDL_QUIT) {
     90             done = 1;
     91         } else if (e.type == SDL_KEYUP) {
     92             if (e.key.keysym.sym == SDLK_ESCAPE)
     93                 done = 1;
     94         } else if (e.type == SDL_AUDIODEVICEADDED) {
     95             int index = e.adevice.which;
     96             int iscapture = e.adevice.iscapture;
     97             const char *name = SDL_GetAudioDeviceName(index, iscapture);
     98             if (name != NULL)
     99                 SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name);
    100             else {
    101                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n",
    102                     devtypestr(iscapture), (unsigned int) index, SDL_GetError());
    103                 continue;
    104             }
    105             if (!iscapture) {
    106                 positions[posindex] = 0;
    107                 spec.userdata = &positions[posindex++];
    108                 spec.callback = fillerup;
    109                 dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
    110                 if (!dev) {
    111                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
    112                 } else {
    113                     SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev);
    114                     SDL_PauseAudioDevice(dev, 0);
    115                 }
    116             }
    117         } else if (e.type == SDL_AUDIODEVICEREMOVED) {
    118             dev = (SDL_AudioDeviceID) e.adevice.which;
    119             SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev);
    120             SDL_CloseAudioDevice(dev);
    121         }
    122     }
    123 }
    124 
    125 #ifdef __EMSCRIPTEN__
    126 void
    127 loop()
    128 {
    129     if(done)
    130         emscripten_cancel_main_loop();
    131     else
    132         iteration();
    133 }
    134 #endif
    135 
    136 int
    137 main(int argc, char *argv[])
    138 {
    139     int i;
    140     char filename[4096];
    141 
    142     /* Enable standard application logging */
    143     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    144 
    145     /* Load the SDL library */
    146     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
    147         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    148         return (1);
    149     }
    150 
    151     /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
    152     SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));
    153 
    154     if (argc > 1) {
    155         SDL_strlcpy(filename, argv[1], sizeof(filename));
    156     } else {
    157         SDL_strlcpy(filename, "sample.wav", sizeof(filename));
    158     }
    159     /* Load the wave file into memory */
    160     if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
    161         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
    162         quit(1);
    163     }
    164 
    165 #if HAVE_SIGNAL_H
    166     /* Set the signals */
    167 #ifdef SIGHUP
    168     signal(SIGHUP, poked);
    169 #endif
    170     signal(SIGINT, poked);
    171 #ifdef SIGQUIT
    172     signal(SIGQUIT, poked);
    173 #endif
    174     signal(SIGTERM, poked);
    175 #endif /* HAVE_SIGNAL_H */
    176 
    177     /* Show the list of available drivers */
    178     SDL_Log("Available audio drivers:");
    179     for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
    180         SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
    181     }
    182 
    183     SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n");
    184     SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
    185 
    186 #ifdef __EMSCRIPTEN__
    187     emscripten_set_main_loop(loop, 0, 1);
    188 #else
    189     while (!done) {
    190         SDL_Delay(100);
    191         iteration();
    192     }
    193 #endif
    194 
    195     /* Clean up on signal */
    196     /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */
    197     SDL_QuitSubSystem(SDL_INIT_AUDIO);
    198     SDL_FreeWAV(sound);
    199     SDL_Quit();
    200     return (0);
    201 }
    202 
    203 /* vi: set ts=4 sw=4 expandtab: */