Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Import initial code
  • Loading branch information
falkTX committed Feb 9, 2017
0 parents commit a543449
Show file tree
Hide file tree
Showing 532 changed files with 109,502 additions and 0 deletions.
103 changes: 103 additions & 0 deletions hylia.cpp
@@ -0,0 +1,103 @@
/*
* This file is part of Hylia.
*
* Hylia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Hylia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Hylia. If not, see <http://www.gnu.org/licenses/>.
*/

#include "mod-link.h"

#include "AudioEngine.hpp"
#include "ableton/link/HostTimeFilter.hpp"
#include <chrono>

class HyliaTransport {
public:
HyliaTransport(double bpm, double bufferSize, double sampleRate)
: link(bpm),
engine(link),
outputLatency(0),
sampleTime(0)
{
outputLatency = std::chrono::microseconds(llround(1.0e6 * bufferSize / sampleRate));
}

void setEnabled(bool enabled, double bpm)
{
link.enable(enabled);

if (enabled)
{
sampleTime = 0;
engine.setTempo(bpm);
}
}

void setTempo(double tempo)
{
engine.setTempo(tempo);
}

void process(uint32_t frames, LinkTimeInfo* info)
{
const auto hostTime = hostTimeFilter.sampleTimeToHostTime(sampleTime);
const auto bufferBeginAtOutput = hostTime + outputLatency;

engine.timelineCallback(bufferBeginAtOutput, info);

sampleTime += frames;
}

private:
ableton::Link link;
ableton::linkaudio::AudioEngine engine;

ableton::link::HostTimeFilter<ableton::platforms::stl::Clock> hostTimeFilter;
std::chrono::microseconds outputLatency;
uint32_t sampleTime;
};

hylia_t* hylia_create(double bpm, uint32_t buffer_size, uint32_t sample_rate)
{
HyliaTransport* t;

try {
t = new HyliaTransport(bpm, buffer_size, sample_rate);
} catch (...) {
return nullptr;
}

return (hylia_t*)t;
}

void hylia_enable(hylia_t* link, bool on, double bpm)
{
((HyliaTransport*)link)->setEnabled(on, bpm);
}

void hylia_set_tempo(hylia_t* link, double bpm)
{
((HyliaTransport*)link)->setTempo(bpm);
}

void hylia_process(hylia_t* link, uint32_t frames, hylia_time_info_t* info)
{
((HyliaTransport*)link)->process(frames, (LinkTimeInfo*)info);
}

void hylia_cleanup(hylia_t* link)
{
delete (HyliaTransport*)link;
}

#include "AudioEngine.cpp"
45 changes: 45 additions & 0 deletions hylia.h
@@ -0,0 +1,45 @@
/*
* This file is part of Hylia.
*
* Hylia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Hylia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Hylia. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef MOD_LINK_H_INCLUDED
#define MOD_LINK_H_INCLUDED

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif

typedef struct _hylia_t hylia_t;

typedef struct _hylia_time_info_t {
double bpm, beats, phase;
} hylia_time_info_t;

hylia_t* hylia_create(double bpm, uint32_t buffer_size, uint32_t sample_rate);
void hylia_enable(hylia_t* link, bool on, double bpm);
void hylia_process(hylia_t* link, uint32_t frames, hylia_time_info_t* info);
void hylia_set_tempo(hylia_t* link, double tempo);
void hylia_cleanup(hylia_t* link);

#ifdef __cplusplus
}
#endif

#endif // MOD_LINK_H_INCLUDED
107 changes: 107 additions & 0 deletions link/AudioEngine.cpp
@@ -0,0 +1,107 @@
/* Copyright 2016, Ableton AG, Berlin. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If you would like to incorporate Link into a proprietary software application,
* please contact <link-devs@ableton.com>.
*/

#include "AudioEngine.hpp"

// Make sure to define this before <cmath> is included for Windows
#define _USE_MATH_DEFINES
#include <cmath>

namespace ableton
{
namespace linkaudio
{

AudioEngine::AudioEngine(Link& link)
: mLink(link)
, mSharedEngineData({0., false, 4.})
{
}

double AudioEngine::beatTime() const
{
const auto timeline = mLink.captureAppTimeline();
return timeline.beatAtTime(mLink.clock().micros(), mSharedEngineData.quantum);
}

void AudioEngine::setTempo(double tempo)
{
std::lock_guard<std::mutex> lock(mEngineDataGuard);
mSharedEngineData.requestedTempo = tempo;
}

double AudioEngine::quantum() const
{
return mSharedEngineData.quantum;
}

void AudioEngine::setQuantum(double quantum)
{
std::lock_guard<std::mutex> lock(mEngineDataGuard);
mSharedEngineData.quantum = quantum;
mSharedEngineData.resetBeatTime = true;
}

AudioEngine::EngineData AudioEngine::pullEngineData()
{
auto engineData = EngineData{};
if (mEngineDataGuard.try_lock())
{
engineData.requestedTempo = mSharedEngineData.requestedTempo;
mSharedEngineData.requestedTempo = 0;
engineData.resetBeatTime = mSharedEngineData.resetBeatTime;
engineData.quantum = mSharedEngineData.quantum;
mSharedEngineData.resetBeatTime = false;

mEngineDataGuard.unlock();
}

return engineData;
}

void AudioEngine::timelineCallback(const std::chrono::microseconds hostTime, LinkTimeInfo* const info)
{
const auto engineData = pullEngineData();

auto timeline = mLink.captureAudioTimeline();

if (engineData.resetBeatTime)
{
// Reset the timeline so that beat 0 lands at the beginning of
// this buffer and clear the flag.
timeline.requestBeatAtTime(0, hostTime, engineData.quantum);
}

if (engineData.requestedTempo > 0)
{
// Set the newly requested tempo from the beginning of this buffer
timeline.setTempo(engineData.requestedTempo, hostTime);
}

// Timeline modifications are complete, commit the results
mLink.commitAudioTimeline(timeline);

// Save timeline info
info->bpm = timeline.tempo();
info->beats = timeline.beatAtTime(hostTime, engineData.quantum);
info->phase = timeline.phaseAtTime(hostTime, engineData.quantum);
}

} // namespace linkaudio
} // namespace ableton
66 changes: 66 additions & 0 deletions link/AudioEngine.hpp
@@ -0,0 +1,66 @@
/* Copyright 2016, Ableton AG, Berlin. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If you would like to incorporate Link into a proprietary software application,
* please contact <link-devs@ableton.com>.
*/

#pragma once

// Make sure to define this before <cmath> is included for Windows
#define _USE_MATH_DEFINES
#include "ableton/Link.hpp"
#include <mutex>

struct LinkTimeInfo {
double bpm, beats, phase;
};

namespace ableton
{
namespace linkaudio
{

class AudioEngine
{
public:
AudioEngine(Link& link);
double beatTime() const;
void setTempo(double tempo);
double quantum() const;
void setQuantum(double quantum);

void timelineCallback(const std::chrono::microseconds hostTime, LinkTimeInfo* const info);

private:
struct EngineData
{
double requestedTempo;
bool resetBeatTime;
double quantum;
};

EngineData pullEngineData();

Link& mLink;
EngineData mSharedEngineData;
std::mutex mEngineDataGuard;

friend class AudioPlatform;
};


} // namespace linkaudio
} // namespace ableton

0 comments on commit a543449

Please sign in to comment.