SFML logo
  • Main Page
  • Namespaces
  • Classes
  • Files
  • File List

SoundRecorder.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 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 namespace sf
00044 {
00048 SoundRecorder::SoundRecorder() :
00049 mySampleRate (0),
00050 myIsCapturing(false)
00051 {
00052 
00053 }
00054 
00055 
00059 SoundRecorder::~SoundRecorder()
00060 {
00061     // Nothing to do
00062 }
00063 
00064 
00069 void SoundRecorder::Start(unsigned int SampleRate)
00070 {
00071     // Check if the device can do audio capture
00072     if (!CanCapture())
00073     {
00074         std::cerr << "Failed to start capture : your system cannot capture audio data (call SoundRecorder::CanCapture to check it)" << std::endl;
00075         return;
00076     }
00077 
00078     // Check that another capture is not already running
00079     if (CaptureDevice)
00080     {
00081         std::cerr << "Trying to start audio capture, but another capture is already running" << std::endl;
00082         return;
00083     }
00084 
00085     // Open the capture device for capturing 16 bits mono samples
00086     CaptureDevice = alcCaptureOpenDevice(NULL, SampleRate, AL_FORMAT_MONO16, SampleRate);
00087     if (!CaptureDevice)
00088     {
00089         std::cerr << "Failed to open the audio capture device" << std::endl;
00090         return;
00091     }
00092 
00093     // Clear the sample array
00094     mySamples.clear();
00095 
00096     // Store the sample rate
00097     mySampleRate = SampleRate;
00098 
00099     // Notify derived class
00100     if (OnStart())
00101     {
00102         // Start the capture
00103         alcCaptureStart(CaptureDevice);
00104 
00105         // Start the capture in a new thread, to avoid blocking the main thread
00106         myIsCapturing = true;
00107         Launch();
00108     }
00109 }
00110 
00111 
00115 void SoundRecorder::Stop()
00116 {
00117     // Stop the capturing thread
00118     myIsCapturing = false;
00119     Wait();
00120 }
00121 
00122 
00126 unsigned int SoundRecorder::GetSampleRate() const
00127 {
00128     return mySampleRate;
00129 }
00130 
00131 
00136 bool SoundRecorder::CanCapture()
00137 {
00138     ALCdevice* Device = priv::AudioDevice::GetInstance().GetDevice();
00139 
00140     return alcIsExtensionPresent(Device, "ALC_EXT_CAPTURE") != AL_FALSE;
00141 }
00142 
00143 
00147 bool SoundRecorder::OnStart()
00148 {
00149     // Nothing to do
00150     return true;
00151 }
00152 
00153 
00157 void SoundRecorder::OnStop()
00158 {
00159     // Nothing to do
00160 }
00161 
00162 
00166 void SoundRecorder::Run()
00167 {
00168     while (myIsCapturing)
00169     {
00170         // Process available samples
00171         ProcessCapturedSamples();
00172 
00173         // Don't bother the CPU while waiting for more captured data
00174         Sleep(0.1f);
00175     }
00176 
00177     // Capture is finished : clean up everything
00178     CleanUp();
00179 
00180     // Notify derived class
00181     OnStop();
00182 }
00183 
00184 
00188 void SoundRecorder::ProcessCapturedSamples()
00189 {
00190     // Get the number of samples available
00191     ALCint SamplesAvailable;
00192     alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
00193 
00194     if (SamplesAvailable > 0)
00195     {
00196         // Get the recorded samples
00197         mySamples.resize(SamplesAvailable);
00198         alcCaptureSamples(CaptureDevice, &mySamples[0], SamplesAvailable);
00199 
00200         // Forward them to the derived class
00201         if (!OnProcessSamples(&mySamples[0], mySamples.size()))
00202         {
00203             // The user wants to stop the capture
00204             myIsCapturing = false;
00205         }
00206     }
00207 }
00208 
00209 
00213 void SoundRecorder::CleanUp()
00214 {
00215     // Stop the capture
00216     alcCaptureStop(CaptureDevice);
00217 
00218     // Get the samples left in the buffer
00219     ProcessCapturedSamples();
00220 
00221     // Close the device
00222     alcCaptureCloseDevice(CaptureDevice);
00223     CaptureDevice = NULL;
00224 }
00225 
00226 } // namespace sf

 ::  Copyright © 2007-2008 Laurent Gomila, all rights reserved  ::  Documentation generated by doxygen 1.5.2  ::