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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2399 - (show annotations) (download) (as text)
Sun Jan 13 17:22:23 2013 UTC (11 years, 2 months ago) by persson
File MIME type: text/x-c++hdr
File size: 7404 byte(s)
* sfz engine: added FLAC support (#191)

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003 - 2009 Christian Schoenebeck *
6 * Copyright (C) 2009 - 2013 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_SAMPLEFILE_H__
25 #define __LS_SAMPLEFILE_H__
26
27 #include "Sample.h"
28
29 #include <sndfile.h>
30 #include "../../common/global.h"
31
32 namespace LinuxSampler {
33 class SampleFile : public Sample {
34 public:
35 SampleFile(String File, bool DontClose = false);
36 virtual ~SampleFile();
37
38 String GetFile() { return File; }
39
40 virtual String GetName() { return File; }
41 virtual int GetSampleRate() { return SampleRate; }
42 virtual int GetChannelCount() { return ChannelCount; }
43 virtual long GetTotalFrameCount() { return TotalFrameCount; }
44 virtual int GetFrameSize() { return FrameSize; }
45 virtual int GetLoops() { return Loops; }
46 virtual uint GetLoopStart() { return LoopStart; }
47 virtual uint GetLoopEnd() { return LoopEnd; }
48
49 virtual buffer_t LoadSampleData();
50 virtual buffer_t LoadSampleData(unsigned long FrameCount);
51 virtual buffer_t LoadSampleDataWithNullSamplesExtension(uint NullFrameCount);
52 virtual buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount);
53 virtual void ReleaseSampleData();
54 virtual buffer_t GetCache();
55 virtual long Read(void* pBuffer, unsigned long FrameCount);
56
57 virtual unsigned long ReadAndLoop (
58 void* pBuffer,
59 unsigned long FrameCount,
60 PlaybackState* pPlaybackState
61 );
62
63 virtual long SetPos(unsigned long FrameOffset);
64 virtual long GetPos();
65
66 void Open();
67 void Close();
68
69 private:
70 String File;
71 int SampleRate;
72 int ChannelCount;
73 int Format;
74 int FrameSize; ///< In bytes
75 long TotalFrameCount;
76 int Loops;
77 uint LoopStart;
78 uint LoopEnd;
79
80 SNDFILE* pSndFile;
81
82 buffer_t RAMCache; ///< Buffers samples (already uncompressed) in RAM.
83
84 int* pConvertBuffer;
85
86 long SetPos(unsigned long FrameCount, int Whence);
87 };
88
89 template <class R>
90 class SampleFileBase : public SampleFile {
91 public:
92 SampleFileBase(String File, bool DontClose = false) : SampleFile(File, DontClose) { }
93 virtual ~SampleFileBase() { }
94
95
96
97 /**
98 * Reads \a SampleCount number of sample points from the position stored
99 * in \a pPlaybackState into the buffer pointed by \a pBuffer and moves
100 * the position within the sample respectively, this method honors the
101 * looping informations of the sample (if any). Use this
102 * method if you don't want to load the sample into RAM, thus for disk
103 * streaming. All this methods needs to know to proceed with streaming
104 * for the next time you call this method is stored in \a pPlaybackState.
105 * You have to allocate and initialize the playback_state_t structure by
106 * yourself before you use it to stream a sample:
107 * @code
108 * PlaybackState playbackstate;
109 * playbackstate.position = 0;
110 * playbackstate.reverse = false;
111 * playbackstate.loop_cycles_left = pSample->LoopPlayCount;
112 * @endcode
113 * You don't have to take care of things like if there is actually a loop
114 * defined or if the current read position is located within a loop area.
115 * The method already handles such cases by itself.
116 *
117 * @param pBuffer destination buffer
118 * @param FrameCount number of sample points to read
119 * @param pPlaybackState will be used to store and reload the playback
120 * state for the next ReadAndLoop() call
121 * @returns number of successfully read sample points
122 */
123 unsigned long ReadAndLoop (
124 void* pBuffer,
125 unsigned long FrameCount,
126 PlaybackState* pPlaybackState,
127 R* pRegion
128 ) {
129 // TODO: startAddrsCoarseOffset, endAddrsCoarseOffset
130 unsigned long samplestoread = FrameCount, totalreadsamples = 0, readsamples, samplestoloopend;
131 uint8_t* pDst = (uint8_t*) pBuffer;
132 SetPos(pPlaybackState->position);
133 if (pRegion->HasLoop()) {
134 do {
135 if (GetPos() > pRegion->GetLoopEnd()) SetPos(pRegion->GetLoopStart());
136 samplestoloopend = pRegion->GetLoopEnd() - GetPos();
137 readsamples = Read(&pDst[totalreadsamples * GetFrameSize()], Min(samplestoread, samplestoloopend));
138 samplestoread -= readsamples;
139 totalreadsamples += readsamples;
140 if (readsamples == samplestoloopend) {
141 SetPos(pRegion->GetLoopStart());
142 }
143 } while (samplestoread && readsamples);
144 } else {
145 totalreadsamples = Read(pBuffer, FrameCount);
146 }
147
148 pPlaybackState->position = GetPos();
149
150 return totalreadsamples;
151 }
152
153 protected:
154 inline long Min(long A, long B) { return (A > B) ? B : A; }
155 };
156 } // namespace LinuxSampler
157
158 #endif // __LS_SAMPLEFILE_H__

  ViewVC Help
Powered by ViewVC