1 /* 2 DSFML - The Simple and Fast Multimedia Library for D 3 4 Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@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, including commercial applications, 10 and to alter it and redistribute it freely, subject to the following restrictions: 11 12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. 13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 14 15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 16 17 3. This notice may not be removed or altered from any source distribution 18 */ 19 20 module dsfml.audio.soundbufferrecorder; 21 22 import dsfml.audio.soundrecorder; 23 import dsfml.audio.soundbuffer; 24 25 26 /++ 27 + Specialized SoundRecorder which stores the captured audio data into a sound buffer. 28 + 29 + SoundBufferRecorder allows to access a recorded sound through a SoundBuffer, so that it can be played, saved to a file, etc. 30 + 31 + It has the same simple interface as its base class (start(), stop()) and adds a function to retrieve the recorded sound buffer (getBuffer()). 32 + 33 + As usual, don't forget to call the isAvailable() function before using this class (see SoundRecorder for more details about this). 34 + 35 + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1SoundBufferRecorder.php#details 36 + Authors: Laurent Gomila, Jeremy DeHaan 37 +/ 38 class SoundBufferRecorder : SoundRecorder 39 { 40 private 41 { 42 short[] m_samples; 43 SoundBuffer m_buffer; 44 } 45 46 this() 47 { 48 // Constructor code 49 m_buffer = new SoundBuffer(); 50 } 51 52 ~this() 53 { 54 import dsfml.system.config; 55 mixin(destructorOutput); 56 } 57 58 /** 59 * Get the sound buffer containing the captured audio data. 60 * 61 * The sound buffer is valid only after the capture has ended. This function provides a read-only access to the internal sound buffer, but it can be copied if you need to make any modification to it. 62 * 63 * Returns: Read-only access to the sound buffer 64 */ 65 const(SoundBuffer) getBuffer() const 66 { 67 return m_buffer; 68 } 69 70 protected 71 { 72 /// Start capturing audio data. 73 /// Returns: True to start the capture, or false to abort it 74 override bool onStart() 75 { 76 m_samples.length = 0; 77 m_buffer = new SoundBuffer(); 78 79 return true; 80 } 81 82 /** 83 * Process a new chunk of recorded samples. 84 * 85 * Params: 86 * samples = Array of the new chunk of recorded samples' 87 * 88 * Returns: True to continue the capture, or false to stop it 89 */ 90 override bool onProcessSamples(const(short)[] samples) 91 { 92 m_samples ~= samples; 93 94 return true; 95 } 96 97 /// Stop capturing audio data. 98 /// 99 /// Reimplemented from SoundRecorder. 100 override void onStop() 101 { 102 if(m_samples.length >0) 103 { 104 m_buffer.loadFromSamples(m_samples,1,sampleRate); 105 } 106 } 107 } 108 } 109 110 unittest 111 { 112 //When this unit test is run it occasionally throws an error which will vary, and 113 //is obviously in OpenAL. Probably something to do with the way the binding is done. Will be fixed in 2.1. 114 version(DSFML_Unittest_Audio) 115 { 116 import std.stdio; 117 import core.time; 118 import dsfml.window.keyboard; 119 import dsfml.audio.sound; 120 import dsfml.system.clock; 121 import dsfml.system.sleep; 122 123 124 writeln("Unit test for SoundBufferRecorder."); 125 126 assert(SoundRecorder.isAvailable()); 127 128 129 auto recorder = new SoundBufferRecorder(); 130 131 132 auto clock = new Clock(); 133 134 writeln("Recording for 5 seconds in..."); 135 writeln("3"); 136 clock.restart(); 137 138 while(clock.getElapsedTime().total!"seconds" <1) 139 { 140 //wait for a second 141 } 142 writeln("2"); 143 144 clock.restart(); 145 146 while(clock.getElapsedTime().total!"seconds" <1) 147 { 148 //wait for a second 149 } 150 writeln("1"); 151 152 clock.restart(); 153 154 while(clock.getElapsedTime().total!"seconds" <1) 155 { 156 //wait for a second 157 } 158 writeln("Recording!"); 159 160 recorder.start(); 161 clock.restart(); 162 163 while(clock.getElapsedTime().total!"seconds" <5) 164 { 165 //wait for a second 166 } 167 168 writeln("Done!"); 169 170 171 recorder.stop(); 172 173 174 175 176 auto buffer = recorder.getBuffer(); 177 178 auto recorderDuration = buffer.getDuration(); 179 180 auto recorderSound = new Sound(buffer); 181 182 clock.restart(); 183 184 recorderSound.play(); 185 while(clock.getElapsedTime() < recorderDuration) 186 { 187 //sound playing 188 } 189 190 191 192 193 writeln(); 194 } 195 }