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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2019 - (show annotations) (download)
Tue Oct 27 19:36:09 2009 UTC (14 years, 5 months ago) by iliev
File size: 7104 byte(s)
* SFZ format engine: implemented 24 bit support

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 #include "SampleFile.h"
25 #include "../../common/Exception.h"
26
27 #include <cstring>
28
29 namespace LinuxSampler {
30 #if CONFIG_DEVMODE
31 int SampleFile_OpenFilesCount = 0;
32 #endif
33
34 SampleFile::SampleFile(String File, bool DontClose) {
35 this->File = File;
36 this->pSndFile = NULL;
37
38 SF_INFO sfInfo;
39 sfInfo.format = 0;
40 pSndFile = sf_open(File.c_str(), SFM_READ, &sfInfo);
41 if(pSndFile == NULL) throw Exception(File + ": Can't get sample info: " + String(sf_strerror (NULL)));
42 #if CONFIG_DEVMODE
43 std::cout << "Number of opened sample files: " << ++SampleFile_OpenFilesCount << std::endl;
44 #endif
45 SampleRate = sfInfo.samplerate;
46 ChannelCount = sfInfo.channels;
47 Format = sfInfo.format;
48
49 switch(Format & 0xF) {
50 case SF_FORMAT_PCM_S8:
51 case SF_FORMAT_PCM_U8:
52 case SF_FORMAT_DPCM_8:
53 FrameSize = ChannelCount;
54 break;
55 case SF_FORMAT_PCM_16:
56 case SF_FORMAT_DPCM_16:
57 FrameSize = 2 * ChannelCount;
58 break;
59 case SF_FORMAT_PCM_24:
60 case SF_FORMAT_DWVW_24:
61 FrameSize = 3 * ChannelCount;
62 break;
63 default:
64 FrameSize = 2 * ChannelCount;
65 }
66 TotalFrameCount = sfInfo.frames;
67
68 if(!DontClose) Close();
69 }
70
71 SampleFile::~SampleFile() {
72 Close();
73 }
74
75 void SampleFile::Open() {
76 if(pSndFile) return; // Already opened
77 SF_INFO sfInfo;
78 sfInfo.format = 0;
79 pSndFile = sf_open(File.c_str(), SFM_READ, &sfInfo);
80 if(pSndFile == NULL) throw Exception(File + ": Can't load sample");
81 #if CONFIG_DEVMODE
82 std::cout << "Number of opened sample files: " << ++SampleFile_OpenFilesCount << std::endl;
83 #endif
84 }
85
86 void SampleFile::Close() {
87 if(pSndFile == NULL) return;
88 if(sf_close(pSndFile)) std::cerr << "Sample::Close() " << "Failed to close " << File << std::endl;
89 pSndFile = NULL;
90 #if CONFIG_DEVMODE
91 std::cout << "Number of opened sample files: " << --SampleFile_OpenFilesCount << std::endl;
92 #endif
93 }
94
95 long SampleFile::SetPos(unsigned long FrameOffset) {
96 return SetPos(FrameOffset, SEEK_SET);
97 }
98
99 long SampleFile::SetPos(unsigned long FrameCount, int Whence) {
100 if(pSndFile == NULL) {
101 std::cerr << "Sample::SetPos() " << File << " not opened" << std::endl;
102 return -1;
103 }
104
105 return sf_seek(pSndFile, FrameCount, Whence);
106 }
107
108 long SampleFile::GetPos() {
109 if(pSndFile == NULL) {
110 std::cerr << "Sample::GetPos() " << File << " not opened" << std::endl;
111 return -1;
112 }
113
114 return sf_seek(pSndFile, 0, SEEK_CUR);
115 }
116
117 Sample::buffer_t SampleFile::LoadSampleData() {
118 return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, 0); // 0 amount of NullSamples
119 }
120
121 Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {
122 return LoadSampleDataWithNullSamplesExtension(FrameCount, 0); // 0 amount of NullSamples
123 }
124
125 Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {
126 return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, NullFrameCount);
127 }
128
129 Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {
130 Open();
131 if (FrameCount > this->TotalFrameCount) FrameCount = this->TotalFrameCount;
132 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
133 unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;
134 SetPos(0, SEEK_SET); // reset read position to begin of sample
135 RAMCache.pStart = new int8_t[allocationsize];
136
137 RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;
138 RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
139 // fill the remaining buffer space with silence samples
140 memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
141 Close();
142 return GetCache();
143 }
144
145 long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {
146 Open();
147 int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());
148 return bytes / GetFrameSize();
149 }
150
151 unsigned long SampleFile::ReadAndLoop (
152 void* pBuffer,
153 unsigned long FrameCount,
154 PlaybackState* pPlaybackState
155 ) {
156 // TODO:
157 SetPos(pPlaybackState->position);
158 unsigned long count = Read(pBuffer, FrameCount);
159 pPlaybackState->position = GetPos();
160 return count;
161 }
162
163 void SampleFile::ReleaseSampleData() {
164 if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
165 RAMCache.pStart = NULL;
166 RAMCache.Size = 0;
167 RAMCache.NullExtensionSize = 0;
168 }
169
170 Sample::buffer_t SampleFile::GetCache() {
171 // return a copy of the buffer_t structure
172 buffer_t result;
173 result.Size = this->RAMCache.Size;
174 result.pStart = this->RAMCache.pStart;
175 result.NullExtensionSize = this->RAMCache.NullExtensionSize;
176 return result;
177 }
178 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC