test/testmultiaudio.c
author Gabriel Jacobo <gabomdq@gmail.com>
Wed, 17 Sep 2014 11:41:12 -0300
changeset 9145 aa99e029b12e
parent 8851 a7cfe554d337
child 9269 d51f84c20b10
permissions -rw-r--r--
[Android] Fixes #2480, music does not pause when process backgrounded

This modifies SDL_PauseAudio behavior to pause all audio devices instead of
just the default one (required on Android, at least for testmultiaudio on my
Nexus 4 which reported 2 audio devices).
It also changes SDL_PauseAudioDevice to retain the device lock from pause until
resume in order to save battery in mobile devices.
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
icculus@2049
    12
#include "SDL.h"
icculus@2049
    13
philipp@8787
    14
#include <stdio.h> /* for fflush() and stdout */
philipp@8787
    15
icculus@2049
    16
static SDL_AudioSpec spec;
slouken@2060
    17
static Uint8 *sound = NULL;     /* Pointer to wave data */
slouken@2060
    18
static Uint32 soundlen = 0;     /* Length of wave data */
icculus@2049
    19
icculus@2049
    20
typedef struct
icculus@2049
    21
{
icculus@2049
    22
    SDL_AudioDeviceID dev;
icculus@2049
    23
    int soundpos;
icculus@2049
    24
    volatile int done;
icculus@2049
    25
} callback_data;
icculus@2049
    26
slouken@2060
    27
void SDLCALL
slouken@2060
    28
play_through_once(void *arg, Uint8 * stream, int len)
icculus@2049
    29
{
icculus@2049
    30
    callback_data *cbd = (callback_data *) arg;
icculus@2049
    31
    Uint8 *waveptr = sound + cbd->soundpos;
icculus@2049
    32
    int waveleft = soundlen - cbd->soundpos;
icculus@2049
    33
    int cpy = len;
icculus@2049
    34
    if (cpy > waveleft)
icculus@2049
    35
        cpy = waveleft;
icculus@2049
    36
icculus@2146
    37
    SDL_memcpy(stream, waveptr, cpy);
icculus@2049
    38
    len -= cpy;
icculus@2049
    39
    cbd->soundpos += cpy;
icculus@2049
    40
    if (len > 0) {
icculus@2049
    41
        stream += cpy;
icculus@2146
    42
        SDL_memset(stream, spec.silence, len);
icculus@2049
    43
        cbd->done++;
icculus@2049
    44
    }
icculus@2049
    45
}
icculus@2049
    46
slouken@2060
    47
static void
slouken@2060
    48
test_multi_audio(int devcount)
icculus@2049
    49
{
icculus@2049
    50
    callback_data cbd[64];
icculus@2049
    51
    int keep_going = 1;
icculus@2049
    52
    int i;
gabomdq@9145
    53
    
gabomdq@9145
    54
#ifdef __ANDROID__  
gabomdq@9145
    55
    SDL_Event event;
gabomdq@9145
    56
  
gabomdq@9145
    57
    SDL_CreateWindow("testmultiaudio", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
gabomdq@9145
    58
#endif
icculus@2049
    59
icculus@2049
    60
    if (devcount > 64) {
aschiffler@7639
    61
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n",
slouken@2060
    62
                devcount);
icculus@2049
    63
        devcount = 64;
icculus@2049
    64
    }
icculus@2049
    65
icculus@2049
    66
    spec.callback = play_through_once;
icculus@2049
    67
icculus@2049
    68
    for (i = 0; i < devcount; i++) {
icculus@2049
    69
        const char *devname = SDL_GetAudioDeviceName(i, 0);
aschiffler@7639
    70
        SDL_Log("playing on device #%d: ('%s')...", i, devname);
icculus@2049
    71
        fflush(stdout);
icculus@2049
    72
icculus@2146
    73
        SDL_memset(&cbd[0], '\0', sizeof(callback_data));
icculus@2049
    74
        spec.userdata = &cbd[0];
slouken@2867
    75
        cbd[0].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
icculus@2049
    76
        if (cbd[0].dev == 0) {
aschiffler@7639
    77
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError());
icculus@2049
    78
        } else {
icculus@2049
    79
            SDL_PauseAudioDevice(cbd[0].dev, 0);
gabomdq@9145
    80
            while (!cbd[0].done) {
gabomdq@9145
    81
#ifdef __ANDROID__                
gabomdq@9145
    82
                while (SDL_PollEvent(&event)){}
gabomdq@9145
    83
#endif                
icculus@2049
    84
                SDL_Delay(100);
gabomdq@9145
    85
            }
icculus@2049
    86
            SDL_PauseAudioDevice(cbd[0].dev, 1);
aschiffler@7639
    87
            SDL_Log("done.\n");
icculus@2049
    88
            SDL_CloseAudioDevice(cbd[0].dev);
icculus@2049
    89
        }
icculus@2049
    90
    }
