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:
Fischlurch 2014-08-30 23:42:49 +02:00
parent d9d75727aa
commit 7f6ea5e614
2 changed files with 58 additions and 13 deletions

View file

@ -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

View file

@ -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();