WIP Entwurf Verarbeitungsrahmen

This commit is contained in:
Fischlurch 2014-08-30 19:26:17 +02:00
parent f018ca9371
commit 947e27746f

View file

@ -13,16 +13,19 @@ GNU PUBLIC LICENCE (GPL) Version 2 and above.
#include <stdio.h>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <iostream>
using std::string;
using std::vector;
using std::cout;
using std::cerr;
const size_t BUFF_SIZE = 44100;
const size_t CONTEXT = 1;
const size_t BUFF_SIZE = 44100;
const size_t CONTEXT = 100;
const size_t CHUNK_SIZE = BUFF_SIZE + 2*CONTEXT;
/* ==== Helpers ==== */
@ -48,49 +51,114 @@ name_without_path (string rawName)
/* ==== Abstraction: single channel to be processed ==== */
struct Channel
enum Event {
NO=0,
MAYBE,
YES
};
class Channel
{
string name;
SNDFILE *in = nullptr,
*out = nullptr;
SF_INFO info_in,
info_out;
string name_;
SNDFILE *in_ = nullptr,
*out_ = nullptr;
SF_INFO info_in_,
info_out_;
float buff[BUFF_SIZE+CONTEXT];
float buff_[CHUNK_SIZE];
size_t workPos=0,
loadPos=0;
public:
void
open (string name, string target)
{
this->name = name;
this->name_ = name;
target += name_without_path(name);
info_in.format = 0;
in = sf_open (name.c_str(), SFM_READ, &info_in);
if (!in)
info_in_.format = 0;
in_ = sf_open (name.c_str(), SFM_READ, &info_in_);
if (!in_)
error ("could not open "+name+" -- " + sf_strerror (NULL));
info_out.format = info_in.format;
info_out.channels = info_in.channels;
info_out.samplerate = info_in.samplerate;
out = sf_open(target.c_str(), SFM_WRITE, &info_out);
if (!out)
info_out_.format = info_in_.format;
info_out_.channels = info_in_.channels;
info_out_.samplerate = info_in_.samplerate;
out_ = sf_open(target.c_str(), SFM_WRITE, &info_out_);
if (!out_)
error ("unable to create target "+target+" -- " + sf_strerror (NULL));
}
~Channel()
{
sf_close (in);
if (!sf_close (out))
cerr << "WARNING: problems while closing target '" << name_without_path(name)
<< "' -- " << sf_strerror(out) << "\n";
sf_close (in_);
if (!sf_close (out_))
cerr << "WARNING: problems while closing target '" << name_without_path(name_)
<< "' -- " << sf_strerror(out_) << "\n";
in = out = nullptr;
in_ = out_ = nullptr;
}
void
fillBuffer()
{
error("TODO");
}
void
writeBuffer()
{
error("TODO");
}
/**
* process a single sample position in the current buffer content.
* The sample is copied to the output and it is investigated for glitches.
* @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.
* If the sample is positively an glitch event, and the state is undecided thus far,
* the event state is confirmed; if a glitch can not be confirmed, the state is
* cleared. Otherwise, the undecided state is passed on.
*/
Event
visit (uint i, Event event)
{
return event;
}
};
/**
* fix a glitch detected in the corresponding channel.
* When the Patch is applied, internal work buffers are used
* to create two (partially synthetic) copies of the channel's signal
* which are then cross faded. The result is pushed back into the
* output of the underlying channel.
*/
class Patch
{
float workBuff[2*CONTEXT];
Channel& chan_;
public:
Patch(Channel& c)
: chan_(c)
{
}
void
apply()
{
error("TODO");
}
};
@ -98,28 +166,51 @@ struct Channel
/* ==== high-level operation ==== */
int num_sources = 0;
Channel* channel = nullptr;
vector<Channel> streams(0);
bool hitEnd = false;
void
openStreams (char* name[], string targetDir)
{
assert (!channel);
assert (num_sources);
channel = new Channel[num_sources];
assert (0 == streams.size());
streams.resize(num_sources);
assert (targetDir.length());
if (targetDir.back() != '/')
targetDir += '/';
for (uint i=0; i < num_sources; ++i)
channel[i].open (name[i], targetDir);
streams[i].open (name[i], targetDir);
}
void
closeStreams()
{
delete[] channel;
streams.clear();
}
void
process()
{
while (!hitEnd)
{
for (Channel& channel : streams)
channel.fillBuffer();
for (uint i=0; i < CHUNK_SIZE; ++i)
{
Event event = MAYBE;
for (Channel& channel : streams)
event = channel.visit(i, event);
if (YES == event)
for (Channel& channel : streams)
Patch(channel).apply();
}
for (Channel& channel : streams)
channel.writeBuffer();
}
}
@ -141,7 +232,7 @@ main (int argc, char* argv[]) {
string targetDir = argv[argc-1];
openStreams (&argv[1], targetDir);
process();
closeStreams();
cout << "\nSUCCESS\n"
<< num_sources << " files read and processed --> "