SID Player
All Classes Functions Pages
SIDPlayer.h
1 #pragma once
2 #include "AudioTools.h"
3 #include "SIDAudioSource.h"
4 #include "SIDStream.h"
5 #include "SIDConfig.h"
6 
7 namespace audio_tools {
8 
16 class SIDPlayer : public AudioInfoSupport {
17 public:
18  SIDPlayer(AudioSource &source, AudioOutput &output, SizeSource &sizeSource) {
19  static CodecNOP nop;
20  p_size_source = &sizeSource;
21  player.setAudioSource(source);
22  player.setOutput(output);
23  p_info = &output;
24  p_out = &output;
25  }
26 
27  SIDPlayer(AudioSource &source, AudioStream &output, SizeSource &sizeSource) {
28  static CodecNOP nop;
29  p_size_source = &sizeSource;
30  player.setAudioSource(source);
31  player.setOutput(output);
32  p_info = &output;
33  p_out = &output;
34  }
35 
37  bool begin(int index = 0, bool isActive = true) {
38  TRACEI();
39  // get update audio info from destination
40  setAudioInfo(p_info->audioInfo());
41  info.logInfo();
42  player.setAudioInfo(info);
43  // setup sid stream
44  auto cfg = sid.defaultConfig();
45  cfg.copyFrom(info);
46  sid.begin(cfg);
47 
48  // make sure we have valid audio data
49  assert(cfg.channels>0);
50  assert(cfg.sample_rate>0);
51  assert(cfg.bits_per_sample==16);
52 
53  // setup player
54  player.setAutoNext(false);
55  bool result = player.begin(index, isActive);
56 
57  return result;
58  }
60  void end() {
61  player.end();
62  sid.end();
63  }
64 
66  void setAudioInfo(AudioInfo info) override {
67  TRACED();
68  this->info = info;
69  };
70 
71  AudioInfo audioInfo() override { return info; }
72 
74  void play() { player.play(); }
75 
77  void stop() { player.stop(); }
78 
80  bool previous(int offset = 1) {
81  state = Initial;
82  return player.previous(offset);
83  }
84 
87  bool next(int offset = 1) {
88  state = Initial;
89  return player.next(offset);
90  }
91 
93  bool nextTune(int offset = 1) {
94  int tune =sid.getStreamConfigdata().subtune;
95  tune = (++tune) % sid.getMetadata().total_tunes;
96  sid.setTune(tune);
97  return true;
98  }
99 
101  bool setIndex(int idx) {
102  state = Initial;
103  return player.setIndex(idx);
104  }
105 
107  bool setPath(const char *path) {
108  state = Initial;
109  return player.setPath(path);
110  }
111 
113  Stream *getStream() { return player.getStream(); }
114 
116  bool isActive() { return player.isActive(); }
117 
119  operator bool() { return isActive(); }
120 
122  void setActive(bool isActive) { player.setActive(isActive); }
123 
125  void setVolume(float volume) { player.setVolume(volume); }
126 
128  float volume() { return player.volume(); }
129 
132  void setSilenceOnInactive(bool active) {
133  player.setSilenceOnInactive(active);
134  }
135 
137  bool isSilenceOnInactive() { return player.isSilenceOnInactive(); }
138 
141  void setTimeout(size_t timeout) { timeout_sec = timeout; }
142 
144  void copy() {
145  TRACED();
146  if (!isActive()) {
147  if (isSilenceOnInactive()) {
148  player.writeSilence(DEFAULT_BUFFER_SIZE);
149  }
150  return;
151  }
152 
153  if (state == Initial) {
154  loadSID();
156  setSIDAsInput();
157 
158  } else {
159  // play sid file
160  player.copy();
161  // We can set a timeout for each song
162  if (isPlayingTimedOut()) {
163  moveNextOnEnd();
164  }
165  }
166  }
167 
168 protected:
169  AudioPlayer player;
170  SIDStream sid;
171  Print *p_out;
172  AudioInfoSupport *p_info;
173  AudioInfo info;
174  Vector<uint8_t> sid_data{0};
175  SizeSource *p_size_source = nullptr;
176  enum proces_state_enum { Initial, Playing };
177  proces_state_enum state = Initial;
178  size_t timeout_sec = 0;
179  size_t playing_timout_ms = 0;
180 
181  Print *getOutput() { return player.getVolumeOutput(); }
182 
183  void loadSID() {
184  TRACEI();
185  Stream *p_stream = getStream();
186  // allocate memory
187  int size = p_size_source->size();
188  sid_data.resize(size);
189  p_stream->readBytes(sid_data.data(), size);
190  LOGI("setSID size: %d", size);
191  if (size<MAX_FILE_SIZE){
192  sid.setSID(sid_data.data(), size, 0);
193  state = Playing;
194  } else {
195  LOGE("Song is too big!");
196  next(1);
197  }
198 
199  if (MEMORY_ALLOCATION_LOGIC!=4){
200  // release memory again
201  sid_data.resize(0);
202  }
203  }
204 
207  if (timeout_sec > 0) {
208  playing_timout_ms = millis() + (timeout_sec * 1000);
209  }
210  }
211 
214  return (playing_timout_ms == 0) ? false : millis() > playing_timout_ms;
215  }
216 
217  void moveNextOnEnd() {
218  TRACEI();
219  // move to next play
220  next(1);
221  }
222 
225  StreamCopy *p_copy = &player.getStreamCopy();
226  p_copy->begin(*getOutput(), sid);
227  player.setActive(true);
228  }
229 };
230 
231 } // namespace audio_tools
SID player which is based on the AudioPlayer from the AudioTools project and the SidPlayer provided b...
Definition: SIDPlayer.h:16
void setVolume(float volume)
sets the volume - values need to be between 0.0 and 1.0
Definition: SIDPlayer.h:125
void setSIDAsInput()
Make sure that we copy the data from the sid stream to the output.
Definition: SIDPlayer.h:224
float volume()
Determines the actual volume.
Definition: SIDPlayer.h:128
bool isPlayingTimedOut()
checks if the song has expired
Definition: SIDPlayer.h:213
Stream * getStream()
Provides the actual stream (=e.g.file)
Definition: SIDPlayer.h:113
void end()
Ends the processing.
Definition: SIDPlayer.h:60
void copy()
Call this method in the loop.
Definition: SIDPlayer.h:144
void setActive(bool isActive)
The same like start() / stop()
Definition: SIDPlayer.h:122
void stop()
halts the playing
Definition: SIDPlayer.h:77
void play()
starts / resumes the playing of a matching song
Definition: SIDPlayer.h:74
bool next(int offset=1)
Definition: SIDPlayer.h:87
bool previous(int offset=1)
moves to previous file
Definition: SIDPlayer.h:80
bool isSilenceOnInactive()
Checks if silence_on_inactive has been activated (default false)
Definition: SIDPlayer.h:137
void setTimeout(size_t timeout)
Definition: SIDPlayer.h:141
bool setIndex(int idx)
moves to selected file
Definition: SIDPlayer.h:101
void setSilenceOnInactive(bool active)
Definition: SIDPlayer.h:132
void setIsPlayingTimeout()
calculates when the song expires
Definition: SIDPlayer.h:206
bool setPath(const char *path)
moves to selected file
Definition: SIDPlayer.h:107
bool begin(int index=0, bool isActive=true)
(Re)Starts the playing of the music (from the beginning)
Definition: SIDPlayer.h:37
void setAudioInfo(AudioInfo info) override
Updates the audio info in the related objects.
Definition: SIDPlayer.h:66
bool isActive()
determines if the player is active
Definition: SIDPlayer.h:116
bool nextTune(int offset=1)
moves to next tune
Definition: SIDPlayer.h:93
Provides SID audio data.
Definition: SIDStream.h:59
void setSID(const unsigned char *tunedata, int tunedatalen, int subtune=0)
Loads the tune to be played and starts generating audio.
Definition: SIDStream.h:128
SIDMetadata getMetadata()
Provide the metadata for the sid.
Definition: SIDStream.h:186
void end() override
Stops processing and releases the memory.
Definition: SIDStream.h:118
SIDStreamConfig defaultConfig()
Provides the default configuration.
Definition: SIDStream.h:81
Logic to determine the Size of the Stream: File ?
Definition: SIDAudioSource.h:106