1
/************************************************************************
2
DSPatch - Cross-Platform, Object-Oriented, Flow-Based Programming Library
3
Copyright (c) 2012-2015 Marcus Tomlinson
5
This file is part of DSPatch.
7
GNU Lesser General Public License Usage
8
This file may be used under the terms of the GNU Lesser General Public
9
License version 3.0 as published by the Free Software Foundation and
10
appearing in the file LGPLv3.txt included in the packaging of this
11
file. Please review the following information to ensure the GNU Lesser
12
General Public License version 3.0 requirements will be met:
13
http://www.gnu.org/copyleft/lgpl.html.
16
Alternatively, this file may be used in accordance with the terms and
17
conditions contained in a signed written agreement between you and
20
DSPatch is distributed in the hope that it will be useful,
21
but WITHOUT ANY WARRANTY; without even the implied warranty of
22
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23
************************************************************************/
25
#include <DspWaveStreamer.h>
31
//=================================================================================================
33
DspWaveStreamer::DspWaveStreamer()
37
, _shortToFloatCoeff(1.0f / 32767.0f)
41
_leftChannel.resize(_bufferSize);
42
_rightChannel.resize(_bufferSize);
46
AddOutput_("Sample Rate");
48
pFilePath = AddParameter_("filePath", DspParameter(DspParameter::FilePath, ""));
49
pPlay = AddParameter_("play", DspParameter(DspParameter::Trigger));
50
pPause = AddParameter_("pause", DspParameter(DspParameter::Trigger));
51
pStop = AddParameter_("stop", DspParameter(DspParameter::Trigger));
52
pIsPlaying = AddParameter_("isPlaying", DspParameter(DspParameter::Bool, false));
55
//-------------------------------------------------------------------------------------------------
57
DspWaveStreamer::~DspWaveStreamer()
61
//=================================================================================================
63
bool DspWaveStreamer::LoadFile(char const* filePath)
65
bool wasPlaying = IsPlaying();
73
std::ifstream inFile(filePath, std::ios::binary | std::ios::in);
79
int dwFileSize = 0, dwChunkSize = 0;
86
// look for 'RIFF' chunk identifier
87
inFile.seekg(0, std::ios::beg);
88
inFile.read(dwChunkId, 4);
89
if (strcmp(dwChunkId, "RIFF"))
91
std::cerr << "'" << filePath << "' not found.\n";
95
inFile.seekg(4, std::ios::beg); // get file size
96
inFile.read(reinterpret_cast<char*>(&dwFileSize), 4);
102
inFile.seekg(8, std::ios::beg); // get file format
103
inFile.read(dwExtra, 4);
104
if (strcmp(dwExtra, "WAVE"))
110
// look for 'fmt ' chunk id
111
bool bFilledFormat = false;
112
for (int i = 12; i < dwFileSize;)
114
inFile.seekg(i, std::ios::beg);
115
inFile.read(dwChunkId, 4);
116
inFile.seekg(i + 4, std::ios::beg);
117
inFile.read(reinterpret_cast<char*>(&dwChunkSize), 4);
118
if (!strcmp(dwChunkId, "fmt "))
120
inFile.seekg(i + 8, std::ios::beg);
123
inFile.read(reinterpret_cast<char*>(&_waveFormat.format), 2);
124
inFile.read(reinterpret_cast<char*>(&_waveFormat.channelCount), 2);
125
inFile.read(reinterpret_cast<char*>(&_waveFormat.sampleRate), 4);
126
inFile.read(reinterpret_cast<char*>(&_waveFormat.byteRate), 4);
127
inFile.read(reinterpret_cast<char*>(&_waveFormat.frameSize), 2);
128
inFile.read(reinterpret_cast<char*>(&_waveFormat.bitDepth), 2);
129
inFile.read(reinterpret_cast<char*>(&_waveFormat.extraDataSize), 2);
131
bFilledFormat = true;
134
dwChunkSize += 8; // add offsets of the chunk id, and chunk size data entries
136
dwChunkSize &= 0xfffffffe; // guarantees WORD padding alignment
145
// look for 'data' chunk id
146
bool bFilledData = false;
147
for (int i = 12; i < dwFileSize;)
149
inFile.seekg(i, std::ios::beg);
150
inFile.read(dwChunkId, 4);
151
inFile.seekg(i + 4, std::ios::beg);
152
inFile.read(reinterpret_cast<char*>(&dwChunkSize), 4);
153
if (!strcmp(dwChunkId, "data"))
155
_waveData.resize(dwChunkSize / 2);
156
inFile.seekg(i + 8, std::ios::beg);
157
inFile.read(reinterpret_cast<char*>(&_waveData[0]), dwChunkSize);
161
dwChunkSize += 8; // add offsets of the chunk id, and chunk size data entries
163
dwChunkSize &= 0xfffffffe; // guarantees WORD padding alignment
179
SetParameter_(pFilePath, DspParameter(DspParameter::FilePath, filePath));
183
//-------------------------------------------------------------------------------------------------
185
void DspWaveStreamer::Play()
187
SetParameter_(pIsPlaying, DspParameter(DspParameter::Bool, true));
190
//-------------------------------------------------------------------------------------------------
192
void DspWaveStreamer::Pause()
194
SetParameter_(pIsPlaying, DspParameter(DspParameter::Bool, false));
197
//-------------------------------------------------------------------------------------------------
199
void DspWaveStreamer::Stop()
204
SetParameter_(pIsPlaying, DspParameter(DspParameter::Bool, false));
209
//-------------------------------------------------------------------------------------------------
211
bool DspWaveStreamer::IsPlaying() const
213
return *GetParameter_(pIsPlaying)->GetBool();
216
//=================================================================================================
218
void DspWaveStreamer::Process_(DspSignalBus&, DspSignalBus& outputs)
220
if (IsPlaying() && _waveData.size() > 0)
225
for (int i = 0; i < _bufferSize * 2; i += 2)
227
_leftChannel[index++] = (float)_waveData[_sampleIndex + i] * _shortToFloatCoeff;
231
for (int i = 1; i < _bufferSize * 2; i += 2)
233
_rightChannel[index++] = (float)_waveData[_sampleIndex + i] * _shortToFloatCoeff;
236
_sampleIndex += _bufferSize * 2;
237
_sampleIndex %= _waveData.size() - _bufferSize * 2;
241
outputs.SetValue(0, _leftChannel);
242
outputs.SetValue(1, _rightChannel);
243
outputs.SetValue("Sample Rate", _waveFormat.sampleRate);
247
outputs.ClearValue(0);
248
outputs.ClearValue(1);
252
//-------------------------------------------------------------------------------------------------
254
bool DspWaveStreamer::ParameterUpdating_(int index, DspParameter const& param)
256
if (index == pFilePath)
258
return LoadFile(param.GetString()->c_str());
260
else if (index == pPlay)
265
else if (index == pPause)
270
else if (index == pStop)
279
//=================================================================================================