Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

/root/src/subsynth/syn/Stream/OpenALSound.h

Go to the documentation of this file.
00001 
00002 /****************** <SYN heading BEGIN do not edit this line> *****************
00003  *
00004  * subsynth - modular audio synthesizer
00005  * subsynth is (C) Copyright 2001-2002 by Kevin Meinert
00006  *
00007  * Original Author: Kevin Meinert
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public
00020  * License along with this library; if not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00022  * Boston, MA 02111-1307, USA.
00023  *
00024  * -----------------------------------------------------------------
00025  * File:          $RCSfile: OpenALSound.h,v $
00026  * Date modified: $Date: 2002/02/16 19:24:16 $
00027  * Version:       $Revision: 1.10 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 #ifndef OAL_SOUND
00032 #define OAL_SOUND
00033 
00034 #include <AL/al.h>
00035 #include <AL/alc.h>
00036 #include <AL/alut.h>
00037 
00038 #include <iostream>
00039 #include <vector>
00040 #include <string>
00041 
00042 #ifdef _WIN32
00043    #include <windows.h>
00044 #endif
00045 
00046 #include "syn/Stream/WavImporter.h"
00047 
00048 namespace syn
00049 {
00056    class OpenALSound
00057    {
00058    public:
00059       OpenALSound() : mSource( 0 )
00060       {
00061          position[0] = 0; position[1] = 0; position[2] = 0;
00062       }
00063    
00064       bool load( const syn::AudioFormat& fmt, char* fname )
00065       {
00066          std::vector<unsigned char> data;
00067 
00068          
00069          ALfloat zeroes[] = { 0.0f, 0.0f,  0.0f };
00070          alListenerfv( AL_POSITION, zeroes );
00071          /* alListenerfv(AL_VELOCITY, zeroes ); */
00072          
00073          ALfloat front[]  = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f };
00074          alListenerfv( AL_ORIENTATION, front );
00075 
00076          alGenBuffers( 1, &mBuffer );
00077 
00078          // read the data from the file.
00079          WavImporter i;
00080          int channels, samp_rate, format;
00081          if (false == i.import( fmt, fname, data ))
00082          {
00083             return false;
00084          }
00085 
00086          // convert the AudioFormat params to OpenAL tags...
00087          // this block is an ugly beast...
00088          samp_rate = fmt.samplingRateHz;
00089          channels = fmt.channels;
00090          switch (fmt.datatype)
00091          {
00092          case syn::AudioFormat::UNSIGNED8:
00093             std::cout << "WARNING: UNSIGNED8 unsupported."
00094                       << "Could not not open stream\n" << std::flush; 
00095             return false;
00096          case syn::AudioFormat::SIGNED8:
00097             if (fmt.channels == 1) 
00098                format = AL_FORMAT_MONO8;
00099             else if (fmt.channels == 2)
00100                format = AL_FORMAT_STEREO8;
00101             else 
00102             {
00103                std::cout << "WARNING: Only 1 or 2 channels unsupported. "
00104                          << "Could not not open stream\n" << std::flush; 
00105                return false;
00106             }
00107             break;
00108          case syn::AudioFormat::UNSIGNED16:
00109             std::cout << "WARNING: UNSIGNED16 unsupported. "
00110                       << "Could not not open stream\n" << std::flush; 
00111             return false;
00112          case syn::AudioFormat::SIGNED16:
00113             if (fmt.channels == 1) 
00114                format = AL_FORMAT_MONO16;
00115             else if (fmt.channels == 2) 
00116                format = AL_FORMAT_STEREO16;
00117             else 
00118             {
00119                std::cout << "WARNING: Only 1 or 2 channels unsupported. "
00120                          << "Could not not open stream\n" << std::flush; 
00121                return false;
00122             }
00123             break;
00124          case syn::AudioFormat::FLOAT32:  
00125             std::cout << "WARNING: FLOAT32 unsupported."
00126                       << "Could not not open stream\n" << std::flush; 
00127             return false;
00128          }
00129 
00130          alGetError();
00131 
00132          // save the .wav file data under "mBuffer" identifier
00133          alBufferData( mBuffer, format, &data[0], data.size(), samp_rate );
00134          if (alGetError() != AL_NO_ERROR)
00135          {
00136             std::cerr<<"Could not BufferData\n"<<std::flush;
00137             exit( 1 );
00138          }
00139 
00140          alGenSources( 1, &mSource );
00141 
00142          alSourcei( mSource, AL_BUFFER, mBuffer );
00143          alSourcei( mSource, AL_LOOPING, AL_TRUE );
00144 
00145          return true;
00146       }
00147 
00148       void play()
00149       {
00150          alSourcePlay( mSource );
00151       }
00152    
00153       void setPos( float x, float y, float z )
00154       {
00155          #define ALMAXDISTANCE 60.0f
00156          clamp( x, -ALMAXDISTANCE, ALMAXDISTANCE );
00157          clamp( y, -ALMAXDISTANCE, ALMAXDISTANCE );
00158          clamp( z, -ALMAXDISTANCE, ALMAXDISTANCE );
00159       
00160          ALfloat lispos[] = { x, y, z };
00161          alListenerfv( AL_POSITION, lispos );
00162       }   
00163    
00164       void stop()
00165       {
00166          alSourceStop(mSource);
00167       }   
00168    
00169       void step()
00170       {
00171          static ALfloat position[] = { 10.0, 0.0, 4.0 };
00172 //       static ALfloat movefactor = 4.5;
00173 //       static time_t then = 0;
00174          //time_t now;
00175 
00176          /*now = time( NULL );
00177 
00178          // Switch between left and right stereo sample every two seconds.
00179          if( now - then > 2 ) {
00180             then = now;
00181 
00182             movefactor *= -1.0;
00183          }
00184 
00185          position[0] += movefactor;
00186          */
00187          
00188          alSourcefv( mSource, AL_POSITION, position );
00189 
00190 //         micro_sleep( 500000 );
00191 
00192    //    ALint byteloki;
00193    //    alGetSourceiv( mSource, AL_BYTE_LOKI, &byteloki );
00194    //    alGetBufferi( mBuffer,     AL_SIZE,      &size );
00195 
00196          //fprintf(stderr, "byteloki = %d size = %d\n", byteloki, size);
00197 
00198          return;
00199       }
00200    
00201       bool isPlaying()
00202       {
00203          ALuint sid = mSource;
00204          ALint state;
00205 
00206          if(alIsSource(sid) == AL_FALSE) 
00207          {
00208             return false;
00209          }
00210 
00211          state = AL_INITIAL;
00212 
00213 #   ifdef WIN32
00214          alGetSourcei( sid, AL_SOURCE_STATE, &state );
00215 #   else
00216          alGetSourceiv( sid, AL_SOURCE_STATE, &state );
00217 #   endif 
00218 
00219          switch(state) 
00220          {
00221             case AL_PLAYING:
00222             case AL_PAUSED:
00223               return true;
00224             default:
00225               break;
00226          }
00227 
00228          return false;
00229       }
00230    private:
00231    
00232    
00233 /*
00234       #ifdef _WIN32
00235       void micro_sleep(unsigned int n) 
00236       {
00237          Sleep( n / 1000 );
00238          return;
00239       }
00240 
00241       #else
00242 
00243       void micro_sleep(unsigned int n) 
00244       {
00245          struct timeval tv = { 0, 0 };
00246               tv.tv_usec = n;
00247          select( 0, NULL, NULL, NULL, &tv );
00248          return;
00249       }
00250 
00251 
00252       #endif // _WIN32
00253 */   
00254       void clamp( float& val, float low, float high ) const
00255       {
00256          if (val < low)
00257          {
00258             val = low;
00259          }
00260          else if (val > high)
00261          {
00262             val = high;
00263          }         
00264       }   
00265    
00266       float position[3];
00267       ALuint mSource;
00268       ALuint mBuffer;
00269    };
00270 
00271 }
00272 
00273 #endif

Generated at Mon Apr 15 09:26:08 2002 for subsynth by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001