Sound.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include "Sound.h"
  2. #include <iostream>
  3. #include <windows.h>
  4. #include <al.h>
  5. Sound::Sound(const char* inWavPath, bool inLooping):
  6. buffer_id(0),
  7. source_id(0),
  8. is_looping(inLooping)
  9. {
  10. isPlaying = false;
  11. const char* path = inWavPath;
  12. FILE *fp = fopen(path, "rb"); // Open the WAVE file
  13. if (!fp)
  14. return; // Could not open file
  15. // Check that the WAVE file is OK
  16. char type[4];
  17. fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file
  18. if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF"
  19. return; // Not RIFF
  20. DWORD size;
  21. fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file
  22. fread(type, sizeof(char), 4, fp); // Continue to read the file
  23. if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') // This part should be "WAVE"
  24. return; // Not WAVE
  25. fread(type, sizeof(char), 4, fp); // Continue to read the file
  26. if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') // This part should be "fmt "
  27. return; // Not fmt
  28. // Now we know that the file is a acceptable WAVE file
  29. // Info about the WAVE data is now read and stored
  30. DWORD chunkSize;
  31. fread(&chunkSize, sizeof(DWORD), 1, fp);
  32. short formatType;
  33. fread(&formatType, sizeof(short), 1, fp);
  34. short channels;
  35. fread(&channels, sizeof(short), 1, fp);
  36. DWORD sampleRate;
  37. fread(&sampleRate, sizeof(DWORD), 1, fp);
  38. DWORD avgBytesPerSec;
  39. fread(&avgBytesPerSec, sizeof(DWORD), 1, fp);
  40. short bytesPerSample;
  41. fread(&bytesPerSample, sizeof(short), 1, fp);
  42. short bitsPerSample;
  43. fread(&bitsPerSample, sizeof(short), 1, fp);
  44. ALenum format = 0; // The audio format (bits per sample, number of channels)
  45. if (bitsPerSample == 8)
  46. {
  47. if (channels == 1)
  48. format = AL_FORMAT_MONO8;
  49. else if (channels == 2)
  50. format = AL_FORMAT_STEREO8;
  51. }
  52. else if (bitsPerSample == 16)
  53. {
  54. if (channels == 1)
  55. format = AL_FORMAT_MONO16;
  56. else if (channels == 2)
  57. format = AL_FORMAT_STEREO16;
  58. }
  59. if (!format)
  60. return; // Not valid format
  61. fread(type, sizeof(char), 4, fp);
  62. if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') // This part should be "data"
  63. return; // not data
  64. DWORD dataSize;
  65. fread(&dataSize, sizeof(DWORD), 1, fp); // The size of the sound data is read
  66. // Display the info about the WAVE file
  67. std::cout << "Chunk Size: " << chunkSize << "\n";
  68. std::cout << "Format Type: " << formatType << "\n";
  69. std::cout << "Channels: " << channels << "\n";
  70. std::cout << "Sample Rate: " << sampleRate << "\n";
  71. std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n";
  72. std::cout << "Bytes Per Sample: " << bytesPerSample << "\n";
  73. std::cout << "Bits Per Sample: " << bitsPerSample << "\n";
  74. std::cout << "Data Size: " << dataSize << "\n";
  75. unsigned char* buf = new unsigned char[dataSize]; // Allocate memory for the sound data
  76. std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; // Read the sound data and display the
  77. fclose(fp);
  78. alGenBuffers(1, &buffer_id); // Generate one OpenAL Buffer and link to "buffer"
  79. alGenSources(1, &source_id); // Generate one OpenAL Source and link to "source"
  80. if (alGetError() != AL_NO_ERROR)
  81. return; // Error during buffer/source generation
  82. alBufferData(buffer_id, format, buf, dataSize, sampleRate); // Store the sound data in the OpenAL Buffer
  83. if (alGetError() != AL_NO_ERROR)
  84. return; // Error during buffer loading
  85. delete[] buf; // Delete the sound data buffer
  86. }
  87. Sound::~Sound()
  88. {
  89. alSourceStop(source_id);
  90. alDeleteSources(1, &source_id); // Delete the OpenAL Source
  91. alDeleteBuffers(1, &buffer_id); // Delete the OpenAL Buffer
  92. }
  93. void Sound::SetPos(const Vec3f& inPos, const Vec3f& inVel)
  94. {
  95. alSourcei(source_id, AL_BUFFER, buffer_id); // Link the buffer to the source
  96. alSourcef(source_id, AL_PITCH, 1.0f); // Set the pitch of the source
  97. alSourcef(source_id, AL_GAIN, 1.0f); // Set the gain of the source
  98. alSourcefv(source_id, AL_POSITION, inPos.v); // Set the position of the source
  99. alSourcefv(source_id, AL_VELOCITY, inVel.v); // Set the velocity of the source
  100. alSourcei(source_id, AL_LOOPING, is_looping ? AL_TRUE : AL_FALSE); // Set if source is looping sound
  101. }
  102. void Sound::Play()
  103. {
  104. isPlaying = true;
  105. alSourcePlay(source_id);
  106. int e = alGetError(); // != AL_NO_ERROR) return;
  107. }
  108. void Sound::Pause()
  109. {
  110. alSourcePause(source_id);
  111. }
  112. void Sound::Stop()
  113. {
  114. isPlaying = false;
  115. alSourceStop(source_id);
  116. }
  117. bool Sound::IsPlaying()
  118. {
  119. return isPlaying;
  120. }