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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2019 - (hide 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 iliev 2012 /***************************************************************************
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 iliev 2019 case SF_FORMAT_DPCM_8:
53     FrameSize = ChannelCount;
54     break;
55 iliev 2012 case SF_FORMAT_PCM_16:
56     case SF_FORMAT_DPCM_16:
57 iliev 2019 FrameSize = 2 * ChannelCount;
58 iliev 2012 break;
59 iliev 2019 case SF_FORMAT_PCM_24:
60     case SF_FORMAT_DWVW_24:
61     FrameSize = 3 * ChannelCount;
62     break;
63 iliev 2012 default:
64 iliev 2019 FrameSize = 2 * ChannelCount;
65 iliev 2012 }
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 iliev 2019 int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());
148     return bytes / GetFrameSize();
149 iliev 2012 }
150    
151     unsigned long SampleFile::ReadAndLoop (
152     void* pBuffer,
153     unsigned long FrameCount,
154     PlaybackState* pPlaybackState
155     ) {
156     // TODO:
157     SetPos(pPlaybackState->position);
158 iliev 2018 unsigned long count = Read(pBuffer, FrameCount);
159 iliev 2012 pPlaybackState->position = GetPos();
160 iliev 2018 return count;
161 iliev 2012 }
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