test/testaudiocapture.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
icculus@10231
     1
/*
slouken@10737
     2
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
icculus@10231
     3
icculus@10231
     4
  This software is provided 'as-is', without any express or implied
icculus@10231
     5
  warranty.  In no event will the authors be held liable for any damages
icculus@10231
     6
  arising from the use of this software.
icculus@10231
     7
icculus@10231
     8
  Permission is granted to anyone to use this software for any purpose,
icculus@10231
     9
  including commercial applications, and to alter it and redistribute it
icculus@10231
    10
  freely.
icculus@10231
    11
*/
icculus@10231
    12
#include "SDL.h"
icculus@10231
    13
icculus@10272
    14
#include <stdlib.h>
icculus@10272
    15
icculus@10231
    16
#ifdef __EMSCRIPTEN__
icculus@10231
    17
#include <emscripten/emscripten.h>
icculus@10231
    18
#endif
icculus@10231
    19
icculus@10244
    20
static SDL_Window *window = NULL;
icculus@10244
    21
static SDL_Renderer *renderer = NULL;
icculus@10231
    22
static SDL_AudioSpec spec;
icculus@10246
    23
static SDL_AudioDeviceID devid_in = 0;
icculus@10246
    24
static SDL_AudioDeviceID devid_out = 0;
icculus@10231
    25
icculus@10231
    26
static void
icculus@10231
    27
loop()
icculus@10231
    28
{
icculus@10246
    29
    SDL_bool please_quit = SDL_FALSE;
icculus@10231
    30
    SDL_Event e;
icculus@10231
    31
icculus@10231
    32
    while (SDL_PollEvent(&e)) {
icculus@10231
    33
        if (e.type == SDL_QUIT) {
icculus@10231
    34
            please_quit = SDL_TRUE;
icculus@10246
    35
        } else if (e.type == SDL_KEYDOWN) {
icculus@10246
    36
            if (e.key.keysym.sym == SDLK_ESCAPE) {
icculus@10246
    37
                please_quit = SDL_TRUE;
icculus@10246
    38
            }
icculus@10246
    39
        } else if (e.type == SDL_MOUSEBUTTONDOWN) {
icculus@10246
    40
            if (e.button.button == 1) {
icculus@10246
    41
                SDL_PauseAudioDevice(devid_out, SDL_TRUE);
icculus@10246
    42
                SDL_PauseAudioDevice(devid_in, SDL_FALSE);
icculus@10246
    43
            }
icculus@10246
    44
        } else if (e.type == SDL_MOUSEBUTTONUP) {
icculus@10246
    45
            if (e.button.button == 1) {
icculus@10246
    46
                SDL_PauseAudioDevice(devid_in, SDL_TRUE);
icculus@10246
    47
                SDL_PauseAudioDevice(devid_out, SDL_FALSE);
icculus@10246
    48
            }
icculus@10231
    49
        }
icculus@10231
    50
    }
icculus@10231
    51
icculus@10246
    52
    if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) {
icculus@10244
    53
        SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
icculus@10244
    54
    } else {
icculus@10244
    55
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
icculus@10244
    56
    }
icculus@10244
    57
    SDL_RenderClear(renderer);
icculus@10244
    58
    SDL_RenderPresent(renderer);
icculus@10231
    59
icculus@10231
    60
    if (please_quit) {
icculus@10231
    61
        /* stop playing back, quit. */
icculus@10231
    62
        SDL_Log("Shutting down.\n");
icculus@10246
    63
        SDL_PauseAudioDevice(devid_in, 1);
icculus@10246
    64
        SDL_CloseAudioDevice(devid_in);
icculus@10246
    65
        SDL_PauseAudioDevice(devid_out, 1);
icculus@10246
    66
        SDL_CloseAudioDevice(devid_out);
icculus@10246
    67
        SDL_DestroyRenderer(renderer);
icculus@10246
    68
        SDL_DestroyWindow(window);
icculus@10231
    69
        SDL_Quit();
icculus@10231
    70
        #ifdef __EMSCRIPTEN__
icculus@10231
    71
        emscripten_cancel_main_loop();
icculus@10231
    72
        #endif
icculus@10231
    73
        exit(0);
icculus@10231
    74
    }
icculus@10263
    75
icculus@10263
    76
    /* Note that it would be easier to just have a one-line function that
icculus@10263
    77
        calls SDL_QueueAudio() as a capture device callback, but we're
icculus@10263
    78
        trying to test the API, so we use SDL_DequeueAudio() here. */
