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