react-native-audio-api 0.11.0-alpha.0 → 0.11.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +77 -29
  2. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +17 -4
  3. package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +6 -2
  4. package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.cpp +187 -0
  5. package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.h +57 -0
  6. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +22 -24
  7. package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +3 -2
  8. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +40 -8
  9. package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +3 -2
  10. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +24 -7
  11. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +3 -0
  12. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +16 -115
  13. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +35 -32
  14. package/ios/audioapi/ios/core/IOSAudioFileOptions.h +1 -0
  15. package/ios/audioapi/ios/core/IOSAudioFileOptions.mm +5 -0
  16. package/ios/audioapi/ios/core/IOSAudioFileWriter.h +16 -3
  17. package/ios/audioapi/ios/core/IOSAudioFileWriter.mm +86 -50
  18. package/ios/audioapi/ios/core/IOSAudioRecorder.h +11 -2
  19. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +76 -31
  20. package/ios/audioapi/ios/core/IOSRecorderCallback.h +57 -0
  21. package/ios/audioapi/ios/core/IOSRecorderCallback.mm +189 -0
  22. package/ios/audioapi/ios/core/NativeAudioRecorder.h +2 -3
  23. package/ios/audioapi/ios/core/NativeAudioRecorder.m +26 -0
  24. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +1 -0
  25. package/lib/commonjs/core/AudioRecorder.js +14 -1
  26. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  27. package/lib/module/core/AudioRecorder.js +14 -1
  28. package/lib/module/core/AudioRecorder.js.map +1 -1
  29. package/lib/typescript/core/AudioRecorder.d.ts +6 -3
  30. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  31. package/lib/typescript/interfaces.d.ts +5 -3
  32. package/lib/typescript/interfaces.d.ts.map +1 -1
  33. package/lib/typescript/types.d.ts +5 -0
  34. package/lib/typescript/types.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/src/core/AudioRecorder.ts +27 -10
  37. package/src/interfaces.ts +6 -2
  38. package/src/types.ts +6 -0
@@ -4,6 +4,8 @@
4
4
  #include <audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h>
5
5
  #include <audioapi/libs/miniaudio/miniaudio.h>
6
6
 
