Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Import initial code
- Loading branch information
0 parents
commit a543449
Showing
532 changed files
with
109,502 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Oops, something went wrong.