/[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 2399 by persson, Sun Jan 13 17:22:23 2013 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 - 2013 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 65  namespace LinuxSampler { Line 69  namespace LinuxSampler {
69          }          }
70          TotalFrameCount = sfInfo.frames;          TotalFrameCount = sfInfo.frames;
71    
72            Loops = 0;
73            LoopStart = 0;
74            LoopEnd = 0;
75            SF_INSTRUMENT instrument;
76            if (sf_command(pSndFile, SFC_GET_INSTRUMENT,
77                           &instrument, sizeof(instrument)) != SF_FALSE) {
78                // TODO: instrument.basenote
79    #if HAVE_SF_INSTRUMENT_LOOPS
80                if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) {
81                    Loops = 1;
82                    LoopStart = instrument.loops[0].start;
83                    LoopEnd = instrument.loops[0].end;
84                }
85    #endif
86            }
87          if(!DontClose) Close();          if(!DontClose) Close();
88    
89    #if HAVE_DECL_SF_FORMAT_FLAC
90            if (FrameSize == 3 * ChannelCount &&
91                (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC) {
92                pConvertBuffer = new int[CONVERT_BUFFER_SIZE];
93            }
94    #endif
95      }      }
96    
97      SampleFile::~SampleFile() {      SampleFile::~SampleFile() {
98          Close();          Close();
99            ReleaseSampleData();
100            delete[] pConvertBuffer;
101      }      }
102    
103      void SampleFile::Open() {      void SampleFile::Open() {
# Line 115  namespace LinuxSampler { Line 143  namespace LinuxSampler {
143      }      }
144    
145      Sample::buffer_t SampleFile::LoadSampleData() {      Sample::buffer_t SampleFile::LoadSampleData() {
146          return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, 0); // 0 amount of NullSamples          return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), 0); // 0 amount of NullSamples
147      }      }
148    
149      Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {      Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) {
# Line 123  namespace LinuxSampler { Line 151  namespace LinuxSampler {
151      }      }
152    
153      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) {
154          return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, NullFrameCount);          return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), NullFrameCount);
155      }      }
156    
157      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {      Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) {
158          Open();          Open();
159          if (FrameCount > this->TotalFrameCount) FrameCount = this->TotalFrameCount;          if (FrameCount > GetTotalFrameCount()) FrameCount = GetTotalFrameCount();
160            
161            if (Offset > MaxOffset && FrameCount < GetTotalFrameCount()) {
162                FrameCount = FrameCount + Offset > GetTotalFrameCount() ? GetTotalFrameCount() - Offset : FrameCount;
163                // Offset the RAM cache
164                RAMCacheOffset = Offset;
165            }
166          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;          if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart;
167          unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;          unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize;
168          SetPos(0, SEEK_SET); // reset read position to begin of sample          SetPos(RAMCacheOffset, SEEK_SET); // reset read position to playback start point
169          RAMCache.pStart            = new int8_t[allocationsize];          RAMCache.pStart            = new int8_t[allocationsize];
170    
171          RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;          RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize;
# Line 144  namespace LinuxSampler { Line 178  namespace LinuxSampler {
178    
179      long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {      long SampleFile::Read(void* pBuffer, unsigned long FrameCount) {
180          Open();          Open();
181          int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());          
182          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)
183    
184            // ogg and flac files must be read with sf_readf, not
185            // sf_read_raw. On big endian machines, sf_readf_short is also
186            // used for 16 bit wav files, to get automatic endian
187            // conversion (for 24 bit samples this is handled in
188            // Synthesize::GetSample instead).
189    
190    #if WORDS_BIGENDIAN || HAVE_DECL_SF_FORMAT_VORBIS || HAVE_DECL_SF_FORMAT_FLAC
191            if (
192    #if WORDS_BIGENDIAN
193                FrameSize == 2 * ChannelCount
194    #else
195    #if HAVE_DECL_SF_FORMAT_VORBIS
196                ((Format & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS)
197    #if HAVE_DECL_SF_FORMAT_FLAC
198                ||
199    #endif
200    #endif
201    #if HAVE_DECL_SF_FORMAT_FLAC
202                (FrameSize == 2 * ChannelCount &&
203                 (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC)
204    #endif
205    #endif
206                ) {
207                return sf_readf_short(pSndFile, static_cast<short*>(pBuffer), FrameCount);
208    #if HAVE_DECL_SF_FORMAT_FLAC
209            } else if (FrameSize == 3 * ChannelCount &&
210                       (Format & SF_FORMAT_TYPEMASK) == SF_FORMAT_FLAC) {
211                // 24 bit flac needs to be converted from the 32 bit
212                // integers returned by libsndfile
213                int j = 0;
214                sf_count_t count = FrameCount;
215                const sf_count_t bufsize = CONVERT_BUFFER_SIZE / ChannelCount;
216                unsigned char* const dst = static_cast<unsigned char*>(pBuffer);
217                while (count > 0) {
218                    int n = sf_readf_int(pSndFile, pConvertBuffer, std::min(count, bufsize));
219                    if (n <= 0) break;
220                    for (int i = 0 ; i < n * ChannelCount ; i++) {
221                        dst[j++] = pConvertBuffer[i] >> 8;
222                        dst[j++] = pConvertBuffer[i] >> 16;
223                        dst[j++] = pConvertBuffer[i] >> 24;
224                    }
225                    count -= n;
226                }
227                return FrameCount - count;
228    #endif            
229            } else
230    #endif
231            {
232                int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize());
233                return bytes / GetFrameSize();
234            }
235      }      }
236    
237      unsigned long SampleFile::ReadAndLoop (      unsigned long SampleFile::ReadAndLoop (

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

  ViewVC Help
Powered by ViewVC