testaudiostreamdynamicresample.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely.
  9. */
  10. /* !!! FIXME: this code is not up to standards for SDL3 test apps. Someone should improve this. */
  11. #include <SDL3/SDL.h>
  12. #include <SDL3/SDL_main.h>
  13. #include <SDL3/SDL_test.h>
  14. #include "testutils.h"
  15. #ifdef __EMSCRIPTEN__
  16. #include <emscripten/emscripten.h>
  17. #endif
  18. #include <stdlib.h>
  19. #define SLIDER_WIDTH_PERC 500.f / 600.f
  20. #define SLIDER_HEIGHT_PERC 100.f / 480.f
  21. static int done;
  22. static SDLTest_CommonState *state;
  23. static int multiplier = 100;
  24. static SDL_FRect slider_area;
  25. static SDL_FRect slider_fill_area;
  26. static SDL_AudioSpec spec;
  27. static SDL_AudioStream *stream;
  28. static Uint8 *audio_buf = NULL;
  29. static Uint32 audio_len = 0;
  30. static void loop(void)
  31. {
  32. int i;
  33. SDL_Event e;
  34. int newmultiplier = multiplier;
  35. while (SDL_PollEvent(&e)) {
  36. SDLTest_CommonEvent(state, &e, &done);
  37. #ifdef __EMSCRIPTEN__
  38. if (done) {
  39. emscripten_cancel_main_loop();
  40. }
  41. #endif
  42. if (e.type == SDL_EVENT_MOUSE_MOTION) {
  43. if (e.motion.state & SDL_BUTTON_LMASK) {
  44. const SDL_FPoint p = { e.motion.x, e.motion.y };
  45. if (SDL_PointInRectFloat(&p, &slider_area)) {
  46. const float w = SDL_roundf(p.x - slider_area.x);
  47. slider_fill_area.w = w;
  48. newmultiplier = ((int) ((w / slider_area.w) * 800.0f)) - 400;
  49. }
  50. }
  51. }
  52. }
  53. if (multiplier != newmultiplier) {
  54. SDL_AudioSpec newspec;
  55. char title[64];
  56. int newfreq = spec.freq;
  57. float scale = 1.0f;
  58. multiplier = newmultiplier;
  59. if (multiplier < 0) {
  60. scale = 100.0f / (100.0f - multiplier);
  61. } else if (multiplier > 0) {
  62. scale = (multiplier + 100.0f) / 100.0f;
  63. }
  64. SDL_snprintf(title, sizeof (title), "Drag the slider: %.2fx speed", scale);
  65. for (i = 0; i < state->num_windows; i++) {
  66. SDL_SetWindowTitle(state->windows[i], title);
  67. }
  68. newfreq = (int) (spec.freq * scale);
  69. /* SDL_Log("newfreq=%d multiplier=%d\n", newfreq, multiplier); */
  70. SDL_memcpy(&newspec, &spec, sizeof (spec));
  71. newspec.freq = newfreq;
  72. SDL_SetAudioStreamFormat(stream, &newspec, NULL);
  73. }
  74. /* keep it looping. */
  75. if (SDL_GetAudioStreamAvailable(stream) < ((int) (audio_len / 2))) {
  76. SDL_PutAudioStreamData(stream, audio_buf, audio_len);
  77. }
  78. for (i = 0; i < state->num_windows; i++) {
  79. SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 255, 255);
  80. SDL_RenderClear(state->renderers[i]);
  81. SDL_SetRenderDrawColor(state->renderers[i], 0, 0, 0, 255);
  82. SDL_RenderFillRect(state->renderers[i], &slider_area);
  83. SDL_SetRenderDrawColor(state->renderers[i], 255, 0, 0, 255);
  84. SDL_RenderFillRect(state->renderers[i], &slider_fill_area);
  85. SDL_RenderPresent(state->renderers[i]);
  86. }
  87. }
  88. int main(int argc, char *argv[])
  89. {
  90. char *filename = NULL;
  91. int i;
  92. int rc;
  93. /* Initialize test framework */
  94. state = SDLTest_CommonCreateState(argv, SDL_INIT_AUDIO | SDL_INIT_VIDEO);
  95. if (state == NULL) {
  96. return 1;
  97. }
  98. /* Enable standard application logging */
  99. SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
  100. /* Parse commandline */
  101. for (i = 1; i < argc;) {
  102. int consumed;
  103. consumed = SDLTest_CommonArg(state, i);
  104. if (!consumed) {
  105. if (!filename) {
  106. filename = argv[i];
  107. consumed = 1;
  108. }
  109. }
  110. if (consumed <= 0) {
  111. static const char *options[] = { "[sample.wav]", NULL };
  112. SDLTest_CommonLogUsage(state, argv[0], options);
  113. exit(1);
  114. }
  115. i += consumed;
  116. }
  117. slider_area.x = state->window_w * (1.f - SLIDER_WIDTH_PERC) / 2;
  118. slider_area.y = state->window_h * (1.f - SLIDER_HEIGHT_PERC) / 2;
  119. slider_area.w = SLIDER_WIDTH_PERC * state->window_w;
  120. slider_area.h = SLIDER_HEIGHT_PERC * state->window_h;
  121. slider_fill_area = slider_area;
  122. slider_fill_area.w /= 2;
  123. /* Load the SDL library */
  124. if (!SDLTest_CommonInit(state)) {
  125. SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
  126. return 1;
  127. }
  128. filename = GetResourceFilename(filename, "sample.wav");
  129. rc = SDL_LoadWAV(filename, &spec, &audio_buf, &audio_len);
  130. SDL_free(filename);
  131. if (rc < 0) {
  132. SDL_Log("Failed to load '%s': %s", filename, SDL_GetError());
  133. SDL_Quit();
  134. return 1;
  135. }
  136. for (i = 0; i < state->num_windows; i++) {
  137. SDL_SetWindowTitle(state->windows[i], "Drag the slider: Normal speed");
  138. }
  139. stream = SDL_CreateAudioStream(&spec, &spec);
  140. SDL_PutAudioStreamData(stream, audio_buf, audio_len);
  141. SDL_BindAudioStream(state->audio_id, stream);
  142. #ifdef __EMSCRIPTEN__
  143. emscripten_set_main_loop(loop, 0, 1);
  144. #else
  145. while (!done) {
  146. loop();
  147. }
  148. #endif
  149. SDL_DestroyAudioStream(stream);
  150. SDL_free(audio_buf);
  151. SDLTest_CommonQuit(state);
  152. SDL_Quit();
  153. return 0;
  154. }