OpenShot Library | libopenshot  0.4.0
Delay.cpp
Go to the documentation of this file.
1 
9 // Copyright (c) 2008-2019 OpenShot Studios, LLC
10 //
11 // SPDX-License-Identifier: LGPL-3.0-or-later
12 
13 #include "Delay.h"
14 #include "Exceptions.h"
15 #include "Frame.h"
16 
17 using namespace openshot;
18 
20 
21 Delay::Delay(Keyframe delay_time) : delay_time(delay_time)
22 {
23  init_effect_details();
24 }
25 
26 // Init effect settings
27 void Delay::init_effect_details()
28 {
31 
33  info.class_name = "Delay";
34  info.name = "Delay";
35  info.description = "Adjust the synchronism between the audio and video track.";
36  info.has_audio = true;
37  info.has_video = false;
38  initialized = false;
39 }
40 
41 void Delay::setup(std::shared_ptr<openshot::Frame> frame)
42 {
43  if (!initialized)
44  {
45  const float max_delay_time = 5;
46  delay_buffer_samples = (int)(max_delay_time * (float)frame->SampleRate()) + 1;
47 
48  if (delay_buffer_samples < 1)
50 
51  delay_buffer_channels = frame->audio->getNumChannels();
53  delay_buffer.clear();
55  initialized = true;
56  }
57 }
58 
59 // This method is required for all derived classes of EffectBase, and returns a
60 // modified openshot::Frame object
61 std::shared_ptr<openshot::Frame> Delay::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
62 {
63  const float delay_time_value = (float)delay_time.GetValue(frame_number)*(float)frame->SampleRate();
64  int local_write_position;
65 
66  setup(frame);
67 
68  for (int channel = 0; channel < frame->audio->getNumChannels(); channel++)
69  {
70  float *channel_data = frame->audio->getWritePointer(channel);
71  float *delay_data = delay_buffer.getWritePointer(channel);
72  local_write_position = delay_write_position;
73 
74  for (auto sample = 0; sample < frame->audio->getNumSamples(); ++sample)
75  {
76  const float in = (float)(channel_data[sample]);
77  float out = 0.0f;
78 
79  float read_position = fmodf((float)local_write_position - delay_time_value + (float)delay_buffer_samples, delay_buffer_samples);
80  int local_read_position = floorf(read_position);
81 
82  if (local_read_position != local_write_position)
83  {
84  float fraction = read_position - (float)local_read_position;
85  float delayed1 = delay_data[(local_read_position + 0)];
86  float delayed2 = delay_data[(local_read_position + 1) % delay_buffer_samples];
87  out = (float)(delayed1 + fraction * (delayed2 - delayed1));
88 
89  channel_data[sample] = in + (out - in);
90  delay_data[local_write_position] = in;
91  }
92 
93  if (++local_write_position >= delay_buffer_samples)
94  local_write_position -= delay_buffer_samples;
95  }
96  }
97 
98  delay_write_position = local_write_position;
99 
100  // return the modified frame
101  return frame;
102 }
103 
104 // Generate JSON string of this object
105 std::string Delay::Json() const {
106 
107  // Return formatted string
108  return JsonValue().toStyledString();
109 }
110 
111 // Generate Json::Value for this object
112 Json::Value Delay::JsonValue() const {
113 
114  // Create root json object
115  Json::Value root = EffectBase::JsonValue(); // get parent properties
116  root["type"] = info.class_name;
117  root["delay_time"] = delay_time.JsonValue();
118 
119  // return JsonValue
120  return root;
121 }
122 
123 // Load JSON string into this object
124 void Delay::SetJson(const std::string value) {
125 
126  // Parse JSON string into JSON objects
127  try
128  {
129  const Json::Value root = openshot::stringToJson(value);
130  // Set all values that match
131  SetJsonValue(root);
132  }
133  catch (const std::exception& e)
134  {
135  // Error parsing JSON (or missing keys)
136  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
137  }
138 }
139 
140 // Load Json::Value into this object
141 void Delay::SetJsonValue(const Json::Value root) {
142 
143  // Set parent data
145 
146  // Set data from Json (if key is found)
147  if (!root["delay_time"].isNull())
148  delay_time.SetJsonValue(root["delay_time"]);
149 }
150 
151 // Get all properties for a specific frame
152 std::string Delay::PropertiesJSON(int64_t requested_frame) const {
153 
154  // Generate JSON properties list
155  Json::Value root = BasePropertiesJSON(requested_frame);
156 
157  // Keyframes
158  root["delay_time"] = add_property_json("Delay Time", delay_time.GetValue(requested_frame), "float", "", &delay_time, 0, 5, false, requested_frame);
159 
160  // Return formatted string
161  return root.toStyledString();
162 }
openshot::ClipBase::add_property_json
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
Generate JSON for a property.
Definition: ClipBase.cpp:96
openshot::stringToJson
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:16
openshot::Delay::setup
void setup(std::shared_ptr< openshot::Frame > frame)
Definition: Delay.cpp:41
openshot::EffectBase::info
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:69
openshot::Delay::Delay
Delay()
Default constructor.
Definition: Delay.cpp:19
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::Delay
This class adds a delay into the audio.
Definition: Delay.h:35
openshot::Delay::delay_write_position
int delay_write_position
Definition: Delay.h:47
openshot::EffectBase::JsonValue
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:79
openshot::Delay::delay_time
Keyframe delay_time
Definition: Delay.h:42
openshot::Keyframe::SetJsonValue
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: KeyFrame.cpp:372
openshot::Delay::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a new openshot::Frame object...
Definition: Delay.h:56
openshot::Keyframe::JsonValue
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: KeyFrame.cpp:339
openshot::Delay::Json
std::string Json() const override
Generate JSON string of this object.
Definition: Delay.cpp:105
openshot::EffectBase::BasePropertiesJSON
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
Definition: EffectBase.cpp:179
openshot::Delay::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: Delay.cpp:124
openshot::Keyframe
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:53
openshot::Delay::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: Delay.cpp:112
openshot::InvalidJSON
Exception for invalid JSON.
Definition: Exceptions.h:217
openshot::Delay::PropertiesJSON
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: Delay.cpp:152
openshot::EffectBase::InitEffectInfo
void InitEffectInfo()
Definition: EffectBase.cpp:24
openshot::EffectInfoStruct::has_audio
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:41
Delay.h
Header file for Delay audio effect class.
openshot::Delay::initialized
bool initialized
Definition: Delay.h:48
openshot::Delay::delay_buffer_samples
int delay_buffer_samples
Definition: Delay.h:45
Frame.h
Header file for Frame class.
openshot::Delay::delay_buffer
juce::AudioBuffer< float > delay_buffer
Definition: Delay.h:44
openshot::EffectInfoStruct::class_name
std::string class_name
The class name of the effect.
Definition: EffectBase.h:36
openshot::EffectInfoStruct::description
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:38
openshot::EffectInfoStruct::has_video
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:40
openshot::Delay::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: Delay.cpp:141
openshot::EffectInfoStruct::name
std::string name
The name of the effect.
Definition: EffectBase.h:37
Exceptions.h
Header file for all Exception classes.
openshot::Delay::delay_buffer_channels
int delay_buffer_channels
Definition: Delay.h:46
openshot::EffectBase::SetJsonValue
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:115
openshot::Keyframe::GetValue
double GetValue(int64_t index) const
Get the value at a specific index.
Definition: KeyFrame.cpp:258