7
+ constexpr double BYTES_TO_MB = 1024.0 * 1024.0;
8
+
7
9
  namespace audioapi {
8
10
 
9
11
  MiniAudioFileWriter::MiniAudioFileWriter(
@@ -41,7 +43,7 @@ MiniAudioFileWriter::~MiniAudioFileWriter() {
41
43
  }
42
44
  }
43
45
 
44
- void MiniAudioFileWriter::openFile(
46
+ std::string MiniAudioFileWriter::openFile(
45
47
  int32_t streamSampleRate,
46
48
  int32_t streamChannelCount,
47
49
  int32_t streamMaxBufferSize) {
@@ -58,21 +60,23 @@ void MiniAudioFileWriter::openFile(
58
60
  success = initializeConverterIfNeeded();
59
61
 
60
62
  if (!success) {
61
- return;
63
+ return "";
62
64
  }
63
65
 
64
66
  success = initializeEncoder();
65
67
 
66
68
  if (!success) {
67
- return;
69
+ return "";
68
70
  }
69
71
 
70
72
  isFileOpen_.store(true);
73
+
74
+ return filePath_;
71
75
  }
72
76
 
73
- std::string MiniAudioFileWriter::closeFile() {
77
+ std::tuple<double, double> MiniAudioFileWriter::closeFile() {
74
78
  if (!isFileOpen()) {
75
- return "";
79
+ return {0.0, 0.0};
76
80
  }
77
81
 
78
82
  isFileOpen_.store(false);
@@ -93,10 +97,36 @@ std::string MiniAudioFileWriter::closeFile() {
93
97
  processingBufferLength_ = 0;
94
98
  }
95
99
 
96
- std::string closedFilePath = filePath_;
97
- filePath_ = "";
100
+ // Retrieve duration and file size
101
+ std::string filePath = filePath_;
102
+ double durationInSeconds = 0.0;
103
+ double fileSizeInMB = 0.0;
104
+
105
+ ma_decoder decoder;
106
+
107
+ if (ma_decoder_init_file(filePath_.c_str(), NULL, &decoder) == MA_SUCCESS) {
108
+ ma_uint64 frameCount = 0;
98
109
 
99
- return closedFilePath;
110
+ if (ma_decoder_get_length_in_pcm_frames(&decoder, &frameCount) ==
111
+ MA_SUCCESS) {
112
+ durationInSeconds =
113
+ static_cast<double>(frameCount) / decoder.outputSampleRate;
114
+ }
115
+
116
+ ma_decoder_uninit(&decoder);
117
+ }
118
+
119
+ FILE *file = fopen(filePath_.c_str(), "rb");
120
+
121
+ if (file != nullptr) {
122
+ fseek(file, 0, SEEK_END);
123
+ long fileSizeInBytes = ftell(file);
124
+ fclose(file);
125
+ fileSizeInMB = static_cast<double>(fileSizeInBytes) / BYTES_TO_MB;
126
+ }
127
+
128
+ filePath_ = "";
129
+ return {fileSizeInMB, durationInSeconds};
100
130
  }
101
131
 
102
132
  bool MiniAudioFileWriter::writeAudioData(void *data, int numFrames) {
@@ -126,6 +156,7 @@ bool MiniAudioFileWriter::writeAudioData(void *data, int numFrames) {
126
156
  filePath_.c_str());
127
157
  }
128
158
 
159
+ framesWritten_.fetch_add(numFrames);
129
160
  return result == MA_SUCCESS;
130
161
  }
131
162
 
@@ -142,6 +173,7 @@ bool MiniAudioFileWriter::writeAudioData(void *data, int numFrames) {
142
173
  filePath_.c_str());
143
174
  }
144
175
 
176
+ framesWritten_.fetch_add(numFrames);
145
177
  return result == MA_SUCCESS;
146
178
  }
147
179
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <string>
7
7
  #include <memory>
8
+ #include <tuple>
8
9
 
9
10
  namespace audioapi {
10
11
 
@@ -19,8 +20,8 @@ class MiniAudioFileWriter : public AndroidFileWriterBackend {
19
20
  size_t androidFlags);
20
21
  ~MiniAudioFileWriter() override;
21
22
 
22
- void openFile(int32_t streamSampleRate, int32_t streamChannelCount, int32_t streamMaxBufferSize) override;
23
- std::string closeFile() override;
23
+ std::string openFile(int32_t streamSampleRate, int32_t streamChannelCount, int32_t streamMaxBufferSize) override;
24
+ std::tuple<double, double> closeFile() override;
24
25
 
25
26
  bool writeAudioData(void *data, int numFrames) override;
26
27
 
@@ -35,25 +35,36 @@ AudioRecorderHostObject::AudioRecorderHostObject(
35
35
  JSI_EXPORT_FUNCTION(AudioRecorderHostObject, connect),
36
36
  JSI_EXPORT_FUNCTION(AudioRecorderHostObject, disconnect),
37
37
  JSI_EXPORT_FUNCTION(AudioRecorderHostObject, setOnAudioReady),
38
- JSI_EXPORT_FUNCTION(AudioRecorderHostObject, clearOnAudioReady));
38
+ JSI_EXPORT_FUNCTION(AudioRecorderHostObject, clearOnAudioReady),
39
+ JSI_EXPORT_FUNCTION(AudioRecorderHostObject, getCurrentDuration));
39
40
  }
40
41
 
41
42
  JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, start) {
42
- audioRecorder_->start();
43
+ std::string filePath = audioRecorder_->start();
43
44
 
44
- return jsi::Value::undefined();
45
+ return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, filePath));
45
46
  }
46
47
 