icculus@2049
    91
icculus@2146
    92
    SDL_memset(cbd, '\0', sizeof(cbd));
icculus@2049
    93
aschiffler@7639
    94
    SDL_Log("playing on all devices...\n");
icculus@2049
    95
    for (i = 0; i < devcount; i++) {
icculus@2049
    96
        const char *devname = SDL_GetAudioDeviceName(i, 0);
icculus@2049
    97
        spec.userdata = &cbd[i];
slouken@2867
    98
        cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0);
icculus@2049
    99
        if (cbd[i].dev == 0) {
aschiffler@7639
   100
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError());
icculus@2049
   101
        }
icculus@2049
   102
    }
icculus@2049
   103
icculus@2049
   104
    for (i = 0; i < devcount; i++) {
icculus@2049
   105
        if (cbd[i].dev) {
icculus@2049
   106
            SDL_PauseAudioDevice(cbd[i].dev, 0);
icculus@2049
   107
        }
icculus@2049
   108
    }
icculus@2049
   109
icculus@2049
   110
    while (keep_going) {
icculus@2049
   111
        keep_going = 0;
icculus@2049
   112
        for (i = 0; i < devcount; i++) {
icculus@2049
   113
            if ((cbd[i].dev) && (!cbd[i].done)) {
icculus@2049
   114
                keep_going = 1;
icculus@2049
   115
            }
icculus@2049
   116
        }
gabomdq@9145
   117
#ifdef __ANDROID__        
gabomdq@9145
   118
        while (SDL_PollEvent(&event)){}
gabomdq@9145
   119
#endif        
icculus@2049
   120
        SDL_Delay(100);
icculus@2049
   121
    }
icculus@2049
   122
icculus@2049
   123
    for (i = 0; i < devcount; i++) {
icculus@2049
   124
        if (cbd[i].dev) {
icculus@2049
   125
            SDL_PauseAudioDevice(cbd[i].dev, 1);
icculus@2049
   126
            SDL_CloseAudioDevice(cbd[i].dev);
icculus@2049
   127
        }
icculus@2049
   128
    }
icculus@2049
   129
aschiffler@7639
   130
    SDL_Log("All done!\n");
icculus@2049
   131
}
icculus@2049
   132
icculus@2049
   133
slouken@2060
   134
int
slouken@2060
   135
main(int argc, char **argv)
icculus@2049
   136
{
icculus@2049
   137
    int devcount = 0;
icculus@2049
   138
aschiffler@7639
   139
	/* Enable standard application logging */
aschiffler@7639
   140
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   141
icculus@2049
   142
    /* Load the SDL library */
icculus@2049
   143
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
aschiffler@7639
   144
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
icculus@2049
   145
        return (1);
icculus@2049
   146
    }
icculus@2049
   147
aschiffler@7639
   148
    SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
gabomdq@8834
   149
    
icculus@2049
   150
    devcount = SDL_GetNumAudioDevices(0);
icculus@2049
   151
    if (devcount < 1) {
aschiffler@7639
   152
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
icculus@2049
   153
    } else {
icculus@2049
   154
        if (argv[1] == NULL) {
icculus@2049
   155
            argv[1] = "sample.wav";
icculus@2049
   156
        }
icculus@2049
   157
icculus@2049
   158
        /* Load the wave file into memory */
icculus@2049
   159
        if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) {
aschiffler@7639
   160
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1],
slouken@2060
   161
                    SDL_GetError());
icculus@2049
   162
        } else {
icculus@2049
   163
            test_multi_audio(devcount);
icculus@2049
   164
            SDL_FreeWAV(sound);
icculus@2049
   165
        }
icculus@2049
   166
    }
icculus@2049
   167
icculus@2049
   168
    SDL_Quit();
icculus@2049
   169
    return 0;
icculus@2049
   170
}