Sound.cpp 4.6 KB

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