/[svn]/libgig/trunk/src/gigextract.cpp
ViewVC logotype

Diff of /libgig/trunk/src/gigextract.cpp

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

revision 608 by schoenebeck, Fri Jun 3 14:35:44 2005 UTC revision 933 by schoenebeck, Fri Nov 24 12:50:05 2006 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file loader library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2005 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2006 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8     *   This program is part of libgig.                                       *
9     *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   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  *
12   *   the Free Software Foundation; either version 2 of the License, or     *   *   the Free Software Foundation; either version 2 of the License, or     *
# Line 172  void ExtractSamples(gig::File* gig, char Line 174  void ExtractSamples(gig::File* gig, char
174      openAFlib();      openAFlib();
175  #endif // !HAVE_SNDFILE  #endif // !HAVE_SNDFILE
176      uint8_t* pWave  = NULL;      uint8_t* pWave  = NULL;
177        int* pIntWave = NULL;
178      long BufferSize = 0;      long BufferSize = 0;
179      int samples     = 0;      int samples     = 0;
180        gig::buffer_t decompressionBuffer;
181        decompressionBuffer.Size = 0;
182        unsigned long decompressionBufferSize = 0;
183      cout << "Seeking for available samples..." << flush;      cout << "Seeking for available samples..." << flush;
184      gig::Sample* pSample = gig->GetFirstSample();      gig::Sample* pSample = gig->GetFirstSample();
185      cout << "OK" << endl << flush;      cout << "OK" << endl << flush;
# Line 206  void ExtractSamples(gig::File* gig, char Line 212  void ExtractSamples(gig::File* gig, char
212    
213    
214  #if USE_DISK_STREAMING  #if USE_DISK_STREAMING
215          long neededsize = (pSample->Compressed) ? 10485760 /* 10 MB buffer */          long neededsize = pSample->BitDepth == 24 ?
216                                                  : pSample->SamplesTotal * pSample->FrameSize;              pSample->SamplesTotal * pSample->Channels * sizeof(int) :
217                pSample->SamplesTotal * pSample->FrameSize;
218          if (BufferSize < neededsize) {          if (BufferSize < neededsize) {
219              if (pWave) delete[] pWave;              if (pWave) delete[] pWave;
220              pWave = new uint8_t[neededsize];              pWave = new uint8_t[neededsize];
221              BufferSize = neededsize;              BufferSize = neededsize;
222          }          }
223            pIntWave = (int*)pWave;
224  #  if HASHED_READS_TEST  #  if HASHED_READS_TEST
225          unsigned long readsamples     = 0,          unsigned long readinthisrun   = 0,
                       readinthisrun   = 0,  
226                        samplepiecesize = 2000;                        samplepiecesize = 2000;
227          uint8_t* pSamplePiece = pWave;          uint8_t* pSamplePiece = pWave;
228          do { // we read the sample in small pieces and increment the size with each run just to test streaming capability          do { // we read the sample in small pieces and increment the size with each run just to test streaming capability
229              readinthisrun = pSample->Read(pSamplePiece, ++samplepiecesize);              readinthisrun = pSample->Read(pSamplePiece, ++samplepiecesize);
230              // 24 bit is truncated to 16 by Sample::Read at the moment              pSamplePiece += readinthisrun * pSample->FrameSize;
             pSamplePiece += readinthisrun * (2 * pSample->Channels); // readinthisrun * pSample->FrameSize;  
             readsamples  += readinthisrun;  
231          } while (readinthisrun == samplepiecesize);          } while (readinthisrun == samplepiecesize);
232    
         if (pSample->Compressed) { // hack  
             pSample->SamplesTotal = readsamples;  
             pSample->BitDepth = 16;  
         }  
233  #  else // read in one piece  #  else // read in one piece
234          if (pSample->Compressed) {          if (pSample->Compressed) {
235              pSample->SamplesTotal = pSample->Read(pWave, 10485760 >> 2); // assumes 16 bit stereo              if (decompressionBufferSize < pSample->SamplesTotal) {
236          }                  gig::Sample::DestroyDecompressionBuffer(decompressionBuffer);
237          else {                  decompressionBuffer = gig::Sample::CreateDecompressionBuffer(pSample->SamplesTotal);
238                    decompressionBufferSize = pSample->SamplesTotal;
239                }
240                pSample->Read(pWave, pSample->SamplesTotal, &decompressionBuffer);
241            } else {
242              pSample->Read(pWave, pSample->SamplesTotal);              pSample->Read(pWave, pSample->SamplesTotal);
243          }          }
244  #  endif // HASHED_READS_TEST  #  endif // HASHED_READS_TEST
245  #else // no disk streaming  #else // no disk streaming
246          if (pSample->Compressed) {          if (pSample->Compressed) {
247              cout << "Sorry, sample is compressed and Sample::LoadSampleData() has no decompression routine yet! - Solution: set USE_DISK_STREAMING in gigextract.cpp (line 29) to 1 and recompile!" << endl;              cout << "Sorry, sample is compressed and Sample::LoadSampleData() only decompresses the beginning of the sample - Solution: set USE_DISK_STREAMING in gigextract.cpp (line 32) to 1 and recompile!" << endl;
248            } else {
249                gig::buffer_t buffer = pSample->LoadSampleData(); // load wave into RAM
250                pWave = static_cast<uint8_t*>(buffer.pStart);
251                if (pSample->BitDepth == 24) {
252                    long neededsize = pSample->SamplesTotal * pSample->Channels;
253                    if (BufferSize < neededsize) {
254                        if (pIntWave) delete[] pIntWave;
255                        pIntWave = new int[neededsize];
256                        BufferSize = neededsize;
257                    }
258                }
259          }          }
         else pWave = (uint8_t*) pSample->LoadSampleData(); // load wave into RAM  
