irixsound.h

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Thu Oct 14 11:23:12 1999
00010 // commit: $Id: irixsound.h 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/media/irixsound.h $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_MEDIA_IRIXSOUND_H_UTC20050626084018_DEFINED
00035 #define GROOVX_MEDIA_IRIXSOUND_H_UTC20050626084018_DEFINED
00036 
00037 #include "media/soundrep.h"
00038 
00039 #include "rutz/arrays.h"
00040 #include "rutz/error.h"
00041 #include "rutz/fstring.h"
00042 #include "rutz/sfmt.h"
00043 
00044 #include <dmedia/audio.h>
00045 #include <dmedia/audiofile.h>
00046 #include <unistd.h>
00047 
00048 #include "rutz/trace.h"
00049 #include "rutz/debug.h"
00050 
00051 namespace media
00052 {
00053 
00054   //  #######################################################
00055   //  =======================================================
00056 
00058 
00059   class irix_audio_sound_rep : public sound_rep
00060   {
00061   public:
00062     irix_audio_sound_rep(const char* filename = 0);
00063     virtual ~irix_audio_sound_rep() throw();
00064 
00065     virtual void play();
00066 
00067   private:
00068     ALconfig m_audio_config;
00069     rutz::dynamic_block<unsigned char> m_samples;
00070     AFframecount m_frame_count;
00071   };
00072 
00073 }
00074 
00075 media::irix_audio_sound_rep::irix_audio_sound_rep(const char* filename) :
00076   m_audio_config(alNewConfig()),
00077   m_samples(),
00078   m_frame_count(0)
00079 {
00080 GVX_TRACE("media::irix_audio_sound_rep::irix_audio_sound_rep");
00081 
00082   if (m_audio_config == 0)
00083     throw rutz::error("error creating an ALconfig "
00084                       "while creating Sound", SRC_POS);
00085 
00086   sound_rep::check_filename(filename);
00087 
00088   // Open filename as an audio file for reading. We pass a NULL
00089   // AFfilesetup to indicate that file setup parameters should be
00090   // taken from the file itself.
00091   AFfilehandle audiofile = afOpenFile(filename, "r", (AFfilesetup) 0);
00092   if (audiofile == AF_NULL_FILEHANDLE)
00093     {
00094       throw rutz::error(rutz::sfmt("couldn't open sound file %s", filename),
00095                         SRC_POS);
00096     }
00097 
00098   // Read important parameters from the audio file, and use them to
00099   // set the corresponding parameters in m_audio_config.
00100 
00101   // Number of audio channels (i.e. mono == 1, stereo == 2)
00102   const int num_channels = afGetChannels(audiofile, AF_DEFAULT_TRACK);
00103   if (num_channels == -1)
00104     {
00105       throw rutz::error(rutz::sfmt("error reading the number of channels "
00106                                    "in sound file %s", filename),
00107                         SRC_POS);
00108     }
00109   alSetChannels(m_audio_config, num_channels);
00110 
00111   // Frame count
00112   m_frame_count = afGetFrameCount(audiofile, AF_DEFAULT_TRACK);
00113   if (m_frame_count < 0)
00114     {
00115       throw rutz::error(rutz::sfmt("error reading the frame count "
00116                                    "in sound file %s", filename),
00117                         SRC_POS);
00118     }
00119 
00120   // Sample format and width
00121   int sample_format = 0;
00122   int sample_width = 0;
00123   afGetSampleFormat(audiofile, AF_DEFAULT_TRACK,
00124                     &sample_format, &sample_width);
00125   alSetSampFmt(m_audio_config, sample_format);
00126   alSetWidth(m_audio_config, sample_width);
00127 
00128   // Sample size and rate
00129   const int bytes_per_sample = (sample_width + 7)/8;
00130 
00131   const double sampling_rate = afGetRate(audiofile, AF_DEFAULT_TRACK);
00132 
00133   ALpv pv;
00134   pv.param = AL_RATE;
00135   pv.value.ll = alDoubleToFixed(sampling_rate);
00136 
00137   alSetParams(AL_DEFAULT_DEVICE, &pv, 1);
00138 
00139   dbg_eval(3, num_channels);
00140   dbg_eval(3, m_frame_count);
00141   dbg_eval(3, sample_width);
00142   dbg_eval(3, bytes_per_sample);
00143   dbg_eval_nl(3, sampling_rate);
00144 
00145   // Allocate space for the sound samples
00146   m_samples.resize(m_frame_count*num_channels*bytes_per_sample);
00147 
00148   const int read_result = afReadFrames(audiofile, AF_DEFAULT_TRACK,
00149                                        static_cast<void*>(&m_samples[0]),
00150                                        m_frame_count);
00151 
00152   const int close_result = afCloseFile(audiofile);
00153 
00154   if (read_result == -1)
00155     {
00156       throw rutz::error(rutz::sfmt("error reading sound data "
00157                                    "from file %s", filename), SRC_POS);
00158     }
00159 
00160   if (close_result == -1)
00161     {
00162       throw rutz::error(rutz::sfmt("error closing sound file %s",
00163                                    filename), SRC_POS);
00164     }
00165 }
00166 
00167 media::irix_audio_sound_rep::~irix_audio_sound_rep() throw()
00168 {
00169 GVX_TRACE("media::irix_audio_sound_rep::~irix_audio_sound_rep");
00170   if (m_audio_config != 0)
00171     {
00172       alFreeConfig(m_audio_config);
00173     }
00174 }
00175 
00176 void media::irix_audio_sound_rep::play()
00177 {
00178 GVX_TRACE("media::irix_audio_sound_rep::play");
00179   if (m_samples.size() == 0) return;
00180 
00181   ALport audio_port = alOpenPort("Sound::play", "w", m_audio_config);
00182   dbg_eval_nl(3, (void*) audio_port);
00183   if (audio_port == 0)
00184     {
00185       throw rutz::error("error opening an audio port "
00186                         "during Sound::play", SRC_POS);
00187     }
00188 
00189   int writeResult =
00190     alWriteFrames(audio_port, static_cast<void*>(&m_samples[0]), m_frame_count);
00191   if (writeResult == -1)
00192     {
00193       throw rutz::error("error writing to the audio port "
00194                         "during Sound::play", SRC_POS);
00195     }
00196 
00197   while (alGetFilled(audio_port) > 0)
00198     {
00199       usleep(5000);
00200     }
00201 
00202   int close_result = alClosePort(audio_port);
00203   if (close_result == -1)
00204     {
00205       throw rutz::error("error closing the audio port "
00206                         "during Sound::play", SRC_POS);
00207     }
00208 }
00209 
00210 static const char __attribute__((used)) vcid_groovx_media_irixsound_h_utc20050626084018[] = "$Id: irixsound.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00211 #endif // !GROOVX_MEDIA_IRIXSOUND_H_UTC20050626084018_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.