SoundRecorder.cpp
1
2//
3// SFML - Simple and Fast Multimedia Library
4// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
26// Headers
28#include <SFML/Audio/SoundRecorder.hpp>
29#include <SFML/Audio/AudioDevice.hpp>
30#include <SFML/Audio/OpenAL.hpp>
31#include <SFML/System/Sleep.hpp>
32#include <iostream>
33
34
36// Private data
38namespace
39{
40 ALCdevice* CaptureDevice = NULL;
41}
42
43namespace sf
44{
49mySampleRate (0),
50myIsCapturing(false)
51{
52
53}
54
55
60{
61 // Nothing to do
62}
63
64
69void SoundRecorder::Start(unsigned int SampleRate)
70{
71 // Check if the device can do audio capture
72 if (!CanCapture())
73 {
74 std::cerr << "Failed to start capture : your system cannot capture audio data (call SoundRecorder::CanCapture to check it)" << std::endl;
75 return;
76 }
77
78 // Check that another capture is not already running
79 if (CaptureDevice)
80 {
81 std::cerr << "Trying to start audio capture, but another capture is already running" << std::endl;
82 return;
83 }
84
85 // Open the capture device for capturing 16 bits mono samples
86 CaptureDevice = alcCaptureOpenDevice(NULL, SampleRate, AL_FORMAT_MONO16, SampleRate);
87 if (!CaptureDevice)
88 {
89 std::cerr << "Failed to open the audio capture device" << std::endl;
90 return;
91 }
92
93 // Clear the sample array
94 mySamples.clear();
95
96 // Store the sample rate
97 mySampleRate = SampleRate;
98
99 // Notify derived class
100 if (OnStart())
101 {
102 // Start the capture
103 alcCaptureStart(CaptureDevice);
104
105 // Start the capture in a new thread, to avoid blocking the main thread
106 myIsCapturing = true;
107 Launch();
108 }
109}
110
111
116{
117 // Stop the capturing thread
118 myIsCapturing = false;
119 Wait();
120}
121
122
127{
128 return mySampleRate;
129}
130
131
137{
138 ALCdevice* Device = priv::AudioDevice::GetInstance().GetDevice();
139
140 return (alcIsExtensionPresent(Device, "ALC_EXT_CAPTURE") != AL_FALSE) ||
141 (alcIsExtensionPresent(Device, "ALC_EXT_capture") != AL_FALSE); // "bug" in Mac OS X 10.5 and 10.6
142}
143
144
148bool SoundRecorder::OnStart()
149{
150 // Nothing to do
151 return true;
152}
153
154
158void SoundRecorder::OnStop()
159{
160 // Nothing to do
161}
162
163
167void SoundRecorder::Run()
168{
169 while (myIsCapturing)
170 {
171 // Process available samples
172 ProcessCapturedSamples();
173
174 // Don't bother the CPU while waiting for more captured data
175 Sleep(0.1f);
176 }
177
178 // Capture is finished : clean up everything
179 CleanUp();
180
181 // Notify derived class
182 OnStop();
183}
184
185
189void SoundRecorder::ProcessCapturedSamples()
190{
191 // Get the number of samples available
192 ALCint SamplesAvailable;
193 alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
194
195 if (SamplesAvailable > 0)
196 {
197 // Get the recorded samples
198 mySamples.resize(SamplesAvailable);
199 alcCaptureSamples(CaptureDevice, &mySamples[0], SamplesAvailable);
200
201 // Forward them to the derived class
202 if (!OnProcessSamples(&mySamples[0], mySamples.size()))
203 {
204 // The user wants to stop the capture
205 myIsCapturing = false;
206 }
207 }
208}
209
210
214void SoundRecorder::CleanUp()
215{
216 // Stop the capture
217 alcCaptureStop(CaptureDevice);
218
219 // Get the samples left in the buffer
220 ProcessCapturedSamples();
221
222 // Close the device
223 alcCaptureCloseDevice(CaptureDevice);
224 CaptureDevice = NULL;
225}
226
227} // namespace sf
static bool CanCapture()
Tell if the system supports sound capture.
SoundRecorder()
Default constructor.
void Start(unsigned int SampleRate=44100)
Start the capture.
void Stop()
Stop the capture.
unsigned int GetSampleRate() const
Get the sample rate.
virtual ~SoundRecorder()
Virtual destructor.
void Launch()
Create and run the thread.
Definition Thread.cpp:72
void Wait()
Wait until the thread finishes.
Definition Thread.cpp:89