Sound.cpp 4.7 KB

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