OpenShot Library | libopenshot 0.3.3
Loading...
Searching...
No Matches
Echo.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 "Echo.h"
14#include "Exceptions.h"
15#include "Frame.h"
16
17using namespace openshot;
18
19Echo::Echo() : Echo::Echo(0.1, 0.5, 0.5) { }
20
21Echo::Echo(Keyframe echo_time, Keyframe feedback, Keyframe mix) :
22 echo_time(echo_time), feedback(feedback), mix(mix)
23{
24 // Init effect properties
25 init_effect_details();
26}
27
28// Init effect settings
29void Echo::init_effect_details()
30{
33
35 info.class_name = "Echo";
36 info.name = "Echo";
37 info.description = "Reflection of sound with a delay after the direct sound.";
38 info.has_audio = true;
39 info.has_video = false;
40 initialized = false;
41}
42
43void Echo::setup(std::shared_ptr<openshot::Frame> frame)
44{
45 if (!initialized)
46 {
47 const float max_echo_time = 5;
48 echo_buffer_samples = (int)(max_echo_time * (float)frame->SampleRate()) + 1;
49
50 if (echo_buffer_samples < 1)
52
53 echo_buffer_channels = frame->audio->getNumChannels();
55 echo_buffer.clear();
57 initialized = true;
58 }
59}
60
61// This method is required for all derived classes of EffectBase, and returns a
62// modified openshot::Frame object
63std::shared_ptr<openshot::Frame> Echo::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
64{
65 const float echo_time_value = (float)echo_time.GetValue(frame_number)*(float)frame->SampleRate();
66 const float feedback_value = feedback.GetValue(frame_number);
67 const float mix_value = mix.GetValue(frame_number);
68 int local_write_position;
69
70 setup(frame);
71
72 for (int channel = 0; channel < frame->audio->getNumChannels(); channel++)
73 {
74 float *channel_data = frame->audio->getWritePointer(channel);
75 float *echo_data = echo_buffer.getWritePointer(channel);
76 local_write_position = echo_write_position;
77
78 for (auto sample = 0; sample < frame->audio->getNumSamples(); ++sample)
79 {
80 const float in = (float)(channel_data[sample]);
81 float out = 0.0f;
82
83 float read_position = fmodf((float)local_write_position - echo_time_value + (float)echo_buffer_samples, echo_buffer_samples);
84 int local_read_position = floorf(read_position);
85
86 if (local_read_position != local_write_position)
87 {
88 float fraction = read_position - (float)local_read_position;
89 float echoed1 = echo_data[(local_read_position + 0)];
90 float echoed2 = echo_data[(local_read_position + 1) % echo_buffer_samples];
91 out = (float)(echoed1 + fraction * (echoed2 - echoed1));
92 channel_data[sample] = in + mix_value*(out - in);
93 echo_data[local_write_position] = in + out*feedback_value;
94 }
95
96 if (++local_write_position >= echo_buffer_samples)
97 local_write_position -= echo_buffer_samples;
98 }
99 }
100
101 echo_write_position = local_write_position;
102
103 // return the modified frame
104 return frame;
105}
106
107// Generate JSON string of this object
108std::string Echo::Json() const {
109
110 // Return formatted string
111 return JsonValue().toStyledString();
112}
113
114// Generate Json::Value for this object
115Json::Value Echo::JsonValue() const {
116
117 // Create root json object
118 Json::Value root = EffectBase::JsonValue(); // get parent properties
119 root["type"] = info.class_name;
120 root["echo_time"] = echo_time.JsonValue();
121 root["feedback"] = feedback.JsonValue();
122 root["mix"] = mix.JsonValue();
123
124 // return JsonValue
125 return root;
126}
127
128// Load JSON string into this object
129void Echo::SetJson(const std::string value) {
130
131 // Parse JSON string into JSON objects
132 try
133 {
134 const Json::Value root = openshot::stringToJson(value);
135 // Set all values that match
136 SetJsonValue(root);
137 }
138 catch (const std::exception& e)
139 {
140 // Error parsing JSON (or missing keys)
141 throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
142 }
143}
144
145// Load Json::Value into this object
146void Echo::SetJsonValue(const Json::Value root) {
147
148 // Set parent data
150
151 // Set data from Json (if key is found)
152 if (!root["echo_time"].isNull())
153 echo_time.SetJsonValue(root["echo_time"]);
154 if (!root["feedback"].isNull())
155 feedback.SetJsonValue(root["feedback"]);
156 if (!root["mix"].isNull())
157 mix.SetJsonValue(root["mix"]);
158}
159
160// Get all properties for a specific frame
161std::string Echo::PropertiesJSON(int64_t requested_frame) const {
162
163 // Generate JSON properties list
164 Json::Value root = BasePropertiesJSON(requested_frame);
165
166 // Keyframes
167 root["echo_time"] = add_property_json("Time", echo_time.GetValue(requested_frame), "float", "", &echo_time, 0, 5, false, requested_frame);
168 root["feedback"] = add_property_json("Feedback", feedback.GetValue(requested_frame), "float", "", &feedback, 0, 1, false, requested_frame);
169 root["mix"] = add_property_json("Mix", mix.GetValue(requested_frame), "float", "", &mix, 0, 1, false, requested_frame);
170
171 // Return formatted string
172 return root.toStyledString();
173}
Header file for Echo audio effect class.
Header file for all Exception classes.
Header file for Frame class.
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
This class adds a echo into the audio.
Definition Echo.h:36
Keyframe mix
Definition Echo.h:44
void SetJson(const std::string value) override
Load JSON string into this object.
Definition Echo.cpp:129
int echo_buffer_channels
Definition Echo.h:48
Keyframe echo_time
Definition Echo.h:42
std::string Json() const override
Generate JSON string of this object.
Definition Echo.cpp:108
int echo_write_position
Definition Echo.h:49
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition Echo.cpp:146
juce::AudioBuffer< float > echo_buffer
Definition Echo.h:46
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 Echo.h:58
bool initialized
Definition Echo.h:50
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition Echo.cpp:115
Echo()
Default constructor.
Definition Echo.cpp:19
int echo_buffer_samples
Definition Echo.h:47
std::string PropertiesJSON(int64_t requested_frame) const override
Definition Echo.cpp:161
void setup(std::shared_ptr< openshot::Frame > frame)
Definition Echo.cpp:43
Keyframe feedback
Definition Echo.h:43
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
EffectInfoStruct info
Information about the current effect.
Definition EffectBase.h:69
Exception for invalid JSON.
Definition Exceptions.h:218
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition KeyFrame.h:53
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition KeyFrame.cpp:372
double GetValue(int64_t index) const
Get the value at a specific index.
Definition KeyFrame.cpp:258
Json::Value JsonValue() const
Generate Json::Value for this object.
Definition KeyFrame.cpp:339
This namespace is the default namespace for all code in the openshot library.
Definition Compressor.h:29
const Json::Value stringToJson(const std::string value)
Definition Json.cpp:16
bool has_video
Determines if this effect manipulates the image of a frame.
Definition EffectBase.h:40
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition EffectBase.h:41
std::string class_name
The class name of the effect.
Definition EffectBase.h:36
std::string name
The name of the effect.
Definition EffectBase.h:37
std::string description
The description of this effect and what it does.
Definition EffectBase.h:38