02_play_raw.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include <cstdio>
  2. #include <cstdint>
  3. #include <cerrno>
  4. #include <thread>
  5. #include <chrono>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <atomic>
  9. #include <vector>
  10. #include <iterator>
  11. #include <string>
  12. #include "simple/support/misc.hpp"
  13. #include "simple/musical/initializer.h"
  14. #include "simple/musical/device.h"
  15. using namespace simple::musical;
  16. using namespace std::literals;
  17. int main(int argc, const char** argv) try
  18. {
  19. switch(argc)
  20. {
  21. case 0: std::puts("command not specified??");
  22. case 1: std::puts("file not specified");
  23. case 2: std::puts("format not specified");
  24. case 3: std::puts("channels not specified");
  25. case 4: std::puts("frequency not specified");
  26. // case 5: std::puts("layout not specified"); // TODO
  27. return -1;
  28. }
  29. initializer init;
  30. auto file = fopen(argv[1], "r");
  31. std::fseek(file, 0, SEEK_END);
  32. const std::size_t filesize = std::ftell(file);
  33. std::vector<std::uint8_t> input(filesize);
  34. std::fseek(file, 0, SEEK_SET);
  35. std::fread(input.data(), 1, input.size(), file);
  36. fclose(file);
  37. std::atomic<bool> done = false;
  38. device_with_callback player
  39. (
  40. basic_device_parameters{ spec{
  41. simple::support::ston<int>(argv[4]),
  42. format_from_c_str(argv[2]),
  43. static_cast<spec::channels>(simple::support::ston<std::uint8_t>(argv[3]))
  44. }},
  45. [&done, &input, i = input.begin()](auto& device, auto buffer) mutable
  46. {
  47. const int remaining = input.end() - i;
  48. const int buffer_size = buffer.end() - buffer.begin();
  49. const int size = std::min<int>(remaining, buffer_size);
  50. const int extra = buffer_size - size;
  51. std::copy(i, i + size, buffer.begin());
  52. std::fill_n(buffer.begin() + size, extra, device.silence());
  53. i += size;
  54. if(i == input.end())
  55. done = true;
  56. }
  57. );
  58. player.play();
  59. while(!done)
  60. std::this_thread::sleep_for(50ms);
  61. return 0;
  62. }
  63. catch(...)
  64. {
  65. if(errno)
  66. std::perror("ERROR");
  67. const char* sdl_error = SDL_GetError();
  68. if(*sdl_error)
  69. std::puts(sdl_error);
  70. throw;
  71. }