You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
6.6KB

  1. //=======================================================================
  2. /** @file AudioFile.h
  3. * @author Adam Stark
  4. * @copyright Copyright (C) 2017 Adam Stark
  5. *
  6. * This file is part of the 'AudioFile' library
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. //=======================================================================
  22. #ifndef _AS_AudioFile_h
  23. #define _AS_AudioFile_h
  24. #include <iostream>
  25. #include <vector>
  26. #include <assert.h>
  27. #include <string>
  28. //=============================================================
  29. /** The different types of audio file, plus some other types to
  30. * indicate a failure to load a file, or that one hasn't been
  31. * loaded yet
  32. */
  33. enum class AudioFileFormat
  34. {
  35. Error,
  36. NotLoaded,
  37. Wave,
  38. Aiff
  39. };
  40. //=============================================================
  41. template <class T>
  42. class AudioFile
  43. {
  44. public:
  45. //=============================================================
  46. typedef std::vector<std::vector<T> > AudioBuffer;
  47. //=============================================================
  48. /** Constructor */
  49. AudioFile();
  50. //=============================================================
  51. /** Loads an audio file from a given file path.
  52. * @Returns true if the file was successfully loaded
  53. */
  54. bool load (std::string filePath);
  55. /** Saves an audio file to a given file path.
  56. * @Returns true if the file was successfully saved
  57. */
  58. bool save (std::string filePath, AudioFileFormat format = AudioFileFormat::Wave);
  59. //=============================================================
  60. /** @Returns the sample rate */
  61. uint32_t getSampleRate() const;
  62. /** @Returns the number of audio channels in the buffer */
  63. int getNumChannels() const;
  64. /** @Returns true if the audio file is mono */
  65. bool isMono() const;
  66. /** @Returns true if the audio file is stereo */
  67. bool isStereo() const;
  68. /** @Returns the bit depth of each sample */
  69. int getBitDepth() const;
  70. /** @Returns the number of samples per channel */
  71. int getNumSamplesPerChannel() const;
  72. /** @Returns the length in seconds of the audio file based on the number of samples and sample rate */
  73. double getLengthInSeconds() const;
  74. /** Prints a summary of the audio file to the console */
  75. void printSummary() const;
  76. //=============================================================
  77. /** Set the audio buffer for this AudioFile by copying samples from another buffer.
  78. * @Returns true if the buffer was copied successfully.
  79. */
  80. bool setAudioBuffer (AudioBuffer& newBuffer);
  81. /** Sets the audio buffer to a given number of channels and number of samples per channel. This will try to preserve
  82. * the existing audio, adding zeros to any new channels or new samples in a given channel.
  83. */
  84. void setAudioBufferSize (int numChannels, int numSamples);
  85. /** Sets the number of samples per channel in the audio buffer. This will try to preserve
  86. * the existing audio, adding zeros to new samples in a given channel if the number of samples is increased.
  87. */
  88. void setNumSamplesPerChannel (int numSamples);
  89. /** Sets the number of channels. New channels will have the correct number of samples and be initialised to zero */
  90. void setNumChannels (int numChannels);
  91. /** Sets the bit depth for the audio file. If you use the save() function, this bit depth rate will be used */
  92. void setBitDepth (int numBitsPerSample);
  93. /** Sets the sample rate for the audio file. If you use the save() function, this sample rate will be used */
  94. void setSampleRate (uint32_t newSampleRate);
  95. //=============================================================
  96. /** A vector of vectors holding the audio samples for the AudioFile. You can
  97. * access the samples by channel and then by sample index, i.e:
  98. *
  99. * samples[channel][sampleIndex]
  100. */
  101. AudioBuffer samples;
  102. private:
  103. //=============================================================
  104. enum class Endianness
  105. {
  106. LittleEndian,
  107. BigEndian
  108. };
  109. //=============================================================
  110. AudioFileFormat determineAudioFileFormat (std::vector<uint8_t>& fileData);
  111. bool decodeWaveFile (std::vector<uint8_t>& fileData);
  112. bool decodeAiffFile (std::vector<uint8_t>& fileData);
  113. //=============================================================
  114. bool saveToWaveFile (std::string filePath);
  115. bool saveToAiffFile (std::string filePath);
  116. //=============================================================
  117. void clearAudioBuffer();
  118. //=============================================================
  119. int32_t fourBytesToInt (std::vector<uint8_t>& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
  120. int16_t twoBytesToInt (std::vector<uint8_t>& source, int startIndex, Endianness endianness = Endianness::LittleEndian);
  121. int getIndexOfString (std::vector<uint8_t>& source, std::string s);
  122. T sixteenBitIntToSample (int16_t sample);
  123. uint32_t getAiffSampleRate (std::vector<uint8_t>& fileData, int sampleRateStartIndex);
  124. bool tenByteMatch (std::vector<uint8_t>& v1, int startIndex1, std::vector<uint8_t>& v2, int startIndex2);
  125. void addSampleRateToAiffData (std::vector<uint8_t>& fileData, uint32_t sampleRate);
  126. //=============================================================
  127. void addStringToFileData (std::vector<uint8_t>& fileData, std::string s);
  128. void addInt32ToFileData (std::vector<uint8_t>& fileData, int32_t i, Endianness endianness = Endianness::LittleEndian);
  129. void addInt16ToFileData (std::vector<uint8_t>& fileData, int16_t i, Endianness endianness = Endianness::LittleEndian);
  130. //=============================================================
  131. bool writeDataToFile (std::vector<uint8_t>& fileData, std::string filePath);
  132. //=============================================================
  133. AudioFileFormat audioFileFormat;
  134. uint32_t sampleRate;
  135. int bitDepth;
  136. };
  137. #endif /* AudioFile_h */