47
48
  JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, stop) {
48
- std::string filePath = audioRecorder_->stop();
49
+ auto [path, size, duration] = audioRecorder_->stop();
50
+ auto result = jsi::Object(runtime);
49
51
 
50
- return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, filePath));
52
+ result.setProperty(
53
+ runtime, "path", jsi::String::createFromUtf8(runtime, path));
54
+ result.setProperty(runtime, "size", size);
55
+ result.setProperty(runtime, "duration", duration);
56
+
57
+ return result;
51
58
  }
52
59
 
53
60
  JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, isRecording) {
54
61
  return jsi::Value(audioRecorder_->isRecording());
55
62
  }
56
63
 
64
+ JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, isPaused) {
65
+ return jsi::Value(audioRecorder_->isPaused());
66
+ }
67
+
57
68
  JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, enableFileOutput) {
58
69
  auto options = args[0].getObject(runtime);
59
70
 
@@ -115,8 +126,9 @@ JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, setOnAudioReady) {
115
126
  options.getProperty(runtime, "bufferLength").getNumber());
116
127
  auto channelCount = static_cast<size_t>(
117
128
  options.getProperty(runtime, "channelCount").getNumber());
118
- auto callbackId = static_cast<uint64_t>(
119
- options.getProperty(runtime, "callbackId").getNumber());
129
+ uint64_t callbackId = std::stoull(options.getProperty(runtime, "callbackId")
130
+ .getString(runtime)
131
+ .utf8(runtime));
120
132
 
121
133
  audioRecorder_->setOnAudioReadyCallback(
122
134
  sampleRate, bufferLength, channelCount, callbackId);
@@ -128,4 +140,9 @@ JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, clearOnAudioReady) {
128
140
  return jsi::Value::undefined();
129
141
  }
130
142
 
143
+ JSI_HOST_FUNCTION_IMPL(AudioRecorderHostObject, getCurrentDuration) {
144
+ double duration = audioRecorder_->getCurrentDuration();
145
+ return jsi::Value(duration);
146
+ }
147
+
131
148
  } // namespace audioapi
