ROOT logo
// $Id: AlSource.cxx 2340 2010-01-20 21:53:31Z 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 "AlSource.h"
#include "AlBuffer.h"
#include "AlSource.c7"

#include <Audio1/Audio1.h>

#include <AL/alut.h>

#include <TSystem.h>

//__________________________________________________________________________
// AlSource
//
// mLocationType determines how the source will be placed into scene.
//   LT_FollowParents - Transformation along the parents will be done into the
//                      global coordinate system [default].
//   LT_CamDelta      - Transformation matrix of the source will be taken as relative
//                      to the camera. This is useful to place sources around the
//                      listener in Camera mode.

ClassImp(AlSource);

/**************************************************************************/

void AlSource::_init()
{
  mLocationType = LT_FollowParents;

  mGain    = 1;
  mMinGain = 0;
  mMaxGain = 1;
  mPitch   = 1;

  mConeInnerAngle = 360;
  mConeOuterAngle = 360;
  mConeOuterGain  = 0;

  alGenSources(1, &mAlSrc);
  EmitSourceRay();
  EmitConeRay();
}

AlSource::~AlSource()
{
  if (mAlSrc) alDeleteSources(1, &mAlSrc);
}

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

Bool_t AlSource::IsPlaying()
{
  ALint state = AL_INITIAL;
  alGetSourceiv(mAlSrc, AL_SOURCE_STATE, &state);
  return state == AL_PLAYING || state == AL_PAUSED;
}

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

void AlSource::QueueBuffer(AlBuffer* buf, Int_t count)
{
  static const Exc_t _eh("AlSource::QueueBuffer ");

  if (buf == 0)
    buf = *mDefaultBuffer;

  UInt_t al_buf = 0;
  if (buf != 0)
    al_buf = buf->GetAlBuf();

  while (--count >= 0)
    alSourceQueueBuffers(mAlSrc, 1, &al_buf);

  Audio1::CheckAlError(_eh);
}

void AlSource::UnqueueBuffers(Int_t count)
{
  static const Exc_t _eh("AlSource::UnqueueBuffers ");

  int np;
  alGetSourcei(mAlSrc, AL_BUFFERS_PROCESSED, &np);
  if (count > np)
    throw _eh + "Not enough processed buffers.";

  if (count == 0)
    count = np;

  vector<ALuint> ubufs(count);
  alSourceUnqueueBuffers(mAlSrc, count, &ubufs[0]);

  Audio1::CheckAlError(_eh);
}

void AlSource::UnqueueAllBuffers()
{
  UnqueueBuffers(0);
}

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

void AlSource::Play()
{
  static const Exc_t _eh("AlContext::Play ");

  if (IsPlaying())
      throw _eh + "Already playing.";

  alSourcei(mAlSrc, AL_LOOPING, AL_FALSE);
  alSourcePlay(mAlSrc);
}

void AlSource::Loop()
{
  static const Exc_t _eh("AlSource::Loop ");

  if (IsPlaying())
      throw _eh + "Already playing.";

  alSourcei(mAlSrc, AL_LOOPING, AL_TRUE);
  alSourcePlay(mAlSrc);
}

void AlSource::Stop()
{
  static const Exc_t _eh("AlSource::Stop ");

  if (!IsPlaying())
    throw _eh + "Not playing.";

  alSourceStop(mAlSrc);
  alSourcei(mAlSrc, AL_LOOPING, AL_FALSE);
}

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

void AlSource::EmitSourceRay()
{
  if (mAlSrc)
  {
    alSourcef(mAlSrc, AL_GAIN, mGain);
    alSourcef(mAlSrc, AL_MIN_GAIN, mMinGain);
    alSourcef(mAlSrc, AL_MAX_GAIN, mMaxGain);
    alSourcef(mAlSrc, AL_PITCH, mPitch);
  }
}

