a418d123c4bf35f1e27cc5b0df13d92dcb206b78
[platform/upstream/SDL.git] / test / testaudiocapture.c
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