@@ -22,6 +22,7 @@ class AudioRecorderHostObject : public JsiHostObject {
22
22
  JSI_HOST_FUNCTION_DECL(start);
23
23
  JSI_HOST_FUNCTION_DECL(stop);
24
24
  JSI_HOST_FUNCTION_DECL(isRecording);
25
+ JSI_HOST_FUNCTION_DECL(isPaused);
25
26
 
26
27
  JSI_HOST_FUNCTION_DECL(enableFileOutput);
27
28
  JSI_HOST_FUNCTION_DECL(disableFileOutput);
@@ -35,6 +36,8 @@ class AudioRecorderHostObject : public JsiHostObject {
35
36
  JSI_HOST_FUNCTION_DECL(setOnAudioReady);
36
37
  JSI_HOST_FUNCTION_DECL(clearOnAudioReady);
37
38
 
39
+ JSI_HOST_FUNCTION_DECL(getCurrentDuration);
40
+
38
41
  private:
39
42
  std::shared_ptr<AudioRecorder> audioRecorder_;
40
43
  };
@@ -1,112 +1,19 @@
1
- #include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
2
- #include <audioapi/core/inputs/AudioRecorder.h>
3
- #include <audioapi/core/sources/AudioBuffer.h>
4
- #include <audioapi/core/sources/RecorderAdapterNode.h>
5
- #include <audioapi/events/AudioEventHandlerRegistry.h>
6
- #include <audioapi/utils/AudioBus.h>
7
- #include <audioapi/utils/CircularAudioArray.h>
8
-
9
- namespace audioapi {
10
-
11
- AudioRecorder::AudioRecorder(
12
- const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
13
- : audioEventHandlerRegistry_(audioEventHandlerRegistry) {
14
- isRunning_.store(false);
15
- fileOutputEnabled_.store(false);
16
- callbackOutputEnabled_.store(false);
17
- isConnected_.store(false);
18
- }
19
-
20
- bool AudioRecorder::isRecording() {
21
- return isRunning_.load();
22
- }
23
-
24
- void AudioRecorder::connect(const std::shared_ptr<RecorderAdapterNode> &node) {
25
- // node->init();
26
- // adapterNodeLock_.lock();
27
- // adapterNode_ = node;
28
- // adapterNodeLock_.unlock();
29
- // isConnected_.store(true);
30
- // node->init(ringBufferSize_);
31
- // adapterNodeLock_.lock();
32
- // adapterNode_ = node;
33
- // adapterNodeLock_.unlock();
34
- }
35
-
36
- void AudioRecorder::disconnect() {
37
- // adapterNodeLock_.lock();
38
- // adapterNode_ = nullptr;
39
- // adapterNodeLock_.unlock();
40
- // isConnected_.store(false);
41
- }
42
-
43
- void AudioRecorder::setOnAudioReadyCallback(
44
- float sampleRate,
45
- size_t bufferLength,
46
- size_t channelCount,
47
- uint64_t callbackId) {
48
- callbackProperties_.sampleRate = sampleRate;
49
- callbackProperties_.bufferLength = bufferLength;
50
- callbackProperties_.channelCount = channelCount;
51
- callbackProperties_.callbackId = callbackId;
52
-
53
- callbackOutputEnabled_.store(true);
54
- }
55
-
56
- void AudioRecorder::clearOnAudioReadyCallback() {
57
- callbackOutputEnabled_.store(false);
58
- callbackProperties_ = CallbackProperties{};
59
- }
60
-
61
- void AudioRecorder::invokeOnAudioReadyCallback(
62
- const std::shared_ptr<AudioBus> &bus,
63
- int numFrames) {
64
- // if (!hasCallback()) {
65
- // return;
66
- // }
67
-
68
- // auto audioBuffer = std::make_shared<AudioBuffer>(bus);
69
- // auto audioBufferHostObject =
70
- // std::make_shared<AudioBufferHostObject>(audioBuffer);
71
-
72
- // std::unordered_map<std::string, EventValue> body = {};
73
- // body.insert({"buffer", audioBufferHostObject});
74
- // body.insert({"numFrames", numFrames});
75
-
76
- // if (audioEventHandlerRegistry_ != nullptr) {
77
- // audioEventHandlerRegistry_->invokeHandlerWithEventBody(
78
- // "audioReady", onAudioReadyCallbackId_, body);
79
- // }
80
- }
81
-
82
- void AudioRecorder::sendRemainingCallbackData() {
83
- // if (!hasCallback()) {
84
- // return;
85
- // }
86
-
87
- // auto bus = std::make_shared<AudioBus>(
88
- // circularBuffer_->getNumberOfAvailableFrames(), 1, sampleRate_);
89
- // auto *outputChannel = bus->getChannel(0)->getData();
90
- // auto availableFrames =
91
- // static_cast<int>(circularBuffer_->getNumberOfAvailableFrames());
92
-
93
- // circularBuffer_->pop_front(
94
- // outputChannel, circularBuffer_->getNumberOfAvailableFrames());
95
-
96
- // invokeOnAudioReadyCallback(bus, availableFrames);
97
- }
98
-
99
- bool AudioRecorder::usesCallback() const {
100
- return callbackOutputEnabled_.load();
101
- }
102
-
103
- bool AudioRecorder::usesFileOutput() const {
104
- return fileOutputEnabled_.load();
105
- }
1
+ // void AudioRecorder::connect(const std::shared_ptr<RecorderAdapterNode> &node)
2
+ // { node->init(); adapterNodeLock_.lock(); adapterNode_ = node;
3
+ // adapterNodeLock_.unlock();
4
+ // isConnected_.store(true);
5
+ // node->init(ringBufferSize_);
6
+ // adapterNodeLock_.lock();
7
+ // adapterNode_ = node;
8
+ // adapterNodeLock_.unlock();
9
+ // }
106
10
 
107
- bool AudioRecorder::isConnected() const {
108
- return isConnected_.load();
109
- }
11
+ // void AudioRecorder::disconnect() {
12
+ // adapterNodeLock_.lock();
13
+ // adapterNode_ = nullptr;
14
+ // adapterNodeLock_.unlock();
15
+ // isConnected_.store(false);
16
+ // }
110
17
 
111
18
  // AudioRecorder::AudioRecorder(
112
19
  // const std::shared_ptr<AudioEventHandlerRegistry>
@@ -116,7 +23,7 @@ bool AudioRecorder::isConnected() const {
116
23
  // ringBufferSize_ = std::max(2 * bufferLength, minRingBufferSize);
117
24
 
118
25
  // circularBuffer_ = std::make_shared<CircularAudioArray>(ringBufferSize_);
119
- // isRunning_.store(false);
26
+ // state_.store(RecorderState::Idle);
120
27
  // }
121
28
 
122
29
  // void AudioRecorder::writeToBuffers(const float *data, int numFrames) {
@@ -126,10 +33,4 @@ bool AudioRecorder::isConnected() const {
126
33
  // }
127
34
  // adapterNodeLock_.unlock();
128
35
  // }
129
-
130
- // if (hasCallback()) {
131
- // circularBuffer_->push_back(data, numFrames);
132
- // }
133
36
  // }
134
-
135
- } // namespace audioapi
@@ -4,6 +4,7 @@
4
4
  #include <atomic>
5
5
  #include <mutex>
6
6
  #include <string>
7
+ #include <tuple>
7
8
 
8
9
  namespace audioapi {
9
10
 
@@ -14,13 +15,13 @@ class AudioEventHandlerRegistry;
14
15
 
15
16
  class AudioRecorder {
16
17
  public:
17
- explicit AudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
18
+ enum RecorderState { Idle, Recording, Paused };
19
+ explicit AudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry):
20
+ audioEventHandlerRegistry_(audioEventHandlerRegistry) {}
18
21
  virtual ~AudioRecorder() = default;
19
22
 
20
- virtual void start() = 0;
21
- virtual std::string stop() = 0;
22
-
23
- bool isRecording();
23
+ virtual std::string start() = 0;
24
+ virtual std::tuple<std::string, double, double> stop() = 0;
24
25
 
25
26
  virtual void enableFileOutput(
26
27
  float sampleRate,
@@ -33,49 +34,51 @@ class AudioRecorder {
33
34
  virtual void pause() = 0;
34
35
  virtual void resume() = 0;
35
36
 
36
- void connect(const std::shared_ptr<RecorderAdapterNode> &node);
37
- void disconnect();
37
+ void connect(const std::shared_ptr<RecorderAdapterNode> &node) {}
38
+ void disconnect() {}
38
39
 
39
- void setOnAudioReadyCallback(
40
+ virtual void setOnAudioReadyCallback(
40
41
  float sampleRate,
41
42
  size_t bufferLength,
42
43
  size_t channelCount,
43
- uint64_t callbackId);
44
- void clearOnAudioReadyCallback();
44
+ uint64_t callbackId) = 0;
45
+ virtual void clearOnAudioReadyCallback() = 0;
46
+
47
+ virtual double getCurrentDuration() const = 0;
48
+
49
+ bool usesCallback() const {
50
+ return callbackOutputEnabled_.load();
51
+ }
45
52
 
46
- void invokeOnAudioReadyCallback(
47
- const std::shared_ptr<AudioBus> &bus,
48
- int numFrames);
49
- void sendRemainingCallbackData();
53
+ bool usesFileOutput() const {
54
+ return fileOutputEnabled_.load();
55
+ }
50
56
 
51
- bool usesCallback() const;
52
- bool usesFileOutput() const;
53
- bool isConnected() const;
57
+ bool isConnected() const {
58
+ return isConnected_.load();
59
+ }
60
+
61
+ bool isRecording() const {
62
+ return state_.load() == RecorderState::Recording;
63
+ }
64
+
65
+ bool isPaused() const {
66
+ return state_.load() == RecorderState::Paused;
67
+ }
54
68
 
55
69
  protected:
56
- struct CallbackProperties {
57
- float sampleRate;
58
- size_t bufferLength;
59
- size_t channelCount;
60
- uint64_t callbackId;
61
- };
62
-
63
- CallbackProperties callbackProperties_;
64
70
  // size_t ringBufferSize_;
65
71
 
66
- std::atomic<bool> isRunning_;
67
- std::atomic<bool> fileOutputEnabled_;
68
- std::atomic<bool> callbackOutputEnabled_;
69
- std::atomic<bool> isConnected_;
72
+ std::atomic<RecorderState> state_{ RecorderState::Idle };
73
+ std::atomic<bool> fileOutputEnabled_{false};
74
+ std::atomic<bool> callbackOutputEnabled_{false};
75
+ std::atomic<bool> isConnected_{false};
70
76
  // std::shared_ptr<CircularAudioArray> circularBuffer_;
71
77
 
72
78
  mutable std::mutex adapterNodeLock_;
73
79
  std::shared_ptr<RecorderAdapterNode> adapterNode_ = nullptr;
74
80
 
75
81
  std::shared_ptr<AudioEventHandlerRegistry> audioEventHandlerRegistry_;
76
- uint64_t onAudioReadyCallbackId_ = 0;
77
-
78
- // void writeToBuffers(const float *data, int numFrames);
79
82
  };
80
83
 
81
84
  } // namespace audioapi
@@ -20,6 +20,7 @@ class IOSAudioFileOptions {
20
20
  NSString *getFileExtension() const;
21
21
  NSInteger getBitDepth() const;
22
22
  NSDictionary *getFileSettings();
23
+ float getSampleRate();
23
24
 
24
25
  private:
25
26
  uint8_t format_;
@@ -132,4 +132,9 @@ NSDictionary *IOSAudioFileOptions::getFileSettings()
132
132
  return settings;
133
133
  }
134
134
 
135
+ float IOSAudioFileOptions::getSampleRate()
136
+ {
137
+ return sampleRate_;
138
+ }
139
+
135
140
  } // namespace audioapi
@@ -2,11 +2,15 @@
2
2
 
3
3
  #include <memory>
4
4
  #include <string>
5
+ #include <tuple>
5
6
 
6
7
  #ifndef __OBJC__ // when compiled as C++
7
- typedef struct objc_object AVAudioFile;
8
8
  typedef struct objc_object NSURL;
9
+ typedef struct objc_object NSString;
10
+ typedef struct objc_object AVAudioFile;
11
+ typedef struct objc_object AVAudioFormat;
9
12
  typedef struct objc_object AudioBufferList;
13
+ typedef struct objc_object AVAudioConverter;
10
14
  #endif // __OBJC__
11
15
 
12
16
  namespace audioapi {
@@ -18,12 +22,18 @@ class IOSAudioFileWriter {
18
22
  IOSAudioFileWriter(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags);
19
23
  ~IOSAudioFileWriter();
20
24
 
21
- void openFile(AVAudioFormat *bufferFormat);
22
- std::string closeFile();
25
+ std::string openFile(AVAudioFormat *bufferFormat, size_t maxInputBufferLength);
26
+ std::tuple<double, double> closeFile();
23
27
 
24
28
  bool writeAudioData(const AudioBufferList *audioBufferList, int numFrames);
25
29
 
30
+ double getCurrentDuration() const;
31
+
26
32
  private:
33
+ size_t converterInputBufferSize_;
34
+ size_t converterOutputBufferSize_;
35
+ std::atomic<size_t> framesWritten_{0};
36
+
27
37
  NSString *getISODateStringForDirectory();
28
38
  NSString *getTimestampForFilename();
29
39
  NSURL *getFileURL();
@@ -33,6 +43,9 @@ class IOSAudioFileWriter {
33
43
  AVAudioFormat *bufferFormat_;
34
44
  AVAudioConverter *converter_;
35
45
  NSURL *fileURL_;
46
+
47
+ AVAudioPCMBuffer *converterInputBuffer_;
48
+ AVAudioPCMBuffer *converterOutputBuffer_;
36
49
  };
37
50
 
38
51
  } // namespace audioapi