/[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 2012 - (hide annotations) (download)
Fri Oct 23 17:53:17 2009 UTC (14 years, 5 months ago) by iliev
File size: 6984 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 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     case SF_FORMAT_PCM_16:
53     case SF_FORMAT_DPCM_8:
54     case SF_FORMAT_DPCM_16:
55     FrameSize = sizeof(short) * ChannelCount;
56     break;
57     default:
58     FrameSize = sizeof(int) * ChannelCount;
59     }
60     TotalFrameCount = sfInfo.frames;
61    
62     if(!DontClose) Close();
63     }
64    
65     SampleFile::~SampleFile() {
66     Close();
67     }
68    
69     void SampleFile::Open() {
70     if(pSndFile) return; // Already opened
71     SF_INFO sfInfo;
72     sfInfo.format = 0;
73     pSndFile = sf_open(File.c_str(), SFM_READ, &sfInfo);
74     if(pSndFile == NULL) throw Exception(File + ": Can't load sample");
75     #if CONFIG_DEVMODE
76     std::cout << "Number of opened sample files: " << ++SampleFile_OpenFilesCount << std::endl;
77     #endif
78     }
79    
80     void SampleFile::Close() {
81     if(pSndFile == NULL) return;
82     if(sf_close(pSndFile)) std::cerr << "Sample::Close() " << "Failed to close " << File << std::endl;
83     pSndFile = NULL;
84     #if CONFIG_DEVMODE
85     std::cout << "Number of opened sample files: " << --SampleFile_OpenFilesCount << std::endl;
86     #endif
87     }
88    
89     long SampleFile::SetPos(unsigned long FrameOffset) {
90     return SetPos(FrameOffset, SEEK_SET);
91     }
92    
93     long SampleFile::SetPos(unsigned long FrameCount, int Whence) {
94     if(pSndFile == NULL) {
95     std::cerr << "Sample::SetPos() " << File << " not opened" << std::endl;
96     return -1;
97     }
98    
99     return sf_seek(pSndFile, FrameCount, Whence);
100     }
101    
102     long SampleFile::GetPos() {
103     if(pSndFile == NULL) {
104     std::cerr << "Sample::GetPos() " << File << " not opened" << std::endl;
105     return -1;
106     }
107    
108     return sf_seek(pSndFile, 0, SEEK_CUR);
109     }
110    
111     Sample::buffer_t SampleFile::LoadSampleData() {
112     return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, 0); // 0 amount of NullSamples
113     }
114    
115     Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {
116     return LoadSampleDataWithNullSamplesExtension(FrameCount, 0); // 0 amount of NullSamples
117     }
118    
119     Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {
120     return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, NullFrameCount);
121     }
122    
123     Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {
124     Open();
125     if (FrameCount > this->TotalFrameCount) FrameCount = this->TotalFrameCount;
126     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
127     unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;
128     SetPos(0, SEEK_SET); // reset read position to begin of sample
129     RAMCache.pStart = new int8_t[allocationsize];
130    
131     RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;
132     RAMCache.NullExtensionSize = allocationsize - RAMCache.Size;
133     // fill the remaining buffer space with silence samples
134     memset((int8_t*)RAMCache.pStart + RAMCache.Size, 0, RAMCache.NullExtensionSize);
135     Close();
136     return GetCache();
137     }
138    
139     long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {
140     Open();
141     if(FrameSize == sizeof(short) * ChannelCount) {
142     return sf_readf_short(pSndFile, (short*)pBuffer, FrameCount);
143     } else {
144     return sf_readf_int(pSndFile, (int*)pBuffer, FrameCount);
145     }
146     }
147    
148     unsigned long SampleFile::ReadAndLoop (
149     void* pBuffer,
150     unsigned long FrameCount,
151     PlaybackState* pPlaybackState
152     ) {
153     // TODO:
154     SetPos(pPlaybackState->position);
155     Read(pBuffer, FrameCount);
156     pPlaybackState->position = GetPos();
157     }
158    
159     void SampleFile::ReleaseSampleData() {
160     if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
161     RAMCache.pStart = NULL;
162     RAMCache.Size = 0;
163     RAMCache.NullExtensionSize = 0;
164     }
165    
166     Sample::buffer_t SampleFile::GetCache() {
167     // return a copy of the buffer_t structure
168     buffer_t result;
169     result.Size = this->RAMCache.Size;
170     result.pStart = this->RAMCache.pStart;
171     result.NullExtensionSize = this->RAMCache.NullExtensionSize;
172     return result;
173     }
174     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC