1 /**
2  * ae.ui.audio.wave.base
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.ui.audio.source.wave;
15 
16 import std.algorithm.mutation;
17 import std.range;
18 import std.range.primitives;
19 
20 import ae.ui.audio.source.base;
21 
22 /// Implementation of `AbstractSoundSource` backed by a D range of samples.
23 template WaveSoundSource(Wave)
24 {
25 	alias Sample = typeof(Wave.init.front);
26 
27 	class WaveSoundSource : AbstractSoundSource!Sample
28 	{
29 		Wave wave; ///
30 		uint sampleRate; ///
31 
32 		this(Wave wave, uint sampleRate)
33 		{
34 			this.wave = wave;
35 			this.sampleRate = sampleRate;
36 		} ///
37 
38 		override uint getSampleRate() const nothrow
39 		{
40 			return sampleRate;
41 		} ///
42 
43 		override size_t getNumChannels() const nothrow
44 		{
45 			// TODO
46 			return 1;
47 		} ///
48 
49 		override bool procedural() const nothrow
50 		{
51 			return true;
52 		} ///
53 
54 		override size_t copySamples(size_t channel, size_t start, Sample[] buffer) const nothrow
55 		{
56 			auto w = cast(Wave)wave; // Break constness because Map.save is not const
57 			auto remaining = copy(w.drop(start).take(buffer.length), buffer);
58 			return buffer.length - remaining.length;
59 		} ///
60 
61 		override const(Sample)[] getSamples(size_t channel, size_t start, size_t maxLength) const nothrow
62 		{
63 			assert(false, "Procedural");
64 		} ///
65 	}
66 }
67 
68 /// Construct a `WaveSoundSource` from a range of samples.
69 WaveSoundSource!Wave waveSoundSource(Wave)(Wave wave, uint sampleRate)
70 {
71 	return new WaveSoundSource!Wave(wave, sampleRate);
72 }
73 
74 unittest
75 {
76 	auto w = waveSoundSource([short.max, short.min], 44100);
77 }