SoundRecorder.cpp
00001 00002 // 00003 // SFML - Simple and Fast Multimedia Library 00004 // Copyright (C) 2007-2009 Laurent Gomila ([email protected]) 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 ::