Verarbeitungsmechanismus mit Laden/Schreiben und Kontextbehandlung
implementiert und getestet Ein Kontext-Puffer wird mitgeführt, so daß stets eine bestimmte Anzahl an Kontext-Samples mit verfügbar ist. Puffer-Steuerung erfolgt pro Kanal, so daß auch variierende Dateilängen korrekt gehandhabt werden; die Verarbeitung bricht aber insgesamt innerhalb einer Pufferlänge ab, wenn die kürzesten Samples fertig bearbeitet sind. die eigentliche Korrektur ist noch nicht implementiert; im Test, nach dem Beheben der Implementierungs-Fehler, waren die bearbeiteten Samples schließlich Bit für Bit identisch mit dem Original.
This commit is contained in:
parent
d9d75727aa
commit
7f6ea5e614
2 changed files with 58 additions and 13 deletions
|
|
@ -30,6 +30,7 @@ SynKlick: SynKlick.cc
|
|||
all: SynKlick
|
||||
|
||||
clean:
|
||||
-rm -f SynKlick
|
||||
-rm -f `find . -name "*.o"`
|
||||
-rm -f `find .. -name "*~"`
|
||||
-rm -f *.bak core score.srt
|
||||
|
|
|
|||
|
|
@ -43,7 +43,16 @@ name_without_path (string rawName)
|
|||
{
|
||||
auto pos = rawName.rfind('/');
|
||||
return (pos == string::npos)? rawName
|
||||
: rawName.substr(pos);
|
||||
: rawName.substr(pos+1);
|
||||
}
|
||||
|
||||
void
|
||||
reduceBufferPos (size_t & pos, size_t elementsToRemove)
|
||||
{
|
||||
if (pos < elementsToRemove)
|
||||
pos = 0;
|
||||
else
|
||||
pos -= elementsToRemove;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -66,11 +75,13 @@ class Channel
|
|||
info_out_;
|
||||
|
||||
float buff_[CHUNK_SIZE];
|
||||
size_t workPos=0,
|
||||
loadPos=0;
|
||||
size_t numSamples_ = 0;
|
||||
size_t workPos_ = 0;
|
||||
|
||||
|
||||
public:
|
||||
static bool hitEnd;
|
||||
|
||||
void
|
||||
open (string name, string target)
|
||||
{
|
||||
|
|
@ -81,6 +92,9 @@ class Channel
|
|||
in_ = sf_open (name.c_str(), SFM_READ, &info_in_);
|
||||
if (!in_)
|
||||
error ("could not open "+name+" -- " + sf_strerror (NULL));
|
||||
if (1 != info_in_.channels)
|
||||
error ("only Mono streams supported -- but '"+name_
|
||||
+"' was found to have "+std::to_string(info_in_.channels)+" channels.");
|
||||
|
||||
info_out_.format = info_in_.format;
|
||||
info_out_.channels = info_in_.channels;
|
||||
|
|
@ -93,10 +107,11 @@ class Channel
|
|||
|
||||
~Channel()
|
||||
{
|
||||
sf_close (in_);
|
||||
if (!sf_close (out_))
|
||||
cerr << "WARNING: problems while closing target '" << name_without_path(name_)
|
||||
<< "' -- " << sf_strerror(out_) << "\n";
|
||||
if (in_) sf_close (in_);
|
||||
if (out_)
|
||||
if (0 != sf_close (out_))
|
||||
cerr << "WARNING: problems while closing target '" << name_without_path(name_)
|
||||
<< "' -- " << sf_strerror(out_) << "\n";
|
||||
|
||||
in_ = out_ = nullptr;
|
||||
}
|
||||
|
|
@ -105,18 +120,41 @@ class Channel
|
|||
void
|
||||
fillBuffer()
|
||||
{
|
||||
error("TODO");
|
||||
assert(numSamples_ < CHUNK_SIZE);
|
||||
float* startPos = buff_ + numSamples_;
|
||||
size_t samplesToRead = CHUNK_SIZE - numSamples_;
|
||||
numSamples_ = sf_read_float(in_, startPos, samplesToRead);
|
||||
if (numSamples_ < samplesToRead)
|
||||
hitEnd = true; // causes the processing to end with this chunk.
|
||||
|
||||
numSamples_ += (startPos - buff_);
|
||||
assert(workPos_ <= numSamples_);
|
||||
}
|
||||
|
||||
void
|
||||
writeBuffer()
|
||||
{
|
||||
error("TODO");
|
||||
size_t samplesToWrite = numSamples_ - (hitEnd? 0 : 2*CONTEXT);
|
||||
size_t actuallyWritten = sf_write_float(out_, buff_, samplesToWrite);
|
||||
if (actuallyWritten < samplesToWrite)
|
||||
cerr << "Alarm: only "<<actuallyWritten<<" instead of "<<samplesToWrite
|
||||
<<" samples written for " << name_ <<"\n";
|
||||
|
||||
if (!hitEnd)
|
||||
// move processing context samples to the beginning of the buffer;
|
||||
// they will be written together with the next chunk of data
|
||||
{
|
||||
for (uint i=0; i < 2*CONTEXT; ++i)
|
||||
buff_[i] = buff_[i + actuallyWritten];
|
||||
reduceBufferPos(numSamples_, actuallyWritten);
|
||||
reduceBufferPos(workPos_, actuallyWritten);
|
||||
}
|
||||
assert(workPos_ <= numSamples_);
|
||||
}
|
||||
|
||||
/**
|
||||
* process a single sample position in the current buffer content.
|
||||
* The sample is copied to the output and it is investigated for glitches.
|
||||
* investigate a single sample position in the current buffer content.
|
||||
* The delta to the preceding sample(s) is used to detect a signal glitch.
|
||||
* @param i position of current sample
|
||||
* @param event state of other tracks investigated thus far
|
||||
* @return the event detection state including the results of investigating this sample.
|
||||
|
|
@ -127,6 +165,12 @@ class Channel
|
|||
Event
|
||||
visit (uint i, Event event)
|
||||
{
|
||||
if (i + CONTEXT < numSamples_
|
||||
&& CONTEXT <= i
|
||||
&& workPos_ <= i)
|
||||
{
|
||||
workPos_ = i;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +211,7 @@ class Patch
|
|||
|
||||
int num_sources = 0;
|
||||
vector<Channel> streams(0);
|
||||
bool hitEnd = false;
|
||||
bool Channel::hitEnd = false;
|
||||
|
||||
|
||||
void
|
||||
|
|
@ -195,7 +239,7 @@ closeStreams()
|
|||
void
|
||||
process()
|
||||
{
|
||||
while (!hitEnd)
|
||||
while (!Channel::hitEnd)
|
||||
{
|
||||
for (Channel& channel : streams)
|
||||
channel.fillBuffer();
|
||||
|
|
|
|||
Loading…
Reference in a new issue