Add seeking capability to audio

Extend timestamp size in file format
presentation
Ulrich Huber 7 years ago
parent 2f5b575e25
commit 855b051ebb
  1. 4
      src/control/AudioController.cpp
  2. 4
      src/control/AudioController.h
  3. 6
      src/control/tools/InputHandler.cpp
  4. 32
      src/gui/PageViewFindObjectHelper.h
  5. 8
      src/model/Stroke.cpp
  6. 6
      src/model/Stroke.h
  7. 3
      src/util/audio/AudioPlayer.cpp
  8. 13
      src/util/audio/VorbisProducer.cpp
  9. 16
      src/util/serializing/ObjectInputStream.cpp
  10. 1
      src/util/serializing/ObjectInputStream.h
  11. 8
      src/util/serializing/ObjectOutputStream.cpp
  12. 1
      src/util/serializing/ObjectOutputStream.h

@ -44,7 +44,7 @@ void AudioController::recStartStop(bool rec)
return;
}
sttime = (g_get_monotonic_time() / 1000000);
sttime = static_cast<size_t>(g_get_monotonic_time() / 1000);
char buffer[50];
time_t secs = time(nullptr);
@ -113,7 +113,7 @@ Path AudioController::getAudioFolder()
return Path::fromUri(af);
}
gint AudioController::getStartTime()
size_t AudioController::getStartTime()
{
XOJ_CHECK_TYPE(AudioController);

@ -19,13 +19,13 @@ public:
void recStartStop(bool record);
string getAudioFilename();
Path getAudioFolder();
gint getStartTime();
size_t getStartTime();
AudioRecorder* getAudioRecorder();
AudioPlayer* getAudioPlayer();
protected:
string audioFilename;
gint sttime = 0;
size_t sttime = 0;
Settings* settings;
Control* control;
AudioRecorder* audioRecorder;

@ -70,9 +70,9 @@ void InputHandler::createStroke(Point p)
if (xournal->getControl()->getAudioController()->isRecording())
{
string audioFilename = xournal->getControl()->getAudioController()->getAudioFilename();
gint sttime = xournal->getControl()->getAudioController()->getStartTime();
int seconds = ((g_get_monotonic_time() / 1000000) - sttime);
stroke->setTimestamp(seconds);
size_t sttime = xournal->getControl()->getAudioController()->getStartTime();
size_t milliseconds = ((g_get_monotonic_time() / 1000) - sttime);
stroke->setTimestamp(milliseconds);
stroke->setAudioFilename(audioFilename);
}
}

@ -126,8 +126,6 @@ private:
double gap;
};
string lastfn = "";
class PlayObject : public BaseSelectObject
{
public:
@ -158,35 +156,13 @@ protected:
double tmpGap = 0;
if ((s->intersects(x, y, 15, &tmpGap)))
{
int ts = s->getTimestamp();
int buffer = 5;
if (ts >= buffer)
{
ts -= buffer;
}
else
{
ts = 0;
}
size_t ts = s->getTimestamp();
string fn = s->getAudioFilename();
if (fn != lastfn)
{
if (!fn.empty())
{
lastfn = fn;
AudioPlayer *audioPlayer = view->getXournal()->getControl()->getAudioController()->getAudioPlayer();
audioPlayer->start(Path::fromUri(view->settings->getAudioFolder()).str() + "/" + fn, (unsigned int) ts);
}
}
else
{
AudioPlayer *audioPlayer = view->getXournal()->getControl()->getAudioController()->getAudioPlayer();
audioPlayer->abort();
audioPlayer->start(Path::fromUri(view->settings->getAudioFolder()).str() + "/" + fn, (unsigned int) ts);
}
AudioPlayer *audioPlayer = view->getXournal()->getControl()->getAudioController()->getAudioPlayer();
audioPlayer->abort();
audioPlayer->start(Path::fromUri(view->settings->getAudioFolder()).str() + "/" + fn, (unsigned int) ts);
}
}
};

