SoundRecorder.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Audio/SoundRecorder.hpp>
00029 #include <SFML/Audio/AudioDevice.hpp>
00030 #include <SFML/Audio/OpenAL.hpp>
00031 #include <SFML/System/Sleep.hpp>
00032 #include <iostream>
00033 
00034 
00036 // Private data
00038 namespace
00039 {
00040     ALCdevice* CaptureDevice = NULL;
00041 }
00042 
00043 
00047 sfSoundRecorder::sfSoundRecorder() :
00048 mySampleRate (0),
00049 myIsCapturing(false)
00050 {
00051 
00052 }
00053 
00054 
00058 sfSoundRecorder::~sfSoundRecorder()
00059 {
00060     // Nothing to do
00061 }
00062 
00063 
00068 void sfSoundRecorder::Start(unsigned int SampleRate)
00069 {
00070     // Check if the device can do audio capture
00071     if (!CanCapture())
00072     {
00073         std::cerr << "Failed to start capture : your system cannot capture audio data (call sfSoundRecorder::CanCapture to check it)" << std::endl;
00074         return;
00075     }
00076 
00077     // Check that another capture is not already running
00078     if (CaptureDevice)
00079     {
00080         std::cerr << "Trying to start audio capture, but another capture is already running" << std::endl;
00081         return;
00082     }
00083 
00084     // Open the capture device for capturing 16 bits mono samples
00085     CaptureDevice = alcCaptureOpenDevice(NULL, SampleRate, AL_FORMAT_MONO16, SampleRate);
00086     if (!CaptureDevice)
00087     {
00088         std::cerr << "Failed to open the audio capture device" << std::endl;
00089         return;
00090     }
00091 
00092     // Clear the sample array
00093     mySamples.clear();
00094 
00095     // Store the sample rate
00096     mySampleRate = SampleRate;
00097 
00098     // Start the capture
00099     alcCaptureStart(CaptureDevice);
00100 
00101     // Start the capture in a new thread, to avoid blocking the main thread
00102     myIsCapturing = true;
00103     Launch();
00104 }
00105 
00106 
00110 void sfSoundRecorder::Stop()
00111 {
00112     // If capture has not been started, we cannot stop
00113     if (!myIsCapturing)
00114     {
00115         std::cerr << "Trying to stop audio capture, but the capture has not been started ; call Start() first" << std::endl;
00116         return;
00117     }
00118 
00119     // Stop the capturing thread
00120     myIsCapturing = false;
00121     Wait();
00122 }
00123 
00124 
00128 unsigned int sfSoundRecorder::GetSampleRate() const
00129 {
00130     return mySampleRate;
00131 }
00132 
00133 
00138 bool sfSoundRecorder::CanCapture()
00139 {
00140     ALCdevice* Device = sf_private::sfAudioDevice::GetInstance().GetDevice();
00141 
00142     return alcIsExtensionPresent(Device, "ALC_EXT_CAPTURE") != AL_FALSE;
00143 }
00144 
00145 
00149 void sfSoundRecorder::Run()
00150 {
00151     while (myIsCapturing)
00152     {
00153         // Process available samples
00154         ProcessCapturedSamples();
00155 
00156         // Don't bother the CPU while waiting for more captured data
00157         sfSleep(0.1f);
00158     }
00159 
00160     // Capture is finished : clean up everything
00161     CleanUp();
00162 }
00163 
00164 
00168 void sfSoundRecorder::ProcessCapturedSamples()
00169 {
00170     // Get the number of samples available
00171     ALCint SamplesAvailable;
00172     alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
00173 
00174     if (SamplesAvailable > 0)
00175     {
00176         // Get the recorded samples
00177         mySamples.resize(SamplesAvailable);
00178         alcCaptureSamples(CaptureDevice, &mySamples[0], SamplesAvailable);
00179 
00180         // Forward them to the derived class
00181         if (!ProcessSamples(&mySamples[0], mySamples.size()))
00182         {
00183             // The user wants to stop the capture
00184             myIsCapturing = false;
00185         }
00186     }
00187 }
00188 
00189 
00193 void sfSoundRecorder::CleanUp()
00194 {
00195     // Stop the capture
00196     alcCaptureStop(CaptureDevice);
00197 
00198     // Get the samples left in the buffer
00199     ProcessCapturedSamples();
00200 
00201     // Close the device
00202     alcCaptureCloseDevice(CaptureDevice);
00203     CaptureDevice = NULL;
00204 }