/[svn]/linuxsampler/trunk/src/engines/common/Sample.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/common/Sample.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2012 - (show annotations) (download) (as text)
Fri Oct 23 17:53:17 2009 UTC (14 years, 6 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 13376 byte(s)
* Refactoring: moved the independent code from
  the Gigasampler format engine to base classes
* SFZ format engine: experimental code (not usable yet)
* SoundFont format engine: experimental code (not usable yet)
* Fixed crash which may occur when MIDI key + transpose is out of range

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003 - 2009 Christian Schoenebeck *
6 * Copyright (C) 2009 Grigor Iliev *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #ifndef __LS_SAMPLE_H__
25 #define __LS_SAMPLE_H__
26
27 #include "../../common/global.h"
28
29 namespace LinuxSampler {
30 class Sample {
31 public:
32
33 /** Pointer address and size of a buffer. */
34 struct buffer_t {
35 void* pStart; ///< Points to the beginning of the buffer.
36 unsigned long Size; ///< Size of the actual data in the buffer in bytes.
37
38 unsigned long NullExtensionSize; /*/< The buffer might be bigger than the actual data, if that's the case
39 that unused space at the end of the buffer is filled with NULLs and NullExtensionSize reflects
40 that unused buffer space in bytes. Those NULL extensions are mandatory for differential
41 algorithms that have to take the following data words into account, thus have to access past
42 the buffer's boundary. If you don't know what I'm talking about, just forget this variable. :) */
43 buffer_t() {
44 pStart = NULL;
45 Size = 0;
46 NullExtensionSize = 0;
47 }
48 };
49
50 /** Reflects the current playback state for a sample. */
51 class PlaybackState {
52 public:
53 unsigned long position; ///< Current position within the sample.
54 bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
55 unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle.
56 };
57
58 Sample() { }
59 virtual ~Sample() { }
60
61 virtual String GetName() = 0;
62 virtual int GetSampleRate() = 0;
63 virtual int GetChannelCount() = 0;
64
65 /**
66 * @returns The frame size in bytes
67 */
68 virtual int GetFrameSize() = 0;
69
70 /**
71 * @returns The total number of frames in this sample
72 */
73 virtual long GetTotalFrameCount() = 0;
74
75 /**
76 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
77 * ReleaseSampleData() to free the memory if you don't need the cached
78 * sample data anymore.
79 *
80 * @returns buffer_t structure with start address and size of the buffer
81 * in bytes
82 * @see ReleaseSampleData(), Read(), SetPos()
83 */
84 virtual buffer_t LoadSampleData() = 0;
85
86 /**
87 * Reads (uncompresses if needed) and caches the first \a FrameCount
88 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
89 * memory space if you don't need the cached samples anymore. There is no
90 * guarantee that exactly \a SampleCount samples will be cached; this is
91 * not an error. The size will be eventually truncated e.g. to the
92 * beginning of a frame of a compressed sample. This is done for
93 * efficiency reasons while streaming the wave by your sampler engine
94 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
95 * that will be returned to determine the actual cached samples, but note
96 * that the size is given in bytes! You get the number of actually cached
97 * samples by dividing it by the frame size of the sample:
98 * @code
99 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
100 * long cachedsamples = buf.Size / pSample->FrameSize;
101 * @endcode
102 *
103 * @param FrameCount - number of sample points to load into RAM
104 * @returns buffer_t structure with start address and size of
105 * the cached sample data in bytes
106 * @see ReleaseSampleData(), Read(), SetPos()
107 */
108 virtual buffer_t LoadSampleData(unsigned long FrameCount) = 0;
109
110 /**
111 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
112 * ReleaseSampleData() to free the memory if you don't need the cached
113 * sample data anymore.
114 * The method will add \a NullSamplesCount silence samples past the
115 * official buffer end (this won't affect the 'Size' member of the
116 * buffer_t structure, that means 'Size' always reflects the size of the
117 * actual sample data, the buffer might be bigger though). Silence
118 * samples past the official buffer are needed for differential
119 * algorithms that always have to take subsequent samples into account
120 * (resampling/interpolation would be an important example) and avoids
121 * memory access faults in such cases.
122 *
123 * @param NullSamplesCount - number of silence samples the buffer should
124 * be extended past it's data end
125 * @returns buffer_t structure with start address and
126 * size of the buffer in bytes
127 * @see ReleaseSampleData(), Read(), SetPos()
128 */
129 virtual buffer_t LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) = 0;
130
131 /**
132 * Reads (uncompresses if needed) and caches the first \a SampleCount
133 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
134 * memory space if you don't need the cached samples anymore. There is no
135 * guarantee that exactly \a SampleCount samples will be cached; this is
136 * not an error. The size will be eventually truncated e.g. to the
137 * beginning of a frame of a compressed sample. This is done for
138 * efficiency reasons while streaming the wave by your sampler engine
139 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
140 * that will be returned to determine the actual cached samples, but note
141 * that the size is given in bytes! You get the number of actually cached
142 * samples by dividing it by the frame size of the sample:
143 * @code
144 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
145 * long cachedsamples = buf.Size / pSample->FrameSize;
146 * @endcode
147 * The method will add \a NullSamplesCount silence samples past the
148 * official buffer end (this won't affect the 'Size' member of the
149 * buffer_t structure, that means 'Size' always reflects the size of the
150 * actual sample data, the buffer might be bigger though). Silence
151 * samples past the official buffer are needed for differential
152 * algorithms that always have to take subsequent samples into account
153 * (resampling/interpolation would be an important example) and avoids
154 * memory access faults in such cases.
155 *
156 * @param FrameCount - number of sample points to load into RAM
157 * @param NullFramesCount - number of silence samples the buffer should
158 * be extended past it's data end
159 * @returns buffer_t structure with start address and
160 * size of the cached sample data in bytes
161 * @see ReleaseSampleData(), Read()
162 */
163 virtual buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) = 0;
164
165 /**
166 * Frees the cached sample from RAM if loaded with
167 * <i>LoadSampleData()</i> previously.
168 *
169 * @see LoadSampleData();
170 */
171 virtual void ReleaseSampleData() = 0;
172
173 /**
174 * Returns current cached sample points. A buffer_t structure will be
175 * returned which contains address pointer to the begin of the cache and
176 * the size of the cached sample data in bytes. Use
177 * <i>LoadSampleData()</i> to cache a specific amount of sample points in
178 * RAM.
179 *
180 * @returns buffer_t structure with current cached sample points
181 * @see LoadSampleData();
182 */
183 virtual buffer_t GetCache() = 0;
184
185 /**
186 * Reads \a FrameCount number of frames from the current
187 * position into the buffer pointed by \a pBuffer and increments the
188 * position within the sample. Use this method
189 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
190 * thus for disk streaming.
191 *
192 * For 16 bit samples, the data in the buffer will be int16_t
193 * (using native endianness). For 24 bit, the buffer will
194 * contain 4 bytes per sample.
195 *
196 * @param pBuffer destination buffer
197 * @param SampleCount number of sample points to read
198 * @returns number of successfully read sample points
199 */
200 virtual long Read(void* pBuffer, unsigned long FrameCount) = 0;
201
202 /**
203 * Reads \a SampleCount number of sample points from the position stored
204 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
205 * the position within the sample respectively, this method honors the
206 * looping informations of the sample (if any). Use this
207 * method if you don't want to load the sample into RAM, thus for disk
208 * streaming. All this methods needs to know to proceed with streaming
209 * for the next time you call this method is stored in \a pPlaybackState.
210 * You have to allocate and initialize the playback_state_t structure by
211 * yourself before you use it to stream a sample:
212 * @code
213 * PlaybackState playbackstate;
214 * playbackstate.position = 0;
215 * playbackstate.reverse = false;
216 * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
217 * @endcode
218 * You don't have to take care of things like if there is actually a loop
219 * defined or if the current read position is located within a loop area.
220 * The method already handles such cases by itself.
221 *
222 * @param pBuffer destination buffer
223 * @param FrameCount number of sample points to read
224 * @param pPlaybackState will be used to store and reload the playback
225 * state for the next ReadAndLoop() call
226 * @returns number of successfully read sample points
227 */
228 virtual unsigned long ReadAndLoop (
229 void* pBuffer,
230 unsigned long FrameCount,
231 PlaybackState* pPlaybackState
232 ) = 0;
233
234 virtual long SetPos(unsigned long FrameOffset) = 0;
235 virtual long GetPos() = 0;
236 };
237 } // namespace LinuxSampler
238
239 #endif // __LS_SAMPLE_H__

  ViewVC Help
Powered by ViewVC