Skip to content

Instantly share code, notes, and snippets.

@take-cheeze
Created December 7, 2012 13:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save take-cheeze/4233185 to your computer and use it in GitHub Desktop.
Save take-cheeze/4233185 to your computer and use it in GitHub Desktop.
libsndfile and OpenAL test
/*
TO compile:
ccache g++ -Wall -Wextra -pipe -lsndfile -lopenal -lboost_chrono -lboost_system -lboost_thread libsndfile_test.cxx
TO run:
./a.out $AUDIO_FILE
*/
#include <sndfile.h>
#include <AL/al.h>
#include <AL/alc.h>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/array.hpp>
#include <boost/shared_ptr.hpp>
int main(int argc, char **argv) {
assert(argc == 2);
SF_INFO info;
SNDFILE* file = sf_open(argv[1], SFM_READ, &info);
assert(file);
std::vector<uint16_t> data;
boost::array<int16_t, 4096> read_buf;
size_t read_size = 0;
while((read_size = sf_read_short(file, read_buf.data(), read_buf.size())) != 0) {
data.insert(data.end(), read_buf.begin(), read_buf.begin() + read_size);
}
boost::shared_ptr<ALCdevice> dev(alcOpenDevice(NULL), &alcCloseDevice);
ALCcontext* ctx = alcCreateContext(dev.get(), NULL);
alcMakeContextCurrent(ctx);
ALuint buf, src;
alGenSources(1, &src);
alGenBuffers(1, &buf);
assert(src != AL_INVALID_VALUE && buf != AL_INVALID_VALUE);
assert(alGetError() == AL_NO_ERROR);
std::cout << "channel number: " << info.channels << std::endl;
ALfloat const PITCH = 10.0f;
alBufferData(buf, info.channels == 1? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
&data.front(), data.size() * sizeof(uint16_t), info.samplerate);
alSourcei(src, AL_BUFFER, buf);
// alSourcei(src, AL_LOOPING, AL_TRUE);
alSourcef(src, AL_PITCH, PITCH);
alSourcePlay(src);
int loop_count = 0;
using namespace boost::chrono;
milliseconds const loop_interval(100);
while(true) {
boost::this_thread::sleep_for(loop_interval);
ALint state;
alGetSourcei(src, AL_SOURCE_STATE, &state);
if(state != AL_PLAYING) {
std::cout
<< "playing ended. restarting" << std::endl
<< "time from start: "
<< duration_cast<seconds>(loop_interval * loop_count * PITCH) << std::endl
<< "realtime from start: "
<< duration_cast<seconds>(loop_interval * loop_count) << std::endl
;
alSourcePlay(src);
}
loop_count++;
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment