#include "TEDPlugin.h"
#include "../../chipplayer.h"
#include <coreutils/log.h>
#include <coreutils/utils.h>
#include "tedplay/Audio.h"
#include "tedplay/Tedmem.h"
#include "tedplay/tedplay.h"
#include <set>
namespace musix {
class PluginAudio : public Audio
{
public:
PluginAudio() : Audio(44100)
{
int bufDurInMsec = 100;
paused = false;
recording = false;
unsigned int fragsPerSec = 1000 / bufDurInMsec;
unsigned int bufSize1kbChunk = (44100 / fragsPerSec / 1024) * 1024;
if (bufSize1kbChunk == 0) { bufSize1kbChunk = 512; }
bufferLength = bufSize1kbChunk;
unsigned int bfSize =
TED_SOUND_CLOCK / fragsPerSec; ringBufferSize = (bfSize / 8 + 1) * 16;
ringBuffer = new short[ringBufferSize];
ringBufferIndex = ringBufferSize - 1;
}
void play() override {}
void pause() override {}
void stop() override {}
void sleep(unsigned int msec) override
{
static unsigned char buffer[32768];
int bytes = 44100 * msec / 1000;
LOGD("SLEEP %d msec = %d bytes", msec, bytes);
if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
audioCallback((void*)ted, buffer, bytes);
}
void flush() override
{
}
void lock() override {}
void unlock() override {}
void getSamples(int16_t* target, int noSamples) const
{
audioCallback((void*)ted, reinterpret_cast<unsigned char*>(target),
noSamples);
for (int i = (noSamples - 1) / 2; i >= 0; i--) {
target[i * 2] = target[i * 2 + 1] = target[i];
}
}
TED* ted;
};
class TEDPlayer : public ChipPlayer
{
public:
explicit TEDPlayer(const std::string& fileName) : audio(new PluginAudio())
{
LOGD("Trying to play TED music");
audio->ted = machineInit(44100, 24);
tedplayMain(fileName.c_str(), audio);
setMeta("songs", 10);
}
~TEDPlayer() override { tedplayClose(); }
int getSamples(int16_t* target, int noSamples) override
{
audio->getSamples(target, noSamples);
if (!haveSound) {
int s = 0;
for (int i = 0; (s == 0) && i < noSamples; i += 8) {
s += target[i];
}
if (s == 0) {
counter++;
if (counter % 3 == 0) { audio->ted->putKey(counter / 3 - 1); }
} else {
haveSound = true;
}
}
return noSamples;
}
bool seekTo(int song, int ) override
{
LOGD("Seek {}", song);
audio->ted->putKey(song + 1);
return true;
}
private:
PluginAudio* audio;
TED* ted = nullptr;
bool haveSound = false;
int counter = 0;
};
bool TEDPlugin::canHandle(const std::string& name)
{
return utils::path_extension(name) == "prg";
}
ChipPlayer* TEDPlugin::fromFile(const std::string& name)
{
return new TEDPlayer{name};
};
} extern "C" void tedplugin_register()
{
musix::ChipPlugin::addPluginConstructor([](std::string const& config) {
return std::make_shared<musix::TEDPlugin>();
});
}