@ -88,7 +88,7 @@ void Stroke::serialize(ObjectOutputStream& out)
out.writeString(this->audioFilename);
out.writeInt(this->timestamp);
out.writeSizeT(this->timestamp);
out.writeInt(fill);
@ -113,7 +113,7 @@ void Stroke::readSerialized(ObjectInputStream& in)
this->audioFilename = in.readString();
this->timestamp = in.readInt();
this->timestamp = in.readSizeT();
this->fill = in.readInt();
@ -137,14 +137,14 @@ string Stroke::getAudioFilename() const
return this->audioFilename;
}
void Stroke::setTimestamp(int seconds)
void Stroke::setTimestamp(size_t seconds)
{
XOJ_CHECK_TYPE(Stroke);
this->timestamp = seconds;
}
int Stroke::getTimestamp() const
size_t Stroke::getTimestamp() const
{
XOJ_CHECK_TYPE(Stroke);

@ -42,8 +42,8 @@ public:
void setWidth(double width);
double getWidth() const;
void setTimestamp(int seconds);
int getTimestamp() const;
void setTimestamp(size_t seconds);
size_t getTimestamp() const;
void setAudioFilename(string fn);
string getAudioFilename() const;
@ -134,7 +134,7 @@ private:
LineStyle lineStyle;
// Stroke timestamp, to match it to the audio stream
int timestamp;
size_t timestamp = 0;
string audioFilename;
EraseableStroke* eraseable;

@ -45,7 +45,6 @@ void AudioPlayer::start(string filename, unsigned int timestamp)
}
this->stop();
});
//TODO we need something nicer here then detaching the thread
stopThread.detach();
}
@ -67,6 +66,8 @@ void AudioPlayer::abort()
{
XOJ_CHECK_TYPE(AudioPlayer);
this->audioQueue->signalEndOfStream();
// Stop playing audio
this->portAudioConsumer->stopPlaying();

@ -25,9 +25,18 @@ void VorbisProducer::start(std::string filename, const DeviceInfo& outputDevice,
}
//TODO implement seeking (this is hard since we need to get the frame offset)
sf_count_t seekPosition = this->sfInfo.samplerate / 1000 * timestamp;
if (seekPosition < this->sfInfo.frames)
{
sf_seek(this->sfFile, seekPosition, SF_SEEK_SET);
}
else
{
g_warning("VorbisProducer: Seeking outside of audio file extent");
}
this->producerThread = new std::thread(
[&, filename, timestamp]
[&, filename]
{
long numSamples = 1;
auto sampleBuffer = new int[1024 * this->sfInfo.channels];
@ -36,7 +45,7 @@ void VorbisProducer::start(std::string filename, const DeviceInfo& outputDevice,
{
numSamples = sf_readf_int(this->sfFile, sampleBuffer, 1024);
while (this->audioQueue->size() > 4096 && !this->audioQueue->hasStreamEnded())
while (this->audioQueue->size() > 4096 && !this->audioQueue->hasStreamEnded() && !this->stopProducer)
{
std::this_thread::sleep_for(std::chrono::microseconds(100));
}

@ -131,6 +131,22 @@ double ObjectInputStream::readDouble()
return d;
}
size_t ObjectInputStream::readSizeT()
{
XOJ_CHECK_TYPE(ObjectInputStream);
checkType('l');
if (this->pos + sizeof(size_t) >= this->str->len)
{
throw InputStreamException("End reached, but try to read an integer", __FILE__, __LINE__);
}
size_t st = *((size_t*) (this->str->str + this->pos));
this->pos += sizeof(size_t);
return st;
}
string ObjectInputStream::readString()
{
XOJ_CHECK_TYPE(ObjectInputStream);

@ -33,6 +33,7 @@ public:
int readInt();
double readDouble();
size_t readSizeT();
string readString();
void readData(void** data, int* len);

@ -56,6 +56,14 @@ void ObjectOutputStream::writeDouble(double d)
this->encoder->addData(&d, sizeof(double));
}
void ObjectOutputStream::writeSizeT(size_t st)
{
XOJ_CHECK_TYPE(ObjectOutputStream);
this->encoder->addStr("_l");
this->encoder->addData(&st, sizeof(size_t));
}
void ObjectOutputStream::writeString(const char* str)
{
XOJ_CHECK_TYPE(ObjectOutputStream);

@ -30,6 +30,7 @@ public:
void writeInt(int i);
void writeDouble(double d);
void writeSizeT(size_t st);
void writeString(const char* str);
void writeString(const string& s);

Loading…
Cancel
Save