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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2019 by iliev, Tue Oct 27 19:36:09 2009 UTC revision 3054 by schoenebeck, Thu Dec 15 12:47:45 2016 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 - 2009 Christian Schoenebeck                       *   *   Copyright (C) 2003 - 2009 Christian Schoenebeck                       *
6   *   Copyright (C) 2009 Grigor Iliev                                       *   *   Copyright (C) 2009 - 2014 Grigor Iliev                                *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 22  Line 22 
22   ***************************************************************************/   ***************************************************************************/
23    
24  #include "SampleFile.h"  #include "SampleFile.h"
25    #include "../../common/global_private.h"
26  #include "../../common/Exception.h"  #include "../../common/Exception.h"
27    
28  #include <cstring>  #include <cstring>
29    
30    #define CONVERT_BUFFER_SIZE 4096
31    
32  namespace LinuxSampler {  namespace LinuxSampler {
33      #if CONFIG_DEVMODE      #if CONFIG_DEVMODE
34      int SampleFile_OpenFilesCount = 0;      int SampleFile_OpenFilesCount = 0;
# Line 34  namespace LinuxSampler { Line 37  namespace LinuxSampler {
37      SampleFile::SampleFile(String File, bool DontClose) {      SampleFile::SampleFile(String File, bool DontClose) {
38          this->File      = File;          this->File      = File;
39          this->pSndFile  = NULL;          this->pSndFile  = NULL;
40            pConvertBuffer  = NULL;
41    
42          SF_INFO sfInfo;          SF_INFO sfInfo;
43          sfInfo.format = 0;          sfInfo.format = 0;
# Line 46  namespace LinuxSampler { Line 50  namespace LinuxSampler {
50          ChannelCount = sfInfo.channels;          ChannelCount = sfInfo.channels;
51          Format = sfInfo.format;          Format = sfInfo.format;
52    
53          switch(Format & 0xF) {          switch(Format & SF_FORMAT_SUBMASK) {
54              case SF_FORMAT_PCM_S8:              case SF_FORMAT_PCM_S8:
55              case SF_FORMAT_PCM_U8:              case SF_FORMAT_PCM_U8:
56              case SF_FORMAT_DPCM_8:              case SF_FORMAT_DPCM_8:
# Line 58  namespace LinuxSampler { Line 62  namespace LinuxSampler {
62                  break;                  break;
63              case SF_FORMAT_PCM_24:              case SF_FORMAT_PCM_24:
64              case SF_FORMAT_DWVW_24:              case SF_FORMAT_DWVW_24:
65                case SF_FORMAT_PCM_32:
66                case SF_FORMAT_FLOAT:
67                  FrameSize = 3 * ChannelCount;                  FrameSize = 3 * ChannelCount;
68                  break;                  break;
69              default:              default:
# Line 65  namespace LinuxSampler { Line 71  namespace LinuxSampler {
71          }          }
72          TotalFrameCount = sfInfo.frames;          TotalFrameCount = sfInfo.frames;
73    
74            Loops = 0;
75            LoopStart = 0;
76            LoopEnd = 0;
77            SF_INSTRUMENT instrument;
78            if (sf_command(pSndFile, SFC_GET_INSTRUMENT,
79                           &instrument, sizeof(instrument)) != SF_FALSE) {
80                // TODO: instrument.basenote
81    #if HAVE_SF_INSTRUMENT_LOOPS
82                if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
83                    Loops = 1;
84                    LoopStart = instrument.loops[0].start;
85                    LoopEnd = instrument.loops[0].end;
86                }
87    #endif
88            }
89          if(!DontClose) Close();          if(!DontClose) Close();
90    
91            if (FrameSize == 3 * ChannelCount && (
92    #if HAVE_DECL_SF_FORMAT_FLAC
93                    (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC ||
94    #endif
95                    (Format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT ||
96                    (Format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_32)) {
97                pConvertBuffer = new int[CONVERT_BUFFER_SIZE];
98            }
99      }      }
100    
101      SampleFile::~SampleFile() {      SampleFile::~SampleFile() {
102          Close();          Close();
103            ReleaseSampleData();
104            delete[] pConvertBuffer;
105      }      }
106    
107      void SampleFile::Open() {      void SampleFile::Open() {
# Line 115  namespace LinuxSampler { Line 147  namespace LinuxSampler {
147      }      }
148    
149      Sample::buffer_t SampleFile::LoadSampleData() {      Sample::buffer_t SampleFile::LoadSampleData() {
150          return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, 0); // 0 amount of NullSamples          return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), 0); // 0 amount of NullSamples
151      }      }
152    
153      Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {      Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {
# Line 123  namespace LinuxSampler { Line 155  namespace LinuxSampler {
155      }      }
156    
157      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {
158          return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, NullFrameCount);          return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), NullFrameCount);
159      }      }
160    
161      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {
162          Open();          Open();
163          if (FrameCount > this->TotalFrameCount) FrameCount = this->TotalFrameCount;          if (FrameCount > GetTotalFrameCount()) FrameCount = GetTotalFrameCount();
164            
165            if (Offset > MaxOffset && FrameCount < GetTotalFrameCount()) {
166                FrameCount = FrameCount + Offset > GetTotalFrameCount() ? GetTotalFrameCount() - Offset : FrameCount;
167                // Offset the RAM cache
168                RAMCacheOffset = Offset;
169            }
170          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
171          unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;          unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;
172          SetPos(0, SEEK_SET); // reset read position to begin of sample          SetPos(RAMCacheOffset, SEEK_SET); // reset read position to playback start point
173          RAMCache.pStart            = new int8_t[allocationsize];          RAMCache.pStart            = new int8_t[allocationsize];
174    
175          RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;          RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;
# Line 144  namespace LinuxSampler { Line 182  namespace LinuxSampler {
182    
183      long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {      long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {
184          Open();          Open();
185          int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());          
186          return bytes / GetFrameSize();          if (GetPos() + FrameCount > GetTotalFrameCount()) FrameCount = GetTotalFrameCount() - GetPos(); // For the cases where a different sample end is specified (not the end of the file)
187    
188            // ogg and flac files must be read with sf_readf, not
189            // sf_read_raw. On big endian machines, sf_readf_short is also
190            // used for 16 bit wav files, to get automatic endian
191            // conversion (for 24 bit samples this is handled in
192            // Synthesize::GetSample instead).
193    
194    #if WORDS_BIGENDIAN || HAVE_DECL_SF_FORMAT_VORBIS || HAVE_DECL_SF_FORMAT_FLAC
195            if (
196    #if WORDS_BIGENDIAN
197                FrameSize == 2 * ChannelCount
198    #else
199    #if HAVE_DECL_SF_FORMAT_VORBIS
200                ((Format & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS)
201    #if HAVE_DECL_SF_FORMAT_FLAC
202                ||
203    #endif
204    #endif
205    #if HAVE_DECL_SF_FORMAT_FLAC
206                (FrameSize == 2 * ChannelCount &&
207                 (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC)
208    #endif
209    #endif
210                ) {
211                return sf_readf_short(pSndFile, static_cast<short*>(pBuffer), FrameCount);
212            } else if (FrameSize == 3 * ChannelCount && (
213    #if HAVE_DECL_SF_FORMAT_FLAC
214                           (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC ||
215    #endif
216                           (Format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT ||
217                           (Format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_32)) {
218                // 24 bit flac needs to be converted from the 32 bit
219                // integers returned by libsndfile. Float and 32 bit pcm
220                // are treated in the same way.
221                int j = 0;
222                sf_count_t count = FrameCount;
223                const sf_count_t bufsize = CONVERT_BUFFER_SIZE / ChannelCount;
224                unsigned char* const dst = static_cast<unsigned char*>(pBuffer);
225                while (count > 0) {
226                    int n = (int) sf_readf_int(pSndFile, pConvertBuffer, std::min(count, bufsize));
227                    if (n <= 0) break;
228                    for (int i = 0 ; i < n * ChannelCount ; i++) {
229                        dst[j++] = pConvertBuffer[i] >> 8;
230                        dst[j++] = pConvertBuffer[i] >> 16;
231                        dst[j++] = pConvertBuffer[i] >> 24;
232                    }
233                    count -= n;
234                }
235                return FrameCount - count;
236            } else
237    #endif
238            {
239                int bytes = (int)sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());
240                return bytes / GetFrameSize();
241            }
242      }      }
243    
244      unsigned long SampleFile::ReadAndLoop (      unsigned long SampleFile::ReadAndLoop (

Legend:
Removed from v.2019  
changed lines
  Added in v.3054

  ViewVC Help
Powered by ViewVC