forked from jfchapman/VUPlayer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DecoderWavpack.cpp
53 lines (48 loc) · 1.91 KB
/
DecoderWavpack.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "DecoderWavpack.h"
#include "Utility.h"
DecoderWavpack::DecoderWavpack( const std::wstring& filename ) :
Decoder(),
m_Context( nullptr )
{
char* error = nullptr;
const int flags = OPEN_WVC | OPEN_NORMALIZE | OPEN_DSD_AS_PCM | OPEN_FILE_UTF8;
const int offset = 0;
m_Context = WavpackOpenFileInput( WideStringToUTF8( filename ).c_str(), error, flags, offset );
if ( nullptr != m_Context ) {
SetBPS( static_cast<long>( WavpackGetBitsPerSample( m_Context ) ) );
SetChannels( static_cast<long>( WavpackGetNumChannels( m_Context ) ) );
SetSampleRate( static_cast<long>( WavpackGetSampleRate( m_Context ) ) );
if ( GetSampleRate() > 0 ) {
SetDuration( static_cast<float>( WavpackGetNumSamples64( m_Context ) ) / GetSampleRate() );
}
SetBitrate( static_cast<float>( WavpackGetAverageBitrate( m_Context, TRUE /*count_wvc*/ ) / 1000 ) );
} else {
throw std::runtime_error( "DecoderWavpack could not load file" );
}
}
DecoderWavpack::~DecoderWavpack()
{
WavpackCloseFile( m_Context );
}
long DecoderWavpack::Read( float* buffer, const long sampleCount )
{
const long samplesRead = ( sampleCount > 0 ) ? static_cast<long>( WavpackUnpackSamples( m_Context, reinterpret_cast<int32_t*>( buffer ), sampleCount ) ) : 0;
if ( !( WavpackGetMode( m_Context ) & MODE_FLOAT ) ) {
int32_t* nativeBuffer = reinterpret_cast<int32_t*>( buffer );
const long bufferSize = samplesRead * GetChannels();
const int bitsPerSample = WavpackGetBytesPerSample( m_Context ) * 8;
for ( long index = 0; index < bufferSize; index++ ) {
buffer[ index ] = static_cast<float>( nativeBuffer[ index ] ) / ( 1 << ( bitsPerSample - 1 ) );
}
}
return samplesRead;
}
float DecoderWavpack::Seek( const float position )
{
float seekPosition = position;
const int64_t samplePosition = static_cast<int64_t>( position * GetSampleRate() );
if ( 0 == WavpackSeekSample64( m_Context, samplePosition ) ) {
seekPosition = 0;
}
return seekPosition;
}