OpenAL.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "OpenAL.h"
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <windows.h>
  5. #include <al.h>
  6. #include <alc.h>
  7. OpenAL::OpenAL()
  8. {
  9. }
  10. int OpenAL::EndWithError(char* msg)
  11. {
  12. //Display error message in console
  13. int error = 0;
  14. std::cout << msg << "\n";
  15. system("PAUSE");
  16. return error;
  17. }
  18. int OpenAL::playMusic(void) {
  19. //start nieuwe thread
  20. //speel sound;
  21. isPlaying = true;
  22. //Loading of the WAVE file
  23. FILE *fp = NULL; //Create FILE pointer for the WAVE file
  24. fp = fopen("WAVE/Sound.wav", "rb"); //Open the WAVE file
  25. if (!fp) return EndWithError("Failed to open file"); //Could not open file
  26. //Variables to store info about the WAVE file (all of them is not needed for OpenAL)
  27. char type[4];
  28. DWORD size, chunkSize;
  29. short formatType, channels;
  30. DWORD sampleRate, avgBytesPerSec;
  31. short bytesPerSample, bitsPerSample;
  32. DWORD dataSize;
  33. //Check that the WAVE file is OK
  34. fread(type, sizeof(char), 4, fp); //Reads the first bytes in the file
  35. if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') //Should be "RIFF"
  36. return EndWithError("No RIFF"); //Not RIFF
  37. fread(&size, sizeof(DWORD), 1, fp); //Continue to read the file
  38. fread(type, sizeof(char), 4, fp); //Continue to read the file
  39. if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE"
  40. return EndWithError("not WAVE"); //Not WAVE
  41. fread(type, sizeof(char), 4, fp); //Continue to read the file
  42. if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt "
  43. return EndWithError("not fmt "); //Not fmt
  44. //Now we know that the file is a acceptable WAVE file
  45. //Info about the WAVE data is now read and stored
  46. fread(&chunkSize, sizeof(DWORD), 1, fp);
  47. fread(&formatType, sizeof(short), 1, fp);
  48. fread(&channels, sizeof(short), 1, fp);
  49. fread(&sampleRate, sizeof(DWORD), 1, fp);
  50. fread(&avgBytesPerSec, sizeof(DWORD), 1, fp);
  51. fread(&bytesPerSample, sizeof(short), 1, fp);
  52. fread(&bitsPerSample, sizeof(short), 1, fp);
  53. fread(type, sizeof(char), 4, fp);
  54. if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data"
  55. return EndWithError("Missing DATA"); //not data
  56. fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read
  57. //Display the info about the WAVE file
  58. std::cout << "Chunk Size: " << chunkSize << "\n";
  59. std::cout << "Format Type: " << formatType << "\n";
  60. std::cout << "Channels: " << channels << "\n";
  61. std::cout << "Sample Rate: " << sampleRate << "\n";
  62. std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n";
  63. std::cout << "Bytes Per Sample: " << bytesPerSample << "\n";
  64. std::cout << "Bits Per Sample: " << bitsPerSample << "\n";
  65. std::cout << "Data Size: " << dataSize << "\n";
  66. unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data
  67. std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the
  68. //number of bytes loaded.
  69. //Should be the same as the Data Size if OK
  70. //Now OpenAL needs to be initialized
  71. ALCdevice *device; //Create an OpenAL Device
  72. ALCcontext *context; //And an OpenAL Context
  73. device = alcOpenDevice(NULL); //Open the device
  74. if (!device) return EndWithError("no sound device"); //Error during device oening
  75. context = alcCreateContext(device, NULL); //Give the device a context
  76. alcMakeContextCurrent(context); //Make the context the current
  77. if (!context) return EndWithError("no sound context"); //Error during context handeling
  78. ALuint source; //Is the name of source (where the sound come from)
  79. ALuint buffer; //Stores the sound data
  80. ALuint frequency = sampleRate;; //The Sample Rate of the WAVE file
  81. ALenum format = 0; //The audio format (bits per sample, number of channels)
  82. alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer"
  83. alGenSources(1, &source); //Generate one OpenAL Source and link to "source"
  84. if (alGetError() != AL_NO_ERROR) return EndWithError("Error GenSource"); //Error during buffer/source generation
  85. //Figure out the format of the WAVE file
  86. if (bitsPerSample == 8)
  87. {
  88. if (channels == 1)
  89. format = AL_FORMAT_MONO8;
  90. else if (channels == 2)
  91. format = AL_FORMAT_STEREO8;
  92. }
  93. else if (bitsPerSample == 16)
  94. {
  95. if (channels == 1)
  96. format = AL_FORMAT_MONO16;
  97. else if (channels == 2)
  98. format = AL_FORMAT_STEREO16;
  99. }
  100. if (!format) return EndWithError("Wrong BitPerSample"); //Not valid format
  101. alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer
  102. if (alGetError() != AL_NO_ERROR)
  103. return EndWithError("Error loading ALBuffer"); //Error during buffer loading
  104. //Sound setting variables
  105. ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; //Position of the source sound
  106. ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the source sound
  107. ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; //Position of the listener
  108. ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the listener
  109. ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; //Orientation of the listener
  110. //First direction vector, then vector pointing up)
  111. //Listener
  112. alListenerfv(AL_POSITION, ListenerPos); //Set position of the listener
  113. alListenerfv(AL_VELOCITY, ListenerVel); //Set velocity of the listener
  114. alListenerfv(AL_ORIENTATION, ListenerOri); //Set orientation of the listener
  115. //Source
  116. alSourcei(source, AL_BUFFER, buffer); //Link the buffer to the source
  117. alSourcef(source, AL_PITCH, 1.0f); //Set the pitch of the source
  118. alSourcef(source, AL_GAIN, 1.0f); //Set the gain of the source
  119. alSourcefv(source, AL_POSITION, SourcePos); //Set the position of the source
  120. alSourcefv(source, AL_VELOCITY, SourceVel); //Set the velocity of the source
  121. alSourcei(source, AL_LOOPING, AL_FALSE); //Set if source is looping sound
  122. //PLAY
  123. alSourcePlay(source); //Play the sound buffer linked to the source
  124. if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound
  125. system("PAUSE"); //Pause to let the sound play
  126. //Clean-up
  127. fclose(fp); //Close the WAVE file
  128. delete[] buf; //Delete the sound data buffer
  129. alDeleteSources(1, &source); //Delete the OpenAL Source
  130. alDeleteBuffers(1, &buffer); //Delete the OpenAL Buffer
  131. alcMakeContextCurrent(NULL); //Make no context current
  132. alcDestroyContext(context); //Destroy the OpenAL Context
  133. alcCloseDevice(device); //Close the OpenAL Device
  134. isPlaying = false;
  135. return EXIT_SUCCESS;
  136. }
  137. bool OpenAL::isMusicPlaying()
  138. {
  139. return isPlaying;
  140. }
  141. OpenAL::~OpenAL()
  142. {
  143. }