1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/*
* Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
* UNIVERSITAT POMPEU FABRA
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/**
* The goals of this example is to show you how to:
* -> Configure Audio devices in your system using CLAM tools
* -> Play a file using CLAM abstraction of audio devices
*
*/
#include "AudioIO.hxx" // imports CLAM::AudioManager and CLAM::AudioIOConfig declarations
#include "AudioManager.hxx"
#include "AudioOut.hxx" // imports CLAM::AudioOut declaration
#include "AudioFile.hxx" // imports CLAM::AudioFile declaration
#include "MultiChannelAudioFileReader.hxx" // imports CLAM::MultiChannelAudioFileReader
#include "Audio.hxx" // imports the CLAM::Audio ProcessingData class interface
#include "Err.hxx" // imports CLAM::Err exception class declaration
#include <iostream>
int main( int argc, char** argv )
{
try
{
// We take as a parameter from the command line the file to be played back
if ( argc == 1 ) // No input file
{
std::cerr << "No input file" << std::endl;
std::cerr << "Usage: AudioFileReading <input file name>" << std::endl;
exit( - 1 );
}
else if ( argc > 2 ) // Too many parameters
{
std::cerr << "Too many parameters" << std::endl;
std::cerr << "Usage: AudioFileReading <input file name>" << std::endl;
exit( -1 );
}
// Now we will prepare file playback very similarly as the first half of the
// "AudioFileReading" example
CLAM::MultiChannelAudioFileReaderConfig cfg;
cfg.SetSourceFile( argv[1] );
CLAM::MultiChannelAudioFileReader reader;
if (!reader.Configure( cfg ))
{
std::cerr << "Error: file " << cfg.GetSourceFile() << " cannot be opened ";
std::cerr << "or is encoded in an unrecognized format" << std::endl;
exit(-1);
}
std::vector<CLAM::Audio> incomingAudioChannels;
incomingAudioChannels.resize( reader.GetHeader().GetChannels() );
// Once we made sure we can start playing the file, it's time to access and configure the audio hardware devices
// present in our computer. We will do this through the 'AudioManager': a global, unique object that
// mediates between your program and the underlying Operating System sound hardware services.
// So we first create an instance of AudioManager by passing its constructor two
// values: the first one being the sample rate we want the card to play the samples
// we write onto it and thenumber of samples we will want to write on to the
// card at once.
// In this example we will try 44.1 kHz playback sample rate, and we will estimate that 1024
// will be well enough for our purposes.
// The AudioManager class should be declared before AudioOut objects, because
// they need this manager to know how to play the sound (which sound device is available for them).
// NOTE about the frame size determination: The size of these 'frames' can be anything
// reasonable below the maximum buffer size we told the AudioManager
// enforce: 0 or 3 frame sizes are *not* reasonable. For this example
// we will use as frame size, 1024, which is a nice number for a variety
// of reasons, not being the only one the fact it is a power of two :)
const CLAM::TData playbackSampleRate = reader.GetHeader().GetSampleRate();
const CLAM::TSize frameSize = 1024; // this is also our read size
// And now we set the size of each Audio object to our intended 'read size'
// in this case ouf frame size
for ( unsigned i = 0; i < incomingAudioChannels.size(); i++ )
{
incomingAudioChannels[i].SetSize( frameSize );
}
CLAM::AudioManager theAudioManager( (int)playbackSampleRate, frameSize );
// Now we will create as many AudioOuts as input channels
CLAM::Array<CLAM::AudioOut > audioOutputs;
audioOutputs.Resize( incomingAudioChannels.size() );
audioOutputs.SetSize( incomingAudioChannels.size() );
// And now we will configure them
CLAM::AudioIOConfig audioOutCfg;
for ( int i = 0; i < audioOutputs.Size(); i++ )
{
// We set the channel id. Sound devices channels are numbered from
// [0...N] - being N the number of channels your sound device can
// support. Usually the channel '0' corresponds to the left channel.
audioOutCfg.SetChannelID( i );
// and we configure the left channel audio object
audioOutputs[i].Configure( audioOutCfg );
// We start it
audioOutputs[i].Start();
}
reader.Start();
while( reader.Do( incomingAudioChannels ) )
{
for ( int i = 0; i < audioOutputs.Size(); i++ )
audioOutputs[i].Do( incomingAudioChannels[i] );
}
for ( int i = 0; i < audioOutputs.Size(); i++ )
audioOutputs[i].Stop();
reader.Stop();
}
catch ( CLAM::Err& e )
{
e.Print();
exit(-1);
}
catch( std::exception& e )
{
std::cerr << e.what() << std::endl;
exit(-1);
}
return 0;
}
|