icculus@10263
    79
    while (SDL_TRUE) {
icculus@10263
    80
        Uint8 buf[1024];
icculus@10263
    81
        const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof (buf));
icculus@10263
    82
        SDL_QueueAudio(devid_out, buf, br);
icculus@10263
    83
        if (br < sizeof (buf)) {
icculus@10263
    84
            break;
icculus@10263
    85
        }
icculus@10263
    86
    }
icculus@10231
    87
}
icculus@10231
    88
icculus@10231
    89
int
icculus@10231
    90
main(int argc, char **argv)
icculus@10231
    91
{
icculus@10237
    92
    /* (argv[1] == NULL means "open default device.") */
icculus@10237
    93
    const char *devname = argv[1];
icculus@10272
    94
    SDL_AudioSpec wanted;
icculus@10237
    95
    int devcount;
icculus@10237
    96
    int i;
icculus@10237
    97
icculus@10231
    98
    /* Enable standard application logging */
icculus@10231
    99
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
icculus@10231
   100
icculus@10231
   101
    /* Load the SDL library */
icculus@10231
   102
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
icculus@10231
   103
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
icculus@10231
   104
        return (1);
icculus@10231
   105
    }
icculus@10231
   106
icculus@10261
   107
    window = SDL_CreateWindow("testaudiocapture", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
icculus@10244
   108
    renderer = SDL_CreateRenderer(window, -1, 0);
icculus@10244
   109
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
icculus@10244
   110
    SDL_RenderClear(renderer);
icculus@10244
   111
    SDL_RenderPresent(renderer);
icculus@10231
   112
icculus@10231
   113
    SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
icculus@10231
   114
icculus@10237
   115
    devcount = SDL_GetNumAudioDevices(SDL_TRUE);
icculus@10237
   116
    for (i = 0; i < devcount; i++) {
icculus@10237
   117
        SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE));
icculus@10237
   118
    }
icculus@10237
   119
icculus@10272
   120
    SDL_zero(wanted);
icculus@10272
   121
    wanted.freq = 44100;
icculus@10272
   122
    wanted.format = AUDIO_F32SYS;
icculus@10272
   123
    wanted.channels = 1;
icculus@10285
   124
    wanted.samples = 4096;
icculus@10272
   125
    wanted.callback = NULL;
icculus@10272
   126
icculus@10231
   127
    SDL_zero(spec);
icculus@10272
   128
icculus@10272
   129
    /* DirectSound can fail in some instances if you open the same hardware
icculus@10272
   130
       for both capture and output and didn't open the output end first,
icculus@10272
   131
       according to the docs, so if you're doing something like this, always
icculus@10272
   132
       open your capture devices second in case you land in those bizarre
icculus@10272
   133
       circumstances. */
icculus@10272
   134
icculus@10272
   135
    SDL_Log("Opening default playback device...\n");
icculus@10272
   136
    devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
icculus@10272
   137
    if (!devid_out) {
philipp@10298
   138
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError());
icculus@10272
   139
        SDL_Quit();
icculus@10272
   140
        exit(1);
icculus@10272
   141
    }
icculus@10231
   142
icculus@10246
   143
    SDL_Log("Opening capture device %s%s%s...\n",
icculus@10237
   144
            devname ? "'" : "",
icculus@10237
   145
            devname ? devname : "[[default]]",
icculus@10237
   146
            devname ? "'" : "");
icculus@10237
   147
icculus@10246
   148
    devid_in = SDL_OpenAudioDevice(argv[1], SDL_TRUE, &spec, &spec, 0);
icculus@10246
   149
    if (!devid_in) {
icculus@10231
   150
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError());
icculus@10231
   151
        SDL_Quit();
icculus@10231
   152
        exit(1);
icculus@10231
   153
    }
icculus@10231
   154
icculus@10246
   155
    SDL_Log("Ready! Hold down mouse or finger to record!\n");
icculus@10231
   156
icculus@10231
   157
#ifdef __EMSCRIPTEN__
icculus@10231
   158
    emscripten_set_main_loop(loop, 0, 1);
icculus@10231
   159
#else
icculus@10231
   160
    while (1) { loop(); SDL_Delay(16); }
icculus@10231
   161
#endif
icculus@10231
   162
icculus@10231
   163
    return 0;
icculus@10231
   164
}
icculus@10231
   165