| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #include "Sound.h"
- #include <iostream>
- #ifdef WIN32
- #include <windows.h>
- #include <al.h>
- #else
- #include <AL/al.h>
- typedef unsigned long DWORD;
- typedef unsigned short WORD;
- typedef unsigned int UNINT32;
- typedef unsigned char BYTE;
- #endif
- Sound::Sound(const char* inWavPath, bool inLooping):
- buffer_id(0),
- source_id(0),
- is_looping(inLooping)
- {
- const char* path = inWavPath;
- FILE *fp = fopen(path, "rb"); // Open the WAVE file
- if (!fp)
- return; // Could not open file
- // Check that the WAVE file is OK
- char type[4];
- fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file
- if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF"
- return; // Not RIFF
- DWORD size;
- fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file
- fread(type, sizeof(char), 4, fp); // Continue to read the file
- if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') // This part should be "WAVE"
- return; // Not WAVE
- fread(type, sizeof(char), 4, fp); // Continue to read the file
- if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') // This part should be "fmt "
- return; // Not fmt
- // Now we know that the file is a acceptable WAVE file
- // Info about the WAVE data is now read and stored
- DWORD chunkSize;
- fread(&chunkSize, sizeof(DWORD), 1, fp);
- short formatType;
- fread(&formatType, sizeof(short), 1, fp);
- short channels;
- fread(&channels, sizeof(short), 1, fp);
- DWORD sampleRate;
- fread(&sampleRate, sizeof(DWORD), 1, fp);
- DWORD avgBytesPerSec;
- fread(&avgBytesPerSec, sizeof(DWORD), 1, fp);
- short bytesPerSample;
- fread(&bytesPerSample, sizeof(short), 1, fp);
- short bitsPerSample;
- fread(&bitsPerSample, sizeof(short), 1, fp);
- ALenum format = 0; // The audio format (bits per sample, number of channels)
- if (bitsPerSample == 8)
- {
- if (channels == 1)
- format = AL_FORMAT_MONO8;
- else if (channels == 2)
- format = AL_FORMAT_STEREO8;
- }
- else if (bitsPerSample == 16)
- {
- if (channels == 1)
- format = AL_FORMAT_MONO16;
- else if (channels == 2)
- format = AL_FORMAT_STEREO16;
- }
- if (!format)
- return; // Not valid format
- fread(type, sizeof(char), 4, fp);
- if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') // This part should be "data"
- return; // not data
- DWORD dataSize;
- fread(&dataSize, sizeof(DWORD), 1, fp); // The size of the sound data is read
- // Display the info about the WAVE file
- std::cout << "Chunk Size: " << chunkSize << "\n";
- std::cout << "Format Type: " << formatType << "\n";
- std::cout << "Channels: " << channels << "\n";
- std::cout << "Sample Rate: " << sampleRate << "\n";
- std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n";
- std::cout << "Bytes Per Sample: " << bytesPerSample << "\n";
- std::cout << "Bits Per Sample: " << bitsPerSample << "\n";
- std::cout << "Data Size: " << dataSize << "\n";
- unsigned char* buf = new unsigned char[dataSize]; // Allocate memory for the sound data
- std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; // Read the sound data and display the
- fclose(fp);
- alGenBuffers(1, &buffer_id); // Generate one OpenAL Buffer and link to "buffer"
- alGenSources(1, &source_id); // Generate one OpenAL Source and link to "source"
- if (alGetError() != AL_NO_ERROR)
- return; // Error during buffer/source generation
- alBufferData(buffer_id, format, buf, dataSize, sampleRate); // Store the sound data in the OpenAL Buffer
- if (alGetError() != AL_NO_ERROR)
- return; // Error during buffer loading
- delete[] buf; // Delete the sound data buffer
- }
- Sound::~Sound()
- {
- alSourceStop(source_id);
- alDeleteSources(1, &source_id); // Delete the OpenAL Source
- alDeleteBuffers(1, &buffer_id); // Delete the OpenAL Buffer
- }
- void Sound::SetPos(const Vec3f& inPos, const Vec3f& inVel)
- {
- alSourcei(source_id, AL_BUFFER, buffer_id); // Link the buffer to the source
- alSourcef(source_id, AL_PITCH, 1.0f); // Set the pitch of the source
- alSourcef(source_id, AL_GAIN, 1.0f); // Set the gain of the source
- alSourcefv(source_id, AL_POSITION, inPos.v); // Set the position of the source
- alSourcefv(source_id, AL_VELOCITY, inVel.v); // Set the velocity of the source
- alSourcei(source_id, AL_LOOPING, is_looping ? AL_TRUE : AL_FALSE); // Set if source is looping sound
- }
- void Sound::Play()
- {
- alSourcePlay(source_id);
- int e = alGetError(); // != AL_NO_ERROR) return;
- }
- void Sound::Pause()
- {
- alSourcePause(source_id);
- }
- void Sound::Stop()
- {
- alSourceStop(source_id);
- }
|