260  #endif // USE_DISK_STREAMING  #endif // USE_DISK_STREAMING
261          if (pWave) {          if (pWave) {
262    
263                // Both libsndfile and libaudiofile uses int for 24 bit
264                // samples. libgig however returns 3 bytes per sample, so
265                // we have to convert the wave data before writing.
266                if (pSample->BitDepth == 24) {
267                    int n = pSample->SamplesTotal * pSample->Channels;
268                    for (int i = n - 1 ; i >= 0 ; i--) {
269    #if HAVE_SNDFILE
270                        pIntWave[i] = pWave[i * 3] << 8 | pWave[i * 3 + 1] << 16 | pWave[i * 3 + 2] << 24;
271    #else
272                        pIntWave[i] = pWave[i * 3] | pWave[i * 3 + 1] << 8 | pWave[i * 3 + 2] << 16;
273    #endif
274                    }
275                }
276    
277              int res = writeWav(filename.c_str(),              int res = writeWav(filename.c_str(),
278                                 pWave,                                 pSample->BitDepth == 24 ? static_cast<void*>(pIntWave) : pWave,
279                                 pSample->SamplesTotal,                                 pSample->SamplesTotal,
280                                 pSample->Channels,                                 pSample->Channels,
281                                 pSample->BitDepth,                                 pSample->BitDepth,
# Line 258  void ExtractSamples(gig::File* gig, char Line 288  void ExtractSamples(gig::File* gig, char
288    
289          pSample = gig->GetNextSample();          pSample = gig->GetNextSample();
290      }      }
291      if (pWave) delete[] (uint8_t*) pWave;      gig::Sample::DestroyDecompressionBuffer(decompressionBuffer);
292    #if USE_DISK_STREAMING
293        if (pWave) delete[] pWave;
294    #else
295        if (pIntWave) delete[] pIntWave;
296    #endif
297  #if !HAVE_SNDFILE // use libaudiofile  #if !HAVE_SNDFILE // use libaudiofile
298      closeAFlib();      closeAFlib();
299  #endif // !HAVE_SNDFILE  #endif // !HAVE_SNDFILE
# Line 272  int writeWav(const char* filename, void* Line 307  int writeWav(const char* filename, void*
307      switch (bitdepth) {      switch (bitdepth) {
308          case 8:          case 8:
309              format |= SF_FORMAT_PCM_S8;              format |= SF_FORMAT_PCM_S8;
             cout << "8 bit" << endl << flush;  
310              break;              break;
311          case 16:          case 16:
312              format |= SF_FORMAT_PCM_16;              format |= SF_FORMAT_PCM_16;
             cout << "16 bit" << endl << flush;  
313              break;              break;
314          case 24:          case 24:
315              format |= SF_FORMAT_PCM_24;              format |= SF_FORMAT_PCM_24;
             cout << "24 bit" << endl << flush;  
316              break;              break;
317          case 32:          case 32:
318              format |= SF_FORMAT_PCM_32;              format |= SF_FORMAT_PCM_32;
             cout << "32 bit" << endl << flush;  
319              break;              break;
320          default:          default:
321              cerr << "Error: Bithdepth " << ToString(bitdepth) << " not supported by libsndfile, ignoring sample!\n" << flush;              cerr << "Error: Bithdepth " << ToString(bitdepth) << " not supported by libsndfile, ignoring sample!\n" << flush;
# Line 299  int writeWav(const char* filename, void* Line 330  int writeWav(const char* filename, void*
330          cerr << "Error: Unable to open output file \'" << filename << "\'.\n" << flush;          cerr << "Error: Unable to open output file \'" << filename << "\'.\n" << flush;
331          return -1;          return -1;
332      }      }
333      if (sf_write_short(hfile, (short*)samples, channels * samplecount) != channels * samplecount) {      sf_count_t res = bitdepth == 24 ?
334            sf_write_int(hfile, static_cast<int*>(samples), channels * samplecount) :
335            sf_write_short(hfile, static_cast<short*>(samples), channels * samplecount);
336        if (res != channels * samplecount) {
337          cerr << sf_strerror(hfile) << endl << flush;          cerr << sf_strerror(hfile) << endl << flush;
338          sf_close(hfile);          sf_close(hfile);
339          return -1;          return -1;
# Line 347  void closeAFlib() { Line 381  void closeAFlib() {
381  #endif // !HAVE_SNDFILE  #endif // !HAVE_SNDFILE
382    
383  string Revision() {  string Revision() {
384      string s = "$Revision: 1.7 $";      string s = "$Revision: 1.9 $";
385      return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword      return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
386  }  }
387    

Legend:
Removed from v.608  
changed lines
  Added in v.933

  ViewVC Help
Powered by ViewVC