AudioFile.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * AudioFile.cpp
  3. *
  4. * Created on: 6 déc. 2023
  5. * Author: fanch
  6. */
  7. #include "AudioFile.h"
  8. #include <unistd.h>
  9. #include <cstring>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <cstdio>
  13. #include "errors.h"
  14. #include "cmath"
  15. #include "Window.h"
  16. void default_audio_file_option(AudioFileOption* out){
  17. out->time_per_window = 1/30.0; // 30 fps
  18. out->buffer_size = 2<<24; // 32 Mo
  19. }
  20. AudioFile::~AudioFile() {
  21. }
  22. AudioFile::AudioFile(const std::string& filename) {
  23. m_buffer = NULL;
  24. m_buffer_start = m_buffer_end = -1;
  25. m_fd = fopen(filename.c_str(), "r");
  26. if(!m_fd){
  27. std::string err = std::string("Erreur impossible de lire le fichier")+filename+")";
  28. throw FileNotFoundError(err);
  29. }
  30. _init();
  31. }
  32. AudioFile::AudioFile(FILE* fd){
  33. m_buffer = NULL;
  34. m_buffer_start = m_buffer_end = -1;
  35. m_fd = fd;
  36. _init();
  37. }
  38. char* AudioFile::_base_read(size_t size, size_t count, char* buffer){
  39. size_t readed=0;
  40. if((readed=fread(buffer, size, count, m_fd))!=count){
  41. printf("Deamndé : %ld lu %ld\n",size*count, readed );
  42. throw IOError(strerror(errno));
  43. }
  44. return buffer;
  45. }
  46. void AudioFile::_init(){
  47. default_audio_file_option(&m_options);
  48. _base_read(sizeof(m_header), 1, (char*)&m_header);
  49. fseek(m_fd, 0, SEEK_END);
  50. int total = ftell(m_fd) - sizeof(m_header);
  51. m_total_time = total / ((float)m_header.byte_per_sec);
  52. }
  53. int8_t* AudioFile::_bufferize(size_t start){
  54. size_t end = start + m_options.time_per_window * m_header.bit_per_sample * m_header.sample_rate;
  55. const int byte_per_sample = m_header.bit_per_sample>>3;
  56. if(start>=m_buffer_start && start<m_buffer_end && end>=m_buffer_start && end<m_buffer_end){
  57. return &m_buffer[start - m_buffer_start];
  58. }
  59. if(m_buffer) delete[] m_buffer;
  60. m_buffer = new int8_t[m_options.buffer_size];
  61. fseek(m_fd, sizeof(m_header) + start, SEEK_SET);
  62. int to_read = m_options.buffer_size/byte_per_sample;
  63. if(start+to_read > m_header.data_size){
  64. to_read = m_header.data_size-start;
  65. }
  66. fread(m_buffer, byte_per_sample, m_options.buffer_size/byte_per_sample, m_fd);
  67. return m_buffer;
  68. }
  69. Window** AudioFile::window_at_time(float time) {
  70. if(time>m_total_time) return NULL;
  71. Window** windows = new Window*[m_header.channels];
  72. size_t sample_per_window = m_options.time_per_window * m_header.bit_per_sample * m_header.sample_rate;
  73. for(size_t i=0; i<m_header.channels; i++)
  74. windows[i] = new Window(this, sample_per_window);
  75. size_t sample_size = m_header.bit_per_sample >> 3;
  76. size_t start = sample_size * m_header.sample_rate * m_header.channels * time;
  77. printf("For time %f offset = %ld + %ld\n", time, sizeof(m_header), start);
  78. int8_t* buffer = _bufferize(start);
  79. for(size_t i=0; i<sample_per_window; i++){
  80. for(size_t channel=0; channel<m_header.channels; channel++){
  81. windows[channel]->data[i] = _val_to_float(buffer+(i*m_header.channels+channel)*sample_size, sample_size);
  82. }
  83. }
  84. return windows;
  85. }
  86. Window* AudioFile::window_channel_at_time(float time, int ch) {
  87. if(time>m_total_time) return NULL;
  88. size_t sample_per_window = m_options.time_per_window * m_header.bit_per_sample * m_header.sample_rate;
  89. Window* windows = new Window(this, sample_per_window);
  90. size_t sample_size = m_header.bit_per_sample >> 3;
  91. size_t start = sample_size * m_header.sample_rate * m_header.channels * time;
  92. printf("For time %f offset = %ld + %ld\n", time, sizeof(m_header), start);
  93. int8_t* buffer = _bufferize(start);
  94. for(size_t i=0; i<sample_per_window; i++){
  95. for(size_t channel=0; channel<m_header.channels; channel++){
  96. if(channel != (uint8_t)ch) continue;
  97. windows->data[i] = _val_to_float(buffer+(i*m_header.channels+channel)*sample_size, sample_size);
  98. }
  99. }
  100. return windows;
  101. }