summaryrefslogtreecommitdiff
path: root/src/audio/jittered_audio_backend.h
blob: e0ce9d7394fedb1e70e97472ec2739182953cd1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// This file is part of the 64k demo project.
// It implements a test backend that simulates jittered audio consumption.
// Useful for stress-testing ring buffer under realistic timing conditions.

#pragma once

#if !defined(STRIP_ALL)

#include "audio_backend.h"
#include <atomic>
#include <thread>

// Simulates a real audio device with timing jitter and variable chunk sizes
class JitteredAudioBackend : public AudioBackend {
 public:
  JitteredAudioBackend();
  ~JitteredAudioBackend() override;

  void init() override;
  void start() override;
  void shutdown() override;

  // Control simulation
  void set_jitter_amount(float jitter_ms);  // Random jitter in ms (default: 5ms)
  void set_base_interval(float interval_ms);  // Base interval between reads (default: 10ms)
  void set_chunk_size_range(int min_frames, int max_frames);  // Variable chunk sizes

  // Query state
  int get_total_frames_consumed() const { return total_frames_consumed_.load(); }
  int get_underrun_count() const { return underrun_count_.load(); }
  bool is_running() const { return running_.load(); }

 private:
  void audio_thread_loop();

  std::thread audio_thread_;
  std::atomic<bool> running_;
  std::atomic<bool> should_stop_;

  // Configuration
  float jitter_ms_;
  float base_interval_ms_;
  int min_chunk_frames_;
  int max_chunk_frames_;

  // Statistics
  std::atomic<int> total_frames_consumed_;
  std::atomic<int> underrun_count_;  // How many times buffer was empty
};

#endif /* !defined(STRIP_ALL) */