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 |
// * |
// * |