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/ALCheck.hpp>
00031 #include <SFML/System/Sleep.hpp>
00032 #include <SFML/System/Err.hpp>
00033 
00034 
00036 // Private data
00038 namespace
00039 {
00040     ALCdevice* captureDevice = NULL;
00041 }
00042 
00043 namespace sf
00044 {
00046 SoundRecorder::SoundRecorder() :
00047 mySampleRate (0),
00048 myIsCapturing(false)
00049 {
00050     priv::EnsureALInit();
00051 }
00052 
00053 
00055 SoundRecorder::~SoundRecorder()
00056 {
00057     // Nothing to do
00058 }
00059 
00060 
00062 void SoundRecorder::Start(unsigned int sampleRate)
00063 {
00064     // Check if the device can do audio capture
00065     if (!IsAvailable())
00066     {
00067         Err() << "Failed to start capture : your system cannot capture audio data (call SoundRecorder::CanCapture to check it)" << std::endl;
00068         return;
00069     }
00070 
00071     // Check that another capture is not already running
00072     if (captureDevice)
00073     {
00074         Err() << "Trying to start audio capture, but another capture is already running" << std::endl;
00075         return;
00076     }
00077 
00078     // Open the capture device for capturing 16 bits mono samples
00079     captureDevice = alcCaptureOpenDevice(NULL, sampleRate, AL_FORMAT_MONO16, sampleRate);
00080     if (!captureDevice)
00081     {
00082         Err() << "Failed to open the audio capture device" << std::endl;
00083         return;
00084     }
00085 
00086     // Clear the array of samples
00087     mySamples.clear();
00088 
00089     // Store the sample rate
00090     mySampleRate = sampleRate;
00091 
00092     // Notify derived class
00093     if (OnStart())
00094     {
00095         // Start the capture
00096         alcCaptureStart(captureDevice);
00097 
00098         // Start the capture in a new thread, to avoid blocking the main thread
00099         myIsCapturing = true;
00100         Launch();
00101     }
00102 }
00103 
00104 
00106 void SoundRecorder::Stop()
00107 {
00108     // Stop the capturing thread
00109     myIsCapturing = false;
00110     Wait();
00111 }
00112 
00113 
00115 unsigned int SoundRecorder::GetSampleRate() const
00116 {
00117     return mySampleRate;
00118 }
00119 
00120 
00122 bool SoundRecorder::IsAvailable()
00123 {
00124     return (priv::AudioDevice::IsExtensionSupported("ALC_EXT_CAPTURE") != AL_FALSE) ||
00125            (priv::AudioDevice::IsExtensionSupported("ALC_EXT_capture") != AL_FALSE); // "bug" in Mac OS X 10.5 and 10.6
00126 }
00127 
00128 
00130 bool SoundRecorder::OnStart()
00131 {
00132     // Nothing to do
00133     return true;
00134 }
00135 
00136 
00138 void SoundRecorder::OnStop()
00139 {
00140     // Nothing to do
00141 }
00142 
00143 
00145 void SoundRecorder::Run()
00146 {
00147     while (myIsCapturing)
00148     {
00149         // Process available samples
00150         ProcessCapturedSamples();
00151 
00152         // Don't bother the CPU while waiting for more captured data
00153         Sleep(0.1f);
00154     }
00155 
00156     // Capture is finished : clean up everything
00157     CleanUp();
00158 
00159     // Notify derived class
00160     OnStop();
00161 }
00162 
00163 
00165 void SoundRecorder::ProcessCapturedSamples()
00166 {
00167     // Get the number of samples available
00168     ALCint samplesAvailable;
00169     alcGetIntegerv(captureDevice, ALC_CAPTURE_SAMPLES, 1, &samplesAvailable);
00170 
00171     if (samplesAvailable > 0)
00172     {
00173         // Get the recorded samples
00174         mySamples.resize(samplesAvailable);
00175         alcCaptureSamples(captureDevice, &mySamples[0], samplesAvailable);
00176 
00177         // Forward them to the derived class
00178         if (!OnProcessSamples(&mySamples[0], mySamples.size()))
00179         {
00180             // The user wants to stop the capture
00181             myIsCapturing = false;
00182         }
00183     }
00184 }
00185 
00186 
00188 void SoundRecorder::CleanUp()
00189 {
00190     // Stop the capture
00191     alcCaptureStop(captureDevice);
00192 
00193     // Get the samples left in the buffer
00194     ProcessCapturedSamples();
00195 
00196     // Close the device
00197     alcCaptureCloseDevice(captureDevice);
00198     captureDevice = NULL;
00199 }
00200 
00201 } // namespace sf

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