main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*================================================================
  2. * Copyright: 2020 John Jackson
  3. * simple_audio
  4. Simple audio example. Demonstrates how to load raw audio data
  5. from disk (.mp3), construct an internal resource and then
  6. use audio instances to play audio at runtime.
  7. Demonstrates how to play, pause, restart, stop, control volume
  8. of audio, as well as get runtime data for the playing instance.
  9. Press `esc` to exit the application.
  10. =================================================================*/
  11. #include <gs.h>
  12. // Forward Decls.
  13. gs_result app_init(); // Use to init your application
  14. gs_result app_update(); // Use to update your application
  15. // Resource handles for internal audio data. Since audio must run on a separate thread, this is necessary.
  16. gs_global gs_resource(gs_audio_source_t) g_src = {0};
  17. gs_global gs_handle_audio_instance g_inst = {0};
  18. int main(int argc, char** argv)
  19. {
  20. // This is our app description. It gives internal hints to our engine for various things like
  21. // window size, title, as well as update, init, and shutdown functions to be run.
  22. gs_application_desc_t app = {0};
  23. app.window_title = "Simple Audio";
  24. app.window_width = 800;
  25. app.window_height = 600;
  26. app.init = &app_init;
  27. app.update = &app_update;
  28. // Construct internal instance of our engine
  29. gs_result res = gs_engine_construct(app)->run();
  30. // Check result of engine after exiting loop
  31. if (res != gs_result_success)
  32. {
  33. gs_println("Error: Engine did not successfully finish running.");
  34. return -1;
  35. }
  36. gs_println("Gunslinger exited successfully.");
  37. return 0;
  38. }
  39. gs_result app_init()
  40. {
  41. // Cache apis
  42. gs_platform_i* platform = gs_engine_subsystem(platform);
  43. gs_audio_i* audio = gs_engine_subsystem(audio);
  44. // Constuct audio resource to play
  45. g_src = audio->load_audio_source_from_file(platform->file_exists("./assets/cold_morning_tx.mp3") ?
  46. "./assets/cold_morning_tx.mp3" : "./../assets/cold_morning_tx.mp3");
  47. // Construct instance source and play on loop. Forever.
  48. // Fill out instance data to pass into audio subsystem
  49. gs_audio_instance_data_t inst = gs_audio_instance_data_new(g_src);
  50. inst.volume = 0.8f; // Range from [0.f, 1.f]
  51. inst.loop = true; // Tell whether or not audio should loop
  52. inst.persistent = true; // Whether or not instance should stick in memory after completing, if not then will be cleared from memory
  53. g_inst = audio->construct_instance(inst);
  54. audio->play(g_inst);
  55. return gs_result_success;
  56. }
  57. gs_result app_update()
  58. {
  59. // Cache necessary APIs
  60. gs_platform_i* platform = gs_engine_instance()->ctx.platform;
  61. gs_audio_i* audio = gs_engine_instance()->ctx.audio;
  62. if (platform->key_pressed(gs_keycode_esc))
  63. {
  64. return gs_result_success;
  65. }
  66. if (platform->key_pressed(gs_keycode_p))
  67. {
  68. if (audio->is_playing(g_inst))
  69. {
  70. audio->pause(g_inst);
  71. }
  72. else
  73. {
  74. audio->play(g_inst);
  75. }
  76. }
  77. // Restart instance
  78. if (platform->key_pressed(gs_keycode_r))
  79. {
  80. audio->restart(g_inst);
  81. }
  82. // Stop audio (sets position back to beginning)
  83. if (platform->key_pressed(gs_keycode_s))
  84. {
  85. audio->stop(g_inst);
  86. }
  87. // Volume up
  88. if (platform->key_pressed(gs_keycode_up))
  89. {
  90. f32 cur_vol = audio->get_volume(g_inst);
  91. audio->set_volume(g_inst, cur_vol + 0.1f);
  92. }
  93. // Volume down
  94. if (platform->key_pressed(gs_keycode_down))
  95. {
  96. f32 cur_vol = audio->get_volume(g_inst);
  97. audio->set_volume(g_inst, cur_vol - 0.1f);
  98. }
  99. // Can grab current runtime instance data as well
  100. gs_audio_instance_data_t id = audio->get_instance_data(g_inst);
  101. s32 sample_count = audio->get_sample_count(id.src);
  102. s32 sample_rate = audio->get_sample_rate(id.src);
  103. s32 num_channels = audio->get_num_channels(id.src);
  104. gs_timed_action(10,
  105. {
  106. s32 min, sec;
  107. char buf[256] = gs_default_val();
  108. // Runtime of source
  109. audio->get_runtime(g_src, &min, &sec);
  110. gs_snprintf(buf, 256, sec < 10 ? "%d:0%d" : "%d:%d", min, sec);
  111. gs_println("Runtime: %s", buf);
  112. // Get current play position
  113. audio->convert_to_runtime(sample_count, sample_rate,
  114. num_channels, id.sample_position, &min, &sec);
  115. gs_snprintf(buf, 256, sec < 10 ? "%d:0%d" : "%d:%d", min, sec);
  116. gs_println("Play Time: %s", buf);
  117. });
  118. return gs_result_in_progress;
  119. }