OpenShot Library | libopenshot 1.1.1
Loading...
Searching...
No Matches
AudioRecorder.h
Go to the documentation of this file.
1
9// Copyright (c) 2008-2026 OpenShot Studios, LLC
10//
11// SPDX-License-Identifier: LGPL-3.0-or-later
12
13#ifndef OPENSHOT_AUDIORECORDER_H
14#define OPENSHOT_AUDIORECORDER_H
15
16#include <atomic>
17#include <condition_variable>
18#include <cstdint>
19#include <deque>
20#include <functional>
21#include <map>
22#include <memory>
23#include <mutex>
24#include <string>
25#include <thread>
26#include <vector>
27
28#include <AppConfig.h>
29#include <juce_audio_basics/juce_audio_basics.h>
30#include <juce_audio_devices/juce_audio_devices.h>
31
32#include "AudioWaveformer.h"
33#include "ChannelLayouts.h"
34
35namespace openshot
36{
37 class FFmpegWriter;
38 class Frame;
39
41 {
42 std::string path;
43 std::string device_name;
44 std::string device_type;
45 std::string codec = "pcm_s16le";
46 int sample_rate = 48000;
47 int channels = 1;
49 int bit_rate = 192000;
50 int buffer_size = 512;
53 std::map<std::string, std::string> options;
54 };
55
57 {
58 double timestamp = 0.0;
59 std::vector<float> peak;
60 std::vector<float> rms;
61 bool clipped = false;
62
63 std::vector<std::vector<float>> vectors() const
64 {
65 std::vector<std::vector<float>> output;
66 output.push_back(peak);
67 output.push_back(rms);
68 return output;
69 }
70 };
71
73 {
74 double start_time = 0.0;
75 double duration = 0.0;
77 std::vector<float> max_samples;
78 std::vector<float> rms_samples;
79
80 std::vector<std::vector<float>> vectors() const
81 {
82 std::vector<std::vector<float>> output;
83 output.push_back(max_samples);
84 output.push_back(rms_samples);
85 return output;
86 }
87 };
88
90 {
91 bool is_open = false;
92 bool is_recording = false;
93 int sample_rate = 0;
94 int channels = 0;
95 int64_t samples_recorded = 0;
96 int64_t dropped_blocks = 0;
97 int64_t queued_blocks = 0;
98 double duration = 0.0;
99 };
100
102 {
103 int sample_rate = 0;
104 int64_t first_sample = 0;
105 std::vector<std::vector<float>> channels;
106
107 int Samples() const
108 {
109 return channels.empty() ? 0 : static_cast<int>(channels.front().size());
110 }
111 };
112
114 {
115 public:
120 static int DeviceChannels(int requested_channels);
121
122#ifndef SWIG
125 static void FillBlock(
126 AudioRecorderBlock& block,
127 int channels,
128 const float* const* input_channel_data,
129 int num_input_channels,
130 int num_samples);
131#endif
132 };
133
135 {
136 public:
138 };
139
141 {
142 public:
143 AudioRecorderWaveformAccumulator(int sample_rate, int samples_per_second);
144
145 std::vector<AudioWaveformChunk> ProcessBlock(const AudioRecorderBlock& block);
147 void Reset();
148
149 private:
150 int sample_rate;
151 int samples_per_second;
152 int sample_divisor;
153 int pending_samples;
154 float pending_max;
155 double pending_squared_sum;
156 int64_t emitted_visual_samples;
157 std::vector<float> max_samples;
158 std::vector<float> rms_samples;
159 };
160
162 {
163 public:
164 static std::shared_ptr<openshot::Frame> CreateFrame(
165 const AudioRecorderBlock& block,
166 openshot::ChannelLayout channel_layout,
167 int64_t frame_number);
168 };
169
171#ifndef SWIG
172 : private juce::AudioIODeviceCallback
173#endif
174 {
175 public:
176 explicit AudioRecorder(const AudioRecorderSettings& settings);
178#ifndef SWIG
179 override
180#endif
181 ;
182
183 void Open();
184 void PrepareRecording();
185 void Start();
186 void Stop();
187 void StartMonitoring();
188 void StopMonitoring();
189 void Close();
190
191 bool IsOpen() const;
192 bool IsRecording() const;
193 bool IsMonitoring() const;
197
198#ifndef SWIG
199 void SetLevelCallback(std::function<void(const AudioLevelData&)> callback);
200 void SetWaveformCallback(std::function<void(const AudioWaveformChunk&)> callback);
202 const float* const* inputChannelData,
203 int numInputChannels,
204 float* const* outputChannelData,
205 int numOutputChannels,
206 int numSamples,
207 const juce::AudioIODeviceCallbackContext& context) override;
208 void audioDeviceAboutToStart(juce::AudioIODevice* device) override;
209 void audioDeviceStopped() override;
210#endif
211
212 private:
213 void ValidateSettings() const;
214 juce::String OpenDevice(int device_channels);
215 void OpenWriter();
216 void WriterLoop();
217 bool PopBlock(AudioRecorderBlock& block);
218
219 AudioRecorderSettings settings;
220 juce::AudioDeviceManager device_manager;
221 std::unique_ptr<openshot::FFmpegWriter> writer;
222 std::unique_ptr<AudioRecorderWaveformAccumulator> waveform_accumulator;
223 AudioRecorderLevelMeter level_meter;
224
225 mutable std::mutex state_mutex;
226 mutable std::mutex queue_mutex;
227 std::condition_variable queue_condition;
228 std::deque<AudioRecorderBlock> queue;
229 std::thread writer_thread;
230
231 std::function<void(const AudioLevelData&)> level_callback;
232 std::function<void(const AudioWaveformChunk&)> waveform_callback;
233 AudioLevelData last_level;
234
235 std::atomic<bool> is_open;
236 std::atomic<bool> is_recording;
237 std::atomic<bool> is_monitoring;
238 std::atomic<bool> writer_should_stop;
239 std::atomic<int64_t> samples_recorded;
240 std::atomic<int64_t> dropped_blocks;
241 int64_t next_frame_number;
242 };
243}
244
245#endif
Header file for AudioWaveformer class.
Header file for ChannelLayout class.
static int DeviceChannels(int requested_channels)
static void FillBlock(AudioRecorderBlock &block, int channels, const float *const *input_channel_data, int num_input_channels, int num_samples)
AudioLevelData ProcessBlock(const AudioRecorderBlock &block) const
std::vector< AudioWaveformChunk > ProcessBlock(const AudioRecorderBlock &block)
openshot::AudioWaveformData Snapshot() const
void SetWaveformCallback(std::function< void(const AudioWaveformChunk &)> callback)
void SetLevelCallback(std::function< void(const AudioLevelData &)> callback)
AudioRecorderStats GetStats() const
void audioDeviceAboutToStart(juce::AudioIODevice *device) override
openshot::AudioWaveformData GetWaveformSnapshot() const
void audioDeviceStopped() override
AudioLevelData GetLevelSnapshot() const
void audioDeviceIOCallbackWithContext(const float *const *inputChannelData, int numInputChannels, float *const *outputChannelData, int numOutputChannels, int numSamples, const juce::AudioIODeviceCallbackContext &context) override
static std::shared_ptr< openshot::Frame > CreateFrame(const AudioRecorderBlock &block, openshot::ChannelLayout channel_layout, int64_t frame_number)
This namespace is the default namespace for all code in the openshot library.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround,...
std::vector< float > rms
std::vector< float > peak
std::vector< std::vector< float > > vectors() const
std::vector< std::vector< float > > channels
std::map< std::string, std::string > options
openshot::ChannelLayout channel_layout
std::vector< float > max_samples
std::vector< float > rms_samples
std::vector< std::vector< float > > vectors() const
This struct holds the extracted waveform data (both the RMS root-mean-squared average,...