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 - 2011 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 * |
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> |
47 |
ChannelCount = sfInfo.channels; |
ChannelCount = sfInfo.channels; |
48 |
Format = sfInfo.format; |
Format = sfInfo.format; |
49 |
|
|
50 |
switch(Format & 0xF) { |
switch(Format & SF_FORMAT_SUBMASK) { |
51 |
case SF_FORMAT_PCM_S8: |
case SF_FORMAT_PCM_S8: |
52 |
case SF_FORMAT_PCM_U8: |
case SF_FORMAT_PCM_U8: |
|
case SF_FORMAT_PCM_16: |
|
53 |
case SF_FORMAT_DPCM_8: |
case SF_FORMAT_DPCM_8: |
54 |
|
FrameSize = ChannelCount; |
55 |
|
break; |
56 |
|
case SF_FORMAT_PCM_16: |
57 |
case SF_FORMAT_DPCM_16: |
case SF_FORMAT_DPCM_16: |
58 |
FrameSize = sizeof(short) * ChannelCount; |
FrameSize = 2 * ChannelCount; |
59 |
|
break; |
60 |
|
case SF_FORMAT_PCM_24: |
61 |
|
case SF_FORMAT_DWVW_24: |
62 |
|
FrameSize = 3 * ChannelCount; |
63 |
break; |
break; |
64 |
default: |
default: |
65 |
FrameSize = sizeof(int) * ChannelCount; |
FrameSize = 2 * ChannelCount; |
66 |
} |
} |
67 |
TotalFrameCount = sfInfo.frames; |
TotalFrameCount = sfInfo.frames; |
68 |
|
|
69 |
|
Loops = 0; |
70 |
|
LoopStart = 0; |
71 |
|
LoopEnd = 0; |
72 |
|
SF_INSTRUMENT instrument; |
73 |
|
if (sf_command(pSndFile, SFC_GET_INSTRUMENT, |
74 |
|
&instrument, sizeof(instrument)) != SF_FALSE) { |
75 |
|
// TODO: instrument.basenote |
76 |
|
#if HAVE_SF_INSTRUMENT_LOOPS |
77 |
|
if (instrument.loop_count && instrument.loops[0].mode != SF_LOOP_NONE) { |
78 |
|
Loops = 1; |
79 |
|
LoopStart = instrument.loops[0].start; |
80 |
|
LoopEnd = instrument.loops[0].end; |
81 |
|
} |
82 |
|
#endif |
83 |
|
} |
84 |
if(!DontClose) Close(); |
if(!DontClose) Close(); |
85 |
} |
} |
86 |
|
|
87 |
SampleFile::~SampleFile() { |
SampleFile::~SampleFile() { |
88 |
Close(); |
Close(); |
89 |
|
ReleaseSampleData(); |
90 |
} |
} |
91 |
|
|
92 |
void SampleFile::Open() { |
void SampleFile::Open() { |
132 |
} |
} |
133 |
|
|
134 |
Sample::buffer_t SampleFile::LoadSampleData() { |
Sample::buffer_t SampleFile::LoadSampleData() { |
135 |
return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, 0); // 0 amount of NullSamples |
return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), 0); // 0 amount of NullSamples |
136 |
} |
} |
137 |
|
|
138 |
Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) { |
Sample::buffer_t SampleFile::LoadSampleData(unsigned long FrameCount) { |
140 |
} |
} |
141 |
|
|
142 |
Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) { |
Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(uint NullFrameCount) { |
143 |
return LoadSampleDataWithNullSamplesExtension(this->TotalFrameCount, NullFrameCount); |
return LoadSampleDataWithNullSamplesExtension(GetTotalFrameCount(), NullFrameCount); |
144 |
} |
} |
145 |
|
|
146 |
Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) { |
Sample::buffer_t SampleFile::LoadSampleDataWithNullSamplesExtension(unsigned long FrameCount, uint NullFramesCount) { |
147 |
Open(); |
Open(); |
148 |
if (FrameCount > this->TotalFrameCount) FrameCount = this->TotalFrameCount; |
if (FrameCount > GetTotalFrameCount()) FrameCount = GetTotalFrameCount(); |
149 |
|
|
150 |
|
if (Offset > MaxOffset && FrameCount < GetTotalFrameCount()) { |
151 |
|
FrameCount = FrameCount + Offset > GetTotalFrameCount() ? GetTotalFrameCount() - Offset : FrameCount; |
152 |
|
// Offset the RAM cache |
153 |
|
RAMCacheOffset = Offset; |
154 |
|
} |
155 |
if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; |
if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; |
156 |
unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize; |
unsigned long allocationsize = (FrameCount + NullFramesCount) * this->FrameSize; |
157 |
SetPos(0, SEEK_SET); // reset read position to begin of sample |
SetPos(RAMCacheOffset, SEEK_SET); // reset read position to playback start point |
158 |
RAMCache.pStart = new int8_t[allocationsize]; |
RAMCache.pStart = new int8_t[allocationsize]; |
159 |
|
|
160 |
RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize; |
RAMCache.Size = Read(RAMCache.pStart, FrameCount) * this->FrameSize; |
167 |
|
|
168 |
long SampleFile::Read(void* pBuffer, unsigned long FrameCount) { |
long SampleFile::Read(void* pBuffer, unsigned long FrameCount) { |
169 |
Open(); |
Open(); |
170 |
if(FrameSize == sizeof(short) * ChannelCount) { |
|
171 |
return sf_readf_short(pSndFile, (short*)pBuffer, FrameCount); |
if (GetPos() + FrameCount > GetTotalFrameCount()) FrameCount = GetTotalFrameCount() - GetPos(); // For the cases where a different sample end is specified (not the end of the file) |
172 |
} else { |
|
173 |
return sf_readf_int(pSndFile, (int*)pBuffer, FrameCount); |
// ogg files must be read with sf_readf, not sf_read_raw. On |
174 |
|
// big endian machines, sf_readf_short is also used for 16 bit |
175 |
|
// wav files, to get automatic endian conversion (for 24 bit |
176 |
|
// samples this is handled in Synthesize::GetSample instead). |
177 |
|
|
178 |
|
#if WORDS_BIGENDIAN || HAVE_DECL_SF_FORMAT_VORBIS |
179 |
|
if ( |
180 |
|
#if WORDS_BIGENDIAN |
181 |
|
FrameSize == 2 * ChannelCount |
182 |
|
#else |
183 |
|
(Format & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS |
184 |
|
#endif |
185 |
|
) { |
186 |
|
return sf_readf_short(pSndFile, static_cast<short*>(pBuffer), FrameCount); |
187 |
|
} else |
188 |
|
#endif |
189 |
|
{ |
190 |
|
int bytes = sf_read_raw(pSndFile, pBuffer, FrameCount * GetFrameSize()); |
191 |
|
return bytes / GetFrameSize(); |
192 |
} |
} |
193 |
} |
} |
194 |
|
|
199 |
) { |
) { |
200 |
// TODO: |
// TODO: |
201 |
SetPos(pPlaybackState->position); |
SetPos(pPlaybackState->position); |
202 |
Read(pBuffer, FrameCount); |
unsigned long count = Read(pBuffer, FrameCount); |
203 |
pPlaybackState->position = GetPos(); |
pPlaybackState->position = GetPos(); |
204 |
|
return count; |
205 |
} |
} |
206 |
|
|
207 |
void SampleFile::ReleaseSampleData() { |
void SampleFile::ReleaseSampleData() { |