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 ::