rockbox_ffi 0.2.0 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78ae6470117f6b52f565285e04c0d65742da1296fc3b336ad6cf3c246266c5ee
4
- data.tar.gz: 11281048c1996c24ff83ec3ceb1f5d66c8529527f2f0f91e3498836eb4fc39ad
3
+ metadata.gz: 65435e6c7a7b4ef8e59f3bc088ce2c9eb978b34d49e134c3e42413e9790bb333
4
+ data.tar.gz: 0d14838882902eaa6818a9726518f0c782848ad34e09b6afe6ca9ddbbf6cdd1a
5
5
  SHA512:
6
- metadata.gz: dcc042306ae5c1ee6afe35a951a0f3ac2da9ad78b33605009b04f755ef23f253efb061f2ddb64afef34760b0a5642b1bc77ddbcfb95db8cc99b1d1198a41feb7
7
- data.tar.gz: 9bf8d8eacd74b7cdef21bfe8bd80f810c58ae742e752f9a12709bd9df296f8a9b502ab014b5335fec522800f6c232dedf6796f168c5a8e07a3ddbea2f36cdb96
6
+ metadata.gz: f4275075ebc6d35b7b495dfc3a081b97960f5dc81f8f279372acf5b852fc0723776f536f9f87602811499a23d1653de9a8c5b072144444fe15dd0cd4b4dc1066
7
+ data.tar.gz: 5b4a35ca244aed1f570cf2d639a131eb8244645fe4ebe86513193345a95716107c72c67f7037f195e8048bff4f885c1d3c8af1fdd218ffabcf200860b841e363
data/README.md CHANGED
@@ -10,6 +10,10 @@ via [`fiddle`](https://docs.ruby-lang.org/en/master/Fiddle.html) (Ruby stdlib)
10
10
  over the prebuilt `librockbox_ffi` shared library. No native extension is
11
11
  compiled — the gem `dlopen`s the shared library at load time.
12
12
 
13
+ > 📖 **Sound settings reference** — the equalizer, tone, crossfeed, compressor
14
+ > and other DSP controls mirror Rockbox's own. See the official
15
+ > [Rockbox manual — Sound Settings](https://download.rockbox.org/daily/manual/rockbox-ipodvideo/rockbox-buildch6.html).
16
+
13
17
  ## Setup
14
18
 
15
19
  Build the shared library once (from the repo root):
data/examples/play.rb CHANGED
@@ -13,9 +13,16 @@ FIXTURE = File.join(REPO, "crates", "rocksky", "fixtures", "08 - Internet Money
13
13
  file = ARGV[0] || FIXTURE
14
14
 
15
15
  player = RockboxFFI::Player.new(volume: 0.8)
16
- player.set_queue([file])
17
- player.play
16
+ # Mutating setters return self, so the setup reads as one fluent chain.
17
+ # DSP: Bass Boost preset + a +7 dB bass / +4 dB treble lift.
18
+ player
19
+ .set_queue([file])
20
+ .set_eq_preset(RockboxFFI::EqPreset::BASS_BOOST)
21
+ .set_bass(7)
22
+ .set_treble(4)
23
+ .play
18
24
  puts "▶ playing #{file}"
25
+ puts "eq: BassBoost preset, bass +7 dB, treble +4 dB"
19
26
 
20
27
  # Reinstall a SIGINT handler AFTER the player boots: the native audio engine
21
28
  # installs its own signal handler while starting the output device, which
@@ -18,6 +18,13 @@ module RockboxFFI
18
18
  ALBUM = 2
19
19
  end
20
20
 
21
+ # Values for Player#set_repeat / #repeat.
22
+ module RepeatMode
23
+ OFF = 0
24
+ ONE = 1
25
+ ALL = 2
26
+ end
27
+
21
28
  module CrossfadeMode
22
29
  OFF = 0
23
30
  AUTO_SKIP = 1
@@ -54,4 +61,47 @@ module RockboxFFI
54
61
  KARAOKE = 5
55
62
  SWAP = 6
56
63
  end
64
+
65
+ # Built-in EQ presets for Player#set_eq_preset.
66
+ module EqPreset
67
+ FLAT = 0
68
+ ACOUSTIC = 1
69
+ BASS_BOOST = 2
70
+ BASS_REDUCER = 3
71
+ CLASSICAL = 4
72
+ DANCE = 5
73
+ DEEP = 6
74
+ ELECTRONIC = 7
75
+ HIP_HOP = 8
76
+ JAZZ = 9
77
+ LATIN = 10
78
+ LOUDNESS = 11
79
+ LOUNGE = 12
80
+ PIANO = 13
81
+ POP = 14
82
+ RNB = 15
83
+ ROCK = 16
84
+ SMALL_SPEAKERS = 17
85
+ TREBLE_BOOST = 18
86
+ TREBLE_REDUCER = 19
87
+ VOCAL_BOOST = 20
88
+ end
89
+
90
+ # Crossfeed mode for Player#set_crossfeed.
91
+ module CrossfeedMode
92
+ OFF = 0
93
+ MEIER = 1
94
+ CUSTOM = 2
95
+ end
96
+
97
+ # Channel mode for Player#set_channel_mode.
98
+ module ChannelMode
99
+ STEREO = 0
100
+ MONO = 1
101
+ CUSTOM = 2
102
+ MONO_LEFT = 3
103
+ MONO_RIGHT = 4
104
+ KARAOKE = 5
105
+ SWAP = 6
106
+ end
57
107
  end
@@ -121,6 +121,32 @@ module RockboxFFI
121
121
  extern "float rb_player_volume(void*)"
122
122
  extern "uint32_t rb_player_sample_rate(void*)"
123
123
  extern "void* rb_player_status_json(void*)"
124
+ extern "void rb_player_set_shuffle(void*, bool)"
125
+ extern "bool rb_player_is_shuffle_enabled(void*)"
126
+ extern "void rb_player_set_repeat(void*, int32_t)"
127
+ extern "int32_t rb_player_repeat(void*)"
128
+
129
+ # ---- player DSP ---------------------------------------------------
130
+ extern "void rb_player_set_eq_enabled(void*, bool)"
131
+ extern "bool rb_player_is_eq_enabled(void*)"
132
+ extern "void rb_player_set_eq_band(void*, size_t, int32_t, float, float)"
133
+ extern "void rb_player_set_eq_precut(void*, float)"
134
+ extern "void rb_player_set_eq_preset(void*, int32_t)"
135
+ extern "void rb_player_set_tone(void*, int32_t, int32_t, int32_t, int32_t)"
136
+ extern "void rb_player_set_bass(void*, int32_t)"
137
+ extern "void rb_player_set_treble(void*, int32_t)"
138
+ extern "void rb_player_set_bass_cutoff(void*, int32_t)"
139
+ extern "void rb_player_set_treble_cutoff(void*, int32_t)"
140
+ extern "void rb_player_set_crossfeed(void*, int32_t, int32_t, int32_t, int32_t, int32_t)"
141
+ extern "void rb_player_set_bass_enhancement(void*, int32_t, int32_t)"
142
+ extern "void rb_player_set_fatigue_reduction(void*, int32_t)"
143
+ extern "void rb_player_set_surround(void*, int32_t, int32_t, int32_t, int32_t)"
144
+ extern "void rb_player_set_channel_mode(void*, int32_t)"
145
+ extern "void rb_player_set_stereo_width(void*, int32_t)"
146
+ extern "void rb_player_set_compressor(void*, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t)"
147
+ extern "void rb_player_set_dither(void*, bool)"
148
+ extern "void rb_player_set_pitch(void*, int32_t)"
149
+ extern "void* rb_player_dsp_settings_json(void*)"
124
150
 
125
151
  # ---- resume -------------------------------------------------------
126
152
  extern "void* rb_player_resume(void*)"
@@ -11,6 +11,11 @@ module RockboxFFI
11
11
  #
12
12
  # ReplayGain +mode+ here uses the *player* values: 0 off, 1 track, 2 album
13
13
  # (see ReplayGainMode) — distinct from the DSP encoding.
14
+ #
15
+ # Mutating setters (queue, transport, settings, DSP) return +self+ so calls
16
+ # can be fluently chained, e.g.
17
+ # player.set_queue([file]).set_shuffle(true).play
18
+ # Getters/queries and lifecycle methods keep their own return values.
14
19
  class Player
15
20
  DEFAULT_CONFIG = {
16
21
  sample_rate: 0, # 0 => device default
@@ -85,12 +90,18 @@ module RockboxFFI
85
90
  private_class_method :finalizer
86
91
 
87
92
  # -- queue ------------------------------------------------------------
93
+ # Replace the queue. Each entry may be a local file path, an http(s)://
94
+ # URL to a finite remote file, or a live-radio / streaming URL.
88
95
  def set_queue(paths)
89
96
  Lib.rb_player_set_queue_json(@ptr, JSON.generate(Array(paths).map(&:to_s)))
97
+ self
90
98
  end
91
99
 
100
+ # Append one track to the queue. +path+ may be a local file path, an
101
+ # http(s):// URL to a finite remote file, or a live-radio / streaming URL.
92
102
  def enqueue(path)
93
103
  Lib.rb_player_enqueue(@ptr, path.to_s)
104
+ self
94
105
  end
95
106
 
96
107
  # Insert +paths+ (a path/URL or Array of them) into the queue at
@@ -100,6 +111,7 @@ module RockboxFFI
100
111
  Lib.rb_player_insert_json(
101
112
  @ptr, JSON.generate(Array(paths).map(&:to_s)), Integer(position), Integer(index)
102
113
  )
114
+ self
103
115
  end
104
116
 
105
117
  # The current queue as an Array of String paths/URLs.
@@ -113,39 +125,48 @@ module RockboxFFI
113
125
  # -- transport --------------------------------------------------------
114
126
  def play
115
127
  Lib.rb_player_play(@ptr)
128
+ self
116
129
  end
117
130
 
118
131
  def pause
119
132
  Lib.rb_player_pause(@ptr)
133
+ self
120
134
  end
121
135
 
122
136
  def toggle
123
137
  Lib.rb_player_toggle(@ptr)
138
+ self
124
139
  end
125
140
 
126
141
  def stop
127
142
  Lib.rb_player_stop(@ptr)
143
+ self
128
144
  end
129
145
 
130
146
  def next
131
147
  Lib.rb_player_next(@ptr)
148
+ self
132
149
  end
133
150
 
134
151
  def previous
135
152
  Lib.rb_player_previous(@ptr)
153
+ self
136
154
  end
137
155
 
138
156
  def skip_to(index)
139
157
  Lib.rb_player_skip_to(@ptr, Integer(index))
158
+ self
140
159
  end
141
160
 
142
161
  def seek_ms(ms)
143
162
  Lib.rb_player_seek_ms(@ptr, Integer(ms))
163
+ self
144
164
  end
145
165
 
146
166
  # -- settings ---------------------------------------------------------
147
167
  def set_volume(vol)
148
168
  Lib.rb_player_set_volume(@ptr, Float(vol))
169
+ self
149
170
  end
150
171
 
151
172
  def volume
@@ -163,11 +184,173 @@ module RockboxFFI
163
184
  @ptr, Integer(mode), Integer(fade_out_delay_ms), Integer(fade_out_duration_ms),
164
185
  Integer(fade_in_delay_ms), Integer(fade_in_duration_ms), Integer(mix_mode)
165
186
  )
187
+ self
166
188
  end
167
189
 
168
190
  # mode: see ReplayGainMode (OFF=0, TRACK=1, ALBUM=2).
169
191
  def set_replaygain(mode, preamp_db, prevent_clipping)
170
192
  Lib.rb_player_set_replaygain(@ptr, Integer(mode), Float(preamp_db), RockboxFFI.b(prevent_clipping))
193
+ self
194
+ end
195
+
196
+ # Enable/disable shuffle.
197
+ def set_shuffle(enabled)
198
+ Lib.rb_player_set_shuffle(@ptr, RockboxFFI.b(enabled))
199
+ self
200
+ end
201
+
202
+ # Whether shuffle is currently enabled.
203
+ def shuffle_enabled?
204
+ !Lib.rb_player_is_shuffle_enabled(@ptr).zero?
205
+ end
206
+
207
+ # Set the repeat mode (see RepeatMode: OFF=0, ONE=1, ALL=2).
208
+ def set_repeat(mode)
209
+ Lib.rb_player_set_repeat(@ptr, Integer(mode))
210
+ self
211
+ end
212
+
213
+ # The current repeat mode as an Integer (see RepeatMode).
214
+ def repeat
215
+ Lib.rb_player_repeat(@ptr)
216
+ end
217
+
218
+ # -- DSP --------------------------------------------------------------
219
+ # Enable/disable the parametric equalizer.
220
+ def set_eq_enabled(enabled)
221
+ Lib.rb_player_set_eq_enabled(@ptr, RockboxFFI.b(enabled))
222
+ self
223
+ end
224
+
225
+ # Whether the parametric equalizer is currently enabled.
226
+ def eq_enabled?
227
+ !Lib.rb_player_is_eq_enabled(@ptr).zero?
228
+ end
229
+
230
+ # Configure one EQ band: +band+ index, +cutoff_hz+ center frequency,
231
+ # +q+ factor, +gain_db+ gain in dB.
232
+ def set_eq_band(band, cutoff_hz, q, gain_db)
233
+ Lib.rb_player_set_eq_band(@ptr, Integer(band), Integer(cutoff_hz), Float(q), Float(gain_db))
234
+ self
235
+ end
236
+
237
+ # Global EQ pre-cut in dB.
238
+ def set_eq_precut(db)
239
+ Lib.rb_player_set_eq_precut(@ptr, Float(db))
240
+ self
241
+ end
242
+
243
+ # Apply a built-in EQ preset (see EqPreset).
244
+ def set_eq_preset(preset)
245
+ Lib.rb_player_set_eq_preset(@ptr, Integer(preset))
246
+ self
247
+ end
248
+
249
+ # Bass/treble tone controls with explicit cutoff frequencies.
250
+ def set_tone(bass_db, treble_db, bass_cutoff_hz, treble_cutoff_hz)
251
+ Lib.rb_player_set_tone(
252
+ @ptr, Integer(bass_db), Integer(treble_db),
253
+ Integer(bass_cutoff_hz), Integer(treble_cutoff_hz)
254
+ )
255
+ self
256
+ end
257
+
258
+ # Bass gain in dB.
259
+ def set_bass(bass_db)
260
+ Lib.rb_player_set_bass(@ptr, Integer(bass_db))
261
+ self
262
+ end
263
+
264
+ # Treble gain in dB.
265
+ def set_treble(treble_db)
266
+ Lib.rb_player_set_treble(@ptr, Integer(treble_db))
267
+ self
268
+ end
269
+
270
+ # Bass tone-control cutoff frequency in Hz.
271
+ def set_bass_cutoff(hz)
272
+ Lib.rb_player_set_bass_cutoff(@ptr, Integer(hz))
273
+ self
274
+ end
275
+
276
+ # Treble tone-control cutoff frequency in Hz.
277
+ def set_treble_cutoff(hz)
278
+ Lib.rb_player_set_treble_cutoff(@ptr, Integer(hz))
279
+ self
280
+ end
281
+
282
+ # Crossfeed for headphone listening. +mode+ (see CrossfeedMode: OFF=0,
283
+ # MEIER=1, CUSTOM=2), plus direct/cross/high-frequency gains and the
284
+ # high-frequency cutoff (Hz) used in CUSTOM mode.
285
+ def set_crossfeed(mode, direct_gain, cross_gain, hf_gain, hf_cutoff)
286
+ Lib.rb_player_set_crossfeed(
287
+ @ptr, Integer(mode), Integer(direct_gain), Integer(cross_gain),
288
+ Integer(hf_gain), Integer(hf_cutoff)
289
+ )
290
+ self
291
+ end
292
+
293
+ # Bass enhancement: +strength+ and +precut+ (in dB).
294
+ def set_bass_enhancement(strength, precut)
295
+ Lib.rb_player_set_bass_enhancement(@ptr, Integer(strength), Integer(precut))
296
+ self
297
+ end
298
+
299
+ # Listening-fatigue reduction (treble roll-off): +strength+.
300
+ def set_fatigue_reduction(strength)
301
+ Lib.rb_player_set_fatigue_reduction(@ptr, Integer(strength))
302
+ self
303
+ end
304
+
305
+ # Surround effect: delay (ms), balance, low/high cutoff frequencies (Hz).
306
+ def set_surround(delay_ms, balance, cutoff_low_hz, cutoff_high_hz)
307
+ Lib.rb_player_set_surround(
308
+ @ptr, Integer(delay_ms), Integer(balance),
309
+ Integer(cutoff_low_hz), Integer(cutoff_high_hz)
310
+ )
311
+ self
312
+ end
313
+
314
+ # Channel mode (see ChannelMode).
315
+ def set_channel_mode(mode)
316
+ Lib.rb_player_set_channel_mode(@ptr, Integer(mode))
317
+ self
318
+ end
319
+
320
+ # Stereo width as a percentage.
321
+ def set_stereo_width(percent)
322
+ Lib.rb_player_set_stereo_width(@ptr, Integer(percent))
323
+ self
324
+ end
325
+
326
+ # Dynamic-range compressor: threshold (dB), makeup gain, ratio, knee,
327
+ # attack (ms), release (ms).
328
+ def set_compressor(threshold_db, makeup_gain, ratio, knee, attack_ms, release_ms)
329
+ Lib.rb_player_set_compressor(
330
+ @ptr, Integer(threshold_db), Integer(makeup_gain), Integer(ratio),
331
+ Integer(knee), Integer(attack_ms), Integer(release_ms)
332
+ )
333
+ self
334
+ end
335
+
336
+ # Enable/disable output dithering.
337
+ def set_dither(enabled)
338
+ Lib.rb_player_set_dither(@ptr, RockboxFFI.b(enabled))
339
+ self
340
+ end
341
+
342
+ # Pitch shift ratio.
343
+ def set_pitch(ratio)
344
+ Lib.rb_player_set_pitch(@ptr, Integer(ratio))
345
+ self
346
+ end
347
+
348
+ # A snapshot of the current DSP settings as a Hash with symbol keys.
349
+ def dsp_settings
350
+ s = RockboxFFI.take_string(Lib.rb_player_dsp_settings_json(@ptr))
351
+ raise "rb_player_dsp_settings_json returned NULL" if s.nil?
352
+
353
+ JSON.parse(s, symbolize_names: true)
171
354
  end
172
355
 
173
356
  # -- status -----------------------------------------------------------
@@ -1,3 +1,3 @@
1
1
  module RockboxFFI
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rockbox_ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsiry Sandratraina