- 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            (alcIsExtensionPresent(Device, "ALC_EXT_capture") != AL_FALSE); // "bug" in Mac OS X 10.5 and 10.6
    00142 }
    00143
    00144
    00148 bool SoundRecorder::OnStart()
    00149 {
    00150     // Nothing to do
    00151     return true;
    00152 }
    00153
    00154
    00158 void SoundRecorder::OnStop()
    00159 {
    00160     // Nothing to do
    00161 }
    00162
    00163
    00167 void SoundRecorder::Run()
    00168 {
    00169     while (myIsCapturing)
    00170     {
    00171         // Process available samples
    00172         ProcessCapturedSamples();
    00173
    00174         // Don't bother the CPU while waiting for more captured data
    00175         Sleep(0.1f);
    00176     }
    00177
    00178     // Capture is finished : clean up everything
    00179     CleanUp();
    00180
    00181     // Notify derived class
    00182     OnStop();
    00183 }
    00184
    00185
    00189 void SoundRecorder::ProcessCapturedSamples()
    00190 {
    00191     // Get the number of samples available
    00192     ALCint SamplesAvailable;
    00193     alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
    00194
    00195     if (SamplesAvailable > 0)
    00196     {
    00197         // Get the recorded samples
    00198         mySamples.resize(SamplesAvailable);
    00199         alcCaptureSamples(CaptureDevice, &mySamples[0], SamplesAvailable);
    00200
    00201         // Forward them to the derived class
    00202         if (!OnProcessSamples(&mySamples[0], mySamples.size()))
    00203         {
    00204             // The user wants to stop the capture
    00205             myIsCapturing = false;
    00206         }
    00207     }
    00208 }
    00209
    00210
    00214 void SoundRecorder::CleanUp()
    00215 {
    00216     // Stop the capture
    00217     alcCaptureStop(CaptureDevice);
    00218
    00219     // Get the samples left in the buffer
    00220     ProcessCapturedSamples();
    00221
    00222     // Close the device
    00223     alcCaptureCloseDevice(CaptureDevice);
    00224     CaptureDevice = NULL;
    00225 }
    00226
    00227 } // namespace sf

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