ROOT logo
// $Id: AlBuffer.cxx 2356 2010-02-17 21:59:06Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#include "AlBuffer.h"
#include "AlBuffer.c7"

#include <AL/alut.h>
#include <vorbis/vorbisfile.h>

namespace
{
#ifdef R__BYTESWAP
  static const int slBigEndian = 0;
#else
  static const int slBigEndian = 1;
#endif
}

// AlBuffer

//______________________________________________________________________________
//
//

ClassImp(AlBuffer);

//==============================================================================

void AlBuffer::clear_buffer_props()
{
  mFrequency = mSize = mBits = mChannels = 0;
  mDuration = 0;
}

void AlBuffer::_init()
{
  mAlBuf = 0;
  clear_buffer_props();
}

AlBuffer::AlBuffer(const Text_t* n, const Text_t* t) :
  ZGlass(n, t)
{
  _init();
}

AlBuffer::~AlBuffer()
{
  if (mAlBuf) alDeleteBuffers(1, &mAlBuf);
}

//==============================================================================

void AlBuffer::Load()
{
  static const Exc_t _eh("AlBuffer::Load ");

  if (mAlBuf)
  {
    // !!! Should check use count - the call fails if buffer is still used.
    // !!! But it is not set from AlSource, so think a bit.

    alDeleteBuffers(1, &mAlBuf);
    mAlBuf = 0;
  }

  if (mFile.EndsWith(".wav"))
  {
    mAlBuf = alutCreateBufferFromFile(mFile);
    if (mAlBuf == AL_NONE)
    {
      ISerr(_eh + GForm("Error in alutCreateBufferFromFile: %s\n", alutGetErrorString(alutGetError())));
    }
  }
  else if (mFile.EndsWith(".ogg"))
  {
    FILE *fp = fopen(mFile, "r");
    if (fp)
    {
      OggVorbis_File oggFile;
      int status = ov_open(fp, &oggFile, 0, 0);
      if (status == 0)
      {
	vorbis_info *info = ov_info(&oggFile, -1);
	ogg_int64_t  len = ov_pcm_total(&oggFile, -1) * info->channels * 2;
	UChar_t     *data = new UChar_t[len];

	int          bs    = -1;
	ogg_int64_t  todo  = len;
	UChar_t     *bufpt = data;

	while (todo)
	{
	  long read = ov_read(&oggFile, (char*)bufpt, todo, slBigEndian, 2, 1, &bs);
	  todo  -= read;
	  bufpt += read;
	}

	alGenBuffers(1, &mAlBuf);
	alBufferData(mAlBuf, (info->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data, len, info->rate);

	delete [] data;
	ov_clear(&oggFile);
      }
      else
      {
	const char *err;
	switch (status)
	{
	case OV_EREAD:      err = "A read from media returned an error."; break;
	case OV_ENOTVORBIS: err = "Bitstream does not contain any Vorbis data."; break;
	case OV_EVERSION:   err = "Vorbis version mismatch."; break;
	case OV_EBADHEADER: err = "Invalid Vorbis bitstream header."; break;
	case OV_EFAULT:     err = "Internal logic fault; indicates a bug or heap/stack corruption."; break;
	default:            err = "unknown."; break;
	}
	ISerr(_eh + "Error in OGG ov_open: " + err);
	fclose(fp);
      }
    }
    else
    {
      ISerr(_eh + "Can not open file.");
    }
  }
  else
  {
    ISerr(_eh + "Unknown file-type.");
  }

  if (mAlBuf != AL_NONE)
  {
    alGetBufferi(mAlBuf, AL_FREQUENCY, &mFrequency);
    alGetBufferi(mAlBuf, AL_SIZE,      &mSize);
    alGetBufferi(mAlBuf, AL_BITS,      &mBits);
    alGetBufferi(mAlBuf, AL_CHANNELS,  &mChannels);
    mDuration = (8.0f * mSize) / (mFrequency * mBits * mChannels);
  }
  else
  {
    clear_buffer_props();
  }

  Stamp(FID());
}
 AlBuffer.cxx:1
 AlBuffer.cxx:2
 AlBuffer.cxx:3
 AlBuffer.cxx:4
 AlBuffer.cxx:5
 AlBuffer.cxx:6
 AlBuffer.cxx:7
 AlBuffer.cxx:8
 AlBuffer.cxx:9
 AlBuffer.cxx:10
 AlBuffer.cxx:11
 AlBuffer.cxx:12
 AlBuffer.cxx:13
 AlBuffer.cxx:14
 AlBuffer.cxx:15
 AlBuffer.cxx:16
 AlBuffer.cxx:17
 AlBuffer.cxx:18
 AlBuffer.cxx:19
 AlBuffer.cxx:20
 AlBuffer.cxx:21
 AlBuffer.cxx:22
 AlBuffer.cxx:23
 AlBuffer.cxx:24
 AlBuffer.cxx:25
 AlBuffer.cxx:26
 AlBuffer.cxx:27
 AlBuffer.cxx:28
 AlBuffer.cxx:29
 AlBuffer.cxx:30
 AlBuffer.cxx:31
 AlBuffer.cxx:32
 AlBuffer.cxx:33
 AlBuffer.cxx:34
 AlBuffer.cxx:35
 AlBuffer.cxx:36
 AlBuffer.cxx:37
 AlBuffer.cxx:38
 AlBuffer.cxx:39
 AlBuffer.cxx:40
 AlBuffer.cxx:41
 AlBuffer.cxx:42
 AlBuffer.cxx:43
 AlBuffer.cxx:44
 AlBuffer.cxx:45
 AlBuffer.cxx:46
 AlBuffer.cxx:47
 AlBuffer.cxx:48
 AlBuffer.cxx:49
 AlBuffer.cxx:50
 AlBuffer.cxx:51
 AlBuffer.cxx:52
 AlBuffer.cxx:53
 AlBuffer.cxx:54
 AlBuffer.cxx:55
 AlBuffer.cxx:56
 AlBuffer.cxx:57
 AlBuffer.cxx:58
 AlBuffer.cxx:59
 AlBuffer.cxx:60
 AlBuffer.cxx:61
 AlBuffer.cxx:62
 AlBuffer.cxx:63
 AlBuffer.cxx:64
 AlBuffer.cxx:65
 AlBuffer.cxx:66
 AlBuffer.cxx:67
 AlBuffer.cxx:68
 AlBuffer.cxx:69
 AlBuffer.cxx:70
 AlBuffer.cxx:71
 AlBuffer.cxx:72
 AlBuffer.cxx:73
 AlBuffer.cxx:74
 AlBuffer.cxx:75
 AlBuffer.cxx:76
 AlBuffer.cxx:77
 AlBuffer.cxx:78
 AlBuffer.cxx:79
 AlBuffer.cxx:80
 AlBuffer.cxx:81
 AlBuffer.cxx:82
 AlBuffer.cxx:83
 AlBuffer.cxx:84
 AlBuffer.cxx:85
 AlBuffer.cxx:86
 AlBuffer.cxx:87
 AlBuffer.cxx:88
 AlBuffer.cxx:89
 AlBuffer.cxx:90
 AlBuffer.cxx:91
 AlBuffer.cxx:92
 AlBuffer.cxx:93
 AlBuffer.cxx:94
 AlBuffer.cxx:95
 AlBuffer.cxx:96
 AlBuffer.cxx:97
 AlBuffer.cxx:98
 AlBuffer.cxx:99
 AlBuffer.cxx:100
 AlBuffer.cxx:101
 AlBuffer.cxx:102
 AlBuffer.cxx:103
 AlBuffer.cxx:104
 AlBuffer.cxx:105
 AlBuffer.cxx:106
 AlBuffer.cxx:107
 AlBuffer.cxx:108
 AlBuffer.cxx:109
 AlBuffer.cxx:110
 AlBuffer.cxx:111
 AlBuffer.cxx:112
 AlBuffer.cxx:113
 AlBuffer.cxx:114
 AlBuffer.cxx:115
 AlBuffer.cxx:116
 AlBuffer.cxx:117
 AlBuffer.cxx:118
 AlBuffer.cxx:119
 AlBuffer.cxx:120
 AlBuffer.cxx:121
 AlBuffer.cxx:122
 AlBuffer.cxx:123
 AlBuffer.cxx:124
 AlBuffer.cxx:125
 AlBuffer.cxx:126
 AlBuffer.cxx:127
 AlBuffer.cxx:128
 AlBuffer.cxx:129
 AlBuffer.cxx:130
 AlBuffer.cxx:131
 AlBuffer.cxx:132
 AlBuffer.cxx:133
 AlBuffer.cxx:134
 AlBuffer.cxx:135
 AlBuffer.cxx:136
 AlBuffer.cxx:137
 AlBuffer.cxx:138
 AlBuffer.cxx:139
 AlBuffer.cxx:140
 AlBuffer.cxx:141
 AlBuffer.cxx:142
 AlBuffer.cxx:143
 AlBuffer.cxx:144
 AlBuffer.cxx:145
 AlBuffer.cxx:146
 AlBuffer.cxx:147
 AlBuffer.cxx:148