void AlSource::EmitConeRay()
{
  if (mAlSrc)
  {
    alSourcef(mAlSrc, AL_CONE_INNER_ANGLE, mConeInnerAngle);
    alSourcef(mAlSrc, AL_CONE_OUTER_ANGLE, mConeOuterAngle);
    alSourcef(mAlSrc, AL_CONE_OUTER_GAIN,  mConeOuterGain);
  }
}

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

void AlSource::PrintSourceInfo()
{
  TString out("AlSource::PrintSourceInfo() ");
  out += Identify() + "\n";

  {
    int ii;
    alGetSourcei(mAlSrc, AL_SOURCE_TYPE, &ii);
    TString st;
    if (ii == AL_UNDETERMINED)   st = "UNDETERMINED";
    else if (ii == AL_STATIC)    st = "STATIC";
    else if (ii == AL_STREAMING) st = "STREAMING";
    else  st = "UNKNOWN";

    TString ss;
    alGetSourcei(mAlSrc, AL_SOURCE_STATE, &ii);
    if      (ii == AL_INITIAL) ss = "INITIAL";
    else if (ii == AL_PLAYING) ss = "PLAYING";
    else if (ii == AL_PAUSED)  ss = "PAUSED";
    else if (ii == AL_STOPPED) ss = "STOPPED";
    else                       ss = "UNKNOWN";

    int lp;
    alGetSourcei(mAlSrc, AL_LOOPING,       &lp);

    out += "  SOURCE_TYPE = " + st + ",  SOURCE_STATE = " + ss + ",  LOOPING = " +
      (lp ? "TRUE" : "FALSE") + "\n";
  }
  {
    int nq, np;
    alGetSourcei(mAlSrc, AL_BUFFERS_QUEUED,    &nq);
    alGetSourcei(mAlSrc, AL_BUFFERS_PROCESSED, &np);
    out += Form("  BUFFERS_QUEUED = %d,  BUFFERS_PROCESSED = %d\n", nq, np);
  }

  cout << out;
}
 AlSource.cxx:1
 AlSource.cxx:2
 AlSource.cxx:3
 AlSource.cxx:4
 AlSource.cxx:5
 AlSource.cxx:6
 AlSource.cxx:7
 AlSource.cxx:8
 AlSource.cxx:9
 AlSource.cxx:10
 AlSource.cxx:11
 AlSource.cxx:12
 AlSource.cxx:13
 AlSource.cxx:14
 AlSource.cxx:15
 AlSource.cxx:16
 AlSource.cxx:17
 AlSource.cxx:18
 AlSource.cxx:19
 AlSource.cxx:20
 AlSource.cxx:21
 AlSource.cxx:22
 AlSource.cxx:23
 AlSource.cxx:24
 AlSource.cxx:25
 AlSource.cxx:26
 AlSource.cxx:27
 AlSource.cxx:28
 AlSource.cxx:29
 AlSource.cxx:30
 AlSource.cxx:31
 AlSource.cxx:32
 AlSource.cxx:33
 AlSource.cxx:34
 AlSource.cxx:35
 AlSource.cxx:36
 AlSource.cxx:37
 AlSource.cxx:38
 AlSource.cxx:39
 AlSource.cxx:40
 AlSource.cxx:41
 AlSource.cxx:42
 AlSource.cxx:43
 AlSource.cxx:44
 AlSource.cxx:45
 AlSource.cxx:46
 AlSource.cxx:47
 AlSource.cxx:48
 AlSource.cxx:49
 AlSource.cxx:50
 AlSource.cxx:51
 AlSource.cxx:52
 AlSource.cxx:53
 AlSource.cxx:54
 AlSource.cxx:55
 AlSource.cxx:56
 AlSource.cxx:57
 AlSource.cxx:58
 AlSource.cxx:59
 AlSource.cxx:60
 AlSource.cxx:61
 AlSource.cxx:62
 AlSource.cxx:63
 AlSource.cxx:64
 AlSource.cxx:65
 AlSource.cxx:66
 AlSource.cxx:67
 AlSource.cxx:68
 AlSource.cxx:69
 AlSource.cxx:70
 AlSource.cxx:71
 AlSource.cxx:72
 AlSource.cxx:73
 AlSource.cxx:74
 AlSource.cxx:75
 AlSource.cxx:76
 AlSource.cxx:77
 AlSource.cxx:78
 AlSource.cxx:79
 AlSource.cxx:80
 AlSource.cxx:81
 AlSource.cxx:82
 AlSource.cxx:83
 AlSource.cxx:84
 AlSource.cxx:85
 AlSource.cxx:86
 AlSource.cxx:87
 AlSource.cxx:88
 AlSource.cxx:89
 AlSource.cxx:90
 AlSource.cxx:91
 AlSource.cxx:92
 AlSource.cxx:93
 AlSource.cxx:94
 AlSource.cxx:95
 AlSource.cxx:96
 AlSource.cxx:97
 AlSource.cxx:98
 AlSource.cxx:99
 AlSource.cxx:100
 AlSource.cxx:101
 AlSource.cxx:102
 AlSource.cxx:103
 AlSource.cxx:104
 AlSource.cxx:105
 AlSource.cxx:106
 AlSource.cxx:107
 AlSource.cxx:108
 AlSource.cxx:109
 AlSource.cxx:110
 AlSource.cxx:111
 AlSource.cxx:112
 AlSource.cxx:113
 AlSource.cxx:114
 AlSource.cxx:115
 AlSource.cxx:116
 AlSource.cxx:117
 AlSource.cxx:118
 AlSource.cxx:119
 AlSource.cxx:120
 AlSource.cxx:121
 AlSource.cxx:122
 AlSource.cxx:123
 AlSource.cxx:124
 AlSource.cxx:125
 AlSource.cxx:126
 AlSource.cxx:127
 AlSource.cxx:128
 AlSource.cxx:129
 AlSource.cxx:130
 AlSource.cxx:131
 AlSource.cxx:132
 AlSource.cxx:133
 AlSource.cxx:134
 AlSource.cxx:135
 AlSource.cxx:136
 AlSource.cxx:137
 AlSource.cxx:138
 AlSource.cxx:139
 AlSource.cxx:140
 AlSource.cxx:141
 AlSource.cxx:142
 AlSource.cxx:143
 AlSource.cxx:144
 AlSource.cxx:145
 AlSource.cxx:146
 AlSource.cxx:147
 AlSource.cxx:148
 AlSource.cxx:149
 AlSource.cxx:150
 AlSource.cxx:151
 AlSource.cxx:152
 AlSource.cxx:153
 AlSource.cxx:154
 AlSource.cxx:155
 AlSource.cxx:156
 AlSource.cxx:157
 AlSource.cxx:158
 AlSource.cxx:159
 AlSource.cxx:160
 AlSource.cxx:161
 AlSource.cxx:162
 AlSource.cxx:163
 AlSource.cxx:164
 AlSource.cxx:165
 AlSource.cxx:166
 AlSource.cxx:167
 AlSource.cxx:168
 AlSource.cxx:169
 AlSource.cxx:170
 AlSource.cxx:171
 AlSource.cxx:172
 AlSource.cxx:173
 AlSource.cxx:174
 AlSource.cxx:175
 AlSource.cxx:176
 AlSource.cxx:177
 AlSource.cxx:178
 AlSource.cxx:179
 AlSource.cxx:180
 AlSource.cxx:181
 AlSource.cxx:182
 AlSource.cxx:183
 AlSource.cxx:184
 AlSource.cxx:185
 AlSource.cxx:186
 AlSource.cxx:187
 AlSource.cxx:188
 AlSource.cxx:189
 AlSource.cxx:190
 AlSource.cxx:191
 AlSource.cxx:192
 AlSource.cxx:193
 AlSource.cxx:194
 AlSource.cxx:195
 AlSource.cxx:196
 AlSource.cxx:197
 AlSource.cxx:198
 AlSource.cxx:199
 AlSource.cxx:200
 AlSource.cxx:201