/[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 2216 - (show annotations) (download) (as text)
Mon Jul 25 17:21:16 2011 UTC (12 years, 8 months ago) by iliev
File MIME type: text/x-c++hdr
File size: 13803 byte(s)
* sfz: added support for sample offset (offset)

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 uint Offset; // The offset used to play the sample (in sample units)
59
60 uint RAMCacheOffset; // The offset of the RAM cache from the sample start (in sample units)
61
62 /*
63 * Specifies the maximum offset (in frames) that can be set without
64 * the need to offset the RAM cache.
65 */
66 uint MaxOffset;
67
68 Sample(): MaxOffset(2000), Offset(0), RAMCacheOffset(0) { }
69 virtual ~Sample() { }
70
71 virtual String GetName() = 0;
72 virtual int GetSampleRate() = 0;
73 virtual int GetChannelCount() = 0;
74
75 /**
76 * @returns The frame size in bytes
77 */
78 virtual int GetFrameSize() = 0;
79
80 /**
81 * @returns The total number of frames in this sample
82 */
83 virtual long GetTotalFrameCount() = 0;
84
85 /**
86 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
87 * ReleaseSampleData() to free the memory if you don't need the cached
88 * sample data anymore.
89 *
90 * @returns buffer_t structure with start address and size of the buffer
91 * in bytes
92 * @see ReleaseSampleData(), Read(), SetPos()
93 */
94 virtual buffer_t LoadSampleData() = 0;
95
96 /**
97 * Reads (uncompresses if needed) and caches the first \a FrameCount
98 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
99 * memory space if you don't need the cached samples anymore. There is no
100 * guarantee that exactly \a SampleCount samples will be cached; this is
101 * not an error. The size will be eventually truncated e.g. to the
102 * beginning of a frame of a compressed sample. This is done for
103 * efficiency reasons while streaming the wave by your sampler engine
104 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
105 * that will be returned to determine the actual cached samples, but note
106 * that the size is given in bytes! You get the number of actually cached
107 * samples by dividing it by the frame size of the sample:
108 * @code
109 * buffer_t buf = pSample->LoadSampleData(acquired_samples);
110 * long cachedsamples = buf.Size / pSample->FrameSize;
111 * @endcode
112 *
113 * @param FrameCount - number of sample points to load into RAM
114 * @returns buffer_t structure with start address and size of
115 * the cached sample data in bytes
116 * @see ReleaseSampleData(), Read(), SetPos()
117 */
118 virtual buffer_t LoadSampleData(unsigned long FrameCount) = 0;
119
120 /**
121 * Loads (and uncompresses if needed) the whole sample wave into RAM. Use
122 * ReleaseSampleData() to free the memory if you don't need the cached
123 * sample data anymore.
124 * The method will add \a NullSamplesCount silence samples past the
125 * official buffer end (this won't affect the 'Size' member of the
126 * buffer_t structure, that means 'Size' always reflects the size of the
127 * actual sample data, the buffer might be bigger though). Silence
128 * samples past the official buffer are needed for differential
129 * algorithms that always have to take subsequent samples into account
130 * (resampling/interpolation would be an important example) and avoids
131 * memory access faults in such cases.
132 *
133 * @param NullSamplesCount - number of silence samples the buffer should
134 * be extended past it's data end
135 * @returns buffer_t structure with start address and
136 * size of the buffer in bytes
137 * @see ReleaseSampleData(), Read(), SetPos()
138 */
139 virtual buffer_t LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) = 0;
140
141 /**
142 * Reads (uncompresses if needed) and caches the first \a SampleCount
143 * numbers of SamplePoints in RAM. Use ReleaseSampleData() to free the
144 * memory space if you don't need the cached samples anymore. There is no
145 * guarantee that exactly \a SampleCount samples will be cached; this is
146 * not an error. The size will be eventually truncated e.g. to the
147 * beginning of a frame of a compressed sample. This is done for
148 * efficiency reasons while streaming the wave by your sampler engine
149 * later. Read the <i>Size</i> member of the <i>buffer_t</i> structure
150 * that will be returned to determine the actual cached samples, but note
151 * that the size is given in bytes! You get the number of actually cached
152 * samples by dividing it by the frame size of the sample:
153 * @code
154 * buffer_t buf = pSample->LoadSampleDataWithNullSamplesExtension(acquired_samples, null_samples);
155 * long cachedsamples = buf.Size / pSample->FrameSize;
156 * @endcode
157 * The method will add \a NullSamplesCount silence samples past the
158 * official buffer end (this won't affect the 'Size' member of the
159 * buffer_t structure, that means 'Size' always reflects the size of the
160 * actual sample data, the buffer might be bigger though). Silence
161 * samples past the official buffer are needed for differential
162 * algorithms that always have to take subsequent samples into account
163 * (resampling/interpolation would be an important example) and avoids
164 * memory access faults in such cases.
165 *
166 * @param FrameCount - number of sample points to load into RAM
167 * @param NullFramesCount - number of silence samples the buffer should
168 * be extended past it's data end
169 * @returns buffer_t structure with start address and
170 * size of the cached sample data in bytes
171 * @see ReleaseSampleData(), Read()
172 */
173 virtual buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) = 0;
174
175 /**
176 * Frees the cached sample from RAM if loaded with
177 * <i>LoadSampleData()</i> previously.
178 *
179 * @see LoadSampleData();
180 */
181 virtual void ReleaseSampleData() = 0;
182
183 /**
184 * Returns current cached sample points. A buffer_t structure will be
185 * returned which contains address pointer to the begin of the cache and
186 * the size of the cached sample data in bytes. Use
187 * <i>LoadSampleData()</i> to cache a specific amount of sample points in
188 * RAM.
189 *
190 * @returns buffer_t structure with current cached sample points
191 * @see LoadSampleData();
192 */
193 virtual buffer_t GetCache() = 0;
194
195 /**
196 * Reads \a FrameCount number of frames from the current
197 * position into the buffer pointed by \a pBuffer and increments the
198 * position within the sample. Use this method
199 * and <i>SetPos()</i> if you don't want to load the sample into RAM,
200 * thus for disk streaming.
201 *
202 * For 16 bit samples, the data in the buffer will be int16_t
203 * (using native endianness). For 24 bit, the buffer will
204 * contain 4 bytes per sample.
205 *
206 * @param pBuffer destination buffer
207 * @param SampleCount number of sample points to read
208 * @returns number of successfully read sample points
209 */
210 virtual long Read(void* pBuffer, unsigned long FrameCount) = 0;
211
212 /**
213 * Reads \a SampleCount number of sample points from the position stored
214 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
215 * the position within the sample respectively, this method honors the
216 * looping informations of the sample (if any). Use this
217 * method if you don't want to load the sample into RAM, thus for disk
218 * streaming. All this methods needs to know to proceed with streaming
219 * for the next time you call this method is stored in \a pPlaybackState.
220 * You have to allocate and initialize the playback_state_t structure by
221 * yourself before you use it to stream a sample:
222 * @code
223 * PlaybackState playbackstate;
224 * playbackstate.position = 0;
225 * playbackstate.reverse = false;
226 * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
227 * @endcode
228 * You don't have to take care of things like if there is actually a loop
229 * defined or if the current read position is located within a loop area.
230 * The method already handles such cases by itself.
231 *
232 * @param pBuffer destination buffer
233 * @param FrameCount number of sample points to read
234 * @param pPlaybackState will be used to store and reload the playback
235 * state for the next ReadAndLoop() call
236 * @returns number of successfully read sample points
237 */
238 virtual unsigned long ReadAndLoop (
239 void* pBuffer,
240 unsigned long FrameCount,
241 PlaybackState* pPlaybackState
242 ) = 0;
243
244 virtual long SetPos(unsigned long FrameOffset) = 0;
245 virtual long GetPos() = 0;
246 };
247 } // namespace LinuxSampler
248
249 #endif // __LS_SAMPLE_H__

  ViewVC Help
Powered by ViewVC