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