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

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

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

revision 2779 by persson, Sun Dec 2 16:30:30 2012 UTC revision 2780 by schoenebeck, Thu Jul 2 20:04:16 2015 UTC
# Line 1404  namespace sf2 { Line 1404  namespace sf2 {
1404          return (pCkSmpl->GetPos() - (Start * 2)) / 2;          return (pCkSmpl->GetPos() - (Start * 2)) / 2;
1405      }      }
1406    
1407      /**      // Actual implementation of Sample::Read*() code. Wrapped into a template for a) runtime effeciency and b) code redundancy reasons.
1408       * Reads \a SampleCount number of sample points from the current      template<bool CLEAR>
1409       * position into the buffer pointed by \a pBuffer and increments the      inline unsigned long ReadSample(Sample* pSample, void* pBuffer, unsigned long SampleCount, Sample::buffer_t* tempBuffer = NULL) {
      * position within the sample. Use this method  
      * and <i>SetPos()</i> if you don't want to load the sample into RAM,  
      * thus for disk streaming.  
      *  
      * For 16 bit samples, the data in the buffer will be int16_t  
      * (using native endianness). For 24 bit, the buffer will  
      * contain three bytes per sample, little-endian.  
      *  
      * @param pBuffer      destination buffer  
      * @param SampleCount  number of sample points to read  
      * @returns            number of successfully read sample points  
      * @see                SetPos()  
      */  
     unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {  
1410          // TODO: startAddrsCoarseOffset, endAddrsCoarseOffset          // TODO: startAddrsCoarseOffset, endAddrsCoarseOffset
1411          if (SampleCount == 0) return 0;          if (SampleCount == 0) return 0;
1412          long pos = GetPos();          long pos = pSample->GetPos();
1413          if (pos + SampleCount > GetTotalFrameCount()) SampleCount = GetTotalFrameCount() - pos;          if (pos + SampleCount > pSample->GetTotalFrameCount())
1414                SampleCount = pSample->GetTotalFrameCount() - pos;
1415            if (!CLEAR) {
1416                if (tempBuffer->Size < SampleCount * pSample->GetFrameSize()) {
1417                    std::cerr << "sf2::Sample error: tempBuffer too small. This is a BUG!" << std::endl;
1418                    return 0;
1419                }
1420            }
1421    
1422          if (GetFrameSize() / GetChannelCount() == 3 /* 24 bit */) {          if (pSample->GetFrameSize() / pSample->GetChannelCount() == 3 /* 24 bit */) {
1423              uint8_t* pBuf = (uint8_t*)pBuffer;              uint8_t* const pTmpBuf = (uint8_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart);
1424              if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) {              uint8_t* const pBuf    = (uint8_t*)pBuffer;
1425                  pCkSmpl->Read(pBuf, SampleCount, 2);              if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) {
1426                  pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);                  pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2);
1427                    pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1);
1428                  for (int i = SampleCount - 1; i >= 0; i--) {                  for (int i = SampleCount - 1; i >= 0; i--) {
1429                      pBuf[i*3] = pBuf[(SampleCount * 2) + i];                      pBuf[i*3]     = pTmpBuf[(SampleCount * 2) + i];
1430                      pBuf[i*3 + 2] = pBuf[i*2 + 1];                      pBuf[i*3 + 2] = pTmpBuf[i*2 + 1];
1431                      pBuf[i*3 + 1] = pBuf[i*2];                      pBuf[i*3 + 1] = pTmpBuf[i*2];
1432                  }                  }
1433              } else if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) {              } else if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) {
1434                  pCkSmpl->Read(pBuf, SampleCount, 2);                  pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2);
1435                  pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);                  pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1);
1436                  for (int i = SampleCount - 1; i >= 0; i--) {                  for (int i = SampleCount - 1; i >= 0; i--) {
1437                      pBuf[i*6] = pBuf[(SampleCount * 2) + i];                      pBuf[i*6]     = pTmpBuf[(SampleCount * 2) + i];
1438                      pBuf[i*6 + 2] = pBuf[i*2 + 1];                      pBuf[i*6 + 2] = pTmpBuf[i*2 + 1];
1439                      pBuf[i*6 + 1] = pBuf[i*2];                      pBuf[i*6 + 1] = pTmpBuf[i*2];
1440                      pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0;                      if (CLEAR)
1441                            pBuf[i*6 + 3] = pBuf[i*6 + 4] = pBuf[i*6 + 5] = 0;
1442                  }                  }
1443              } else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) {              } else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) {
1444                  pCkSmpl->Read(pBuf, SampleCount, 2);                  pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2);
1445                  pCkSm24->Read(pBuf + SampleCount * 2, SampleCount, 1);                  pSample->pCkSm24->Read(pTmpBuf + SampleCount * 2, SampleCount, 1);
1446                  for (int i = SampleCount - 1; i >= 0; i--) {                  for (int i = SampleCount - 1; i >= 0; i--) {
1447                      pBuf[i*6 + 3] = pBuf[(SampleCount * 2) + i];                      pBuf[i*6 + 3] = pTmpBuf[(SampleCount * 2) + i];
1448                      pBuf[i*6 + 5] = pBuf[i*2 + 1];                      pBuf[i*6 + 5] = pTmpBuf[i*2 + 1];
1449                      pBuf[i*6 + 4] = pBuf[i*2];                      pBuf[i*6 + 4] = pTmpBuf[i*2];
1450                      pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0;                      if (CLEAR)
1451                            pBuf[i*6] = pBuf[i*6 + 1] = pBuf[i*6 + 2] = 0;
1452                  }                  }
1453              }              }
1454          } else {          } else {
1455              if (SampleType == MONO_SAMPLE || SampleType == ROM_MONO_SAMPLE) {              if (pSample->SampleType == Sample::MONO_SAMPLE || pSample->SampleType == Sample::ROM_MONO_SAMPLE) {
1456                  return pCkSmpl->Read(pBuffer, SampleCount, 2);                  return pSample->pCkSmpl->Read(pBuffer, SampleCount, 2);
1457              }              }
1458    
1459              int16_t* pBuf = (int16_t*)pBuffer;              int16_t* const pTmpBuf = (int16_t*) ((CLEAR) ? pBuffer : tempBuffer->pStart);
1460              if (SampleType == LEFT_SAMPLE || SampleType == ROM_LEFT_SAMPLE) {              int16_t* const pBuf    = (int16_t*) pBuffer;
1461                  pCkSmpl->Read(pBuf, SampleCount, 2);              if (pSample->SampleType == Sample::LEFT_SAMPLE || pSample->SampleType == Sample::ROM_LEFT_SAMPLE) {
1462                    pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2);
1463                  for (int i = SampleCount - 1; i >= 0; i--) {                  for (int i = SampleCount - 1; i >= 0; i--) {
1464                      pBuf[i*2] = pBuf[i];                      pBuf[i*2] = pTmpBuf[i];
1465                      pBuf[i*2 + 1] = 0;                      if (CLEAR)
1466                            pBuf[i*2 + 1] = 0;
1467                  }                  }
1468              } else if (SampleType == RIGHT_SAMPLE || SampleType == ROM_RIGHT_SAMPLE) {              } else if (pSample->SampleType == Sample::RIGHT_SAMPLE || pSample->SampleType == Sample::ROM_RIGHT_SAMPLE) {
1469                  pCkSmpl->Read(pBuf, SampleCount, 2);                  pSample->pCkSmpl->Read(pTmpBuf, SampleCount, 2);
1470                  for (int i = SampleCount - 1; i >= 0; i--) {                  for (int i = SampleCount - 1; i >= 0; i--) {
1471                      pBuf[i*2] = 0;                      if (CLEAR)
1472                      pBuf[i*2 + 1] = pBuf[i];                          pBuf[i*2] = 0;
1473                        pBuf[i*2 + 1] = pTmpBuf[i];
1474                  }                  }
1475              }              }
1476          }          }
1477    
1478          if (pCkSmpl->GetPos() > (End * 2)) {          if (pSample->pCkSmpl->GetPos() > (pSample->End * 2)) {
1479              std::cerr << "Read after the sample end. This is a BUG!" << std::endl;              std::cerr << "Read after the sample end. This is a BUG!" << std::endl;
1480              std::cerr << "Current position: " << GetPos() << std::endl;              std::cerr << "Current position: " << pSample->GetPos() << std::endl;
1481              std::cerr << "Total number of frames: " << GetTotalFrameCount() << std::endl << std::endl;              std::cerr << "Total number of frames: " << pSample->GetTotalFrameCount() << std::endl << std::endl;
1482          }          }
1483          return SampleCount;          return SampleCount;
1484      }      }
1485    
1486        /**
1487         * Reads \a SampleCount number of sample points from the current
1488         * position into the buffer pointed by \a pBuffer and increments the
1489         * position within the sample. Use this method
1490         * and <i>SetPos()</i> if you don't want to load the sample into RAM,
1491         * thus for disk streaming.
1492         *
1493         * For 16 bit samples, the data in the buffer will be int16_t
1494         * (using native endianness). For 24 bit, the buffer will
1495         * contain three bytes per sample, little-endian.
1496         *
1497         * Stereo Samples: stereo samples are stored as a pair of mono samples with
1498         * SoundFont 2. Due to historical reasons, this Read() method expects
1499         * @a pBuffer to be a stereo buffer, however only the audio channel covered
1500         * by the sample data of this sample will be filled. The other audio channel
1501         * of @a pBuffer will be set to zero. This is probably not what you want.
1502         * So you might want to use ReadNoClear() instead.
1503         *
1504         * @param pBuffer      destination buffer
1505         * @param SampleCount  number of sample points to read
1506         * @returns            number of successfully read sample points
1507         * @see                SetPos(), ReadNoClear()
1508         */
1509        unsigned long Sample::Read(void* pBuffer, unsigned long SampleCount) {
1510            return ReadSample<true>(this, pBuffer, SampleCount);
1511        }
1512    
1513        /**
1514         * Reads \a SampleCount number of sample points from the current
1515         * position into the buffer pointed by \a pBuffer and increments the
1516         * position within the sample. Use this method
1517         * and <i>SetPos()</i> if you don't want to load the sample into RAM,
1518         * thus for disk streaming.
1519         *
1520         * For 16 bit samples, the data in the buffer will be int16_t
1521         * (using native endianness). For 24 bit, the buffer will
1522         * contain three bytes per sample, little-endian.
1523         *
1524         * Stereo Samples: stereo samples are stored as a pair of mono samples with
1525         * SoundFont 2. This ReadNoClear() method expects @a pBuffer to be a stereo
1526         * buffer, however only the audio channel covered by the sample data of this
1527         * sample will be filled. The other audio channel
1528         * of @a pBuffer will remain untouched. So you might pass the same
1529         * @a pBuffer to the other, linked sample to actually get the interleaved
1530         * stereo audio stream. To avoid destroying the other audio channel's data
1531         * you must pass an external, tempoary working buffer @a tempBuffer, which
1532         * should already be allocated to the size required to decode the requested
1533         * length of sample data. That @a tempBuffer is only used by ReadNoClear()
1534         * to fulfill its work, it does not contain any useful data after this
1535         * method returned.
1536         *
1537         * @param pBuffer      destination buffer
1538         * @param SampleCount  number of sample points to read
1539         * @param tempBuffer   temporary work buffer (must be pre-allocated large enough)
1540         * @returns            number of successfully read sample points
1541         * @see                SetPos(), Read()
1542         */
1543        unsigned long Sample::ReadNoClear(void* pBuffer, unsigned long SampleCount, buffer_t& tempBuffer) {
1544            return ReadSample<false>(this, pBuffer, SampleCount, &tempBuffer);
1545        }
1546    
1547    
1548  // *************** functions ***************  // *************** functions ***************
1549  // *  // *

Legend:
Removed from v.2779  
changed lines
  Added in v.2780

  ViewVC Help
Powered by ViewVC