diff options
Diffstat (limited to 'firmware/replaygain.c')
-rw-r--r-- | firmware/replaygain.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/firmware/replaygain.c b/firmware/replaygain.c index 23a25cc310..542eee6101 100644 --- a/firmware/replaygain.c +++ b/firmware/replaygain.c | |||
@@ -20,9 +20,12 @@ | |||
20 | #include <ctype.h> | 20 | #include <ctype.h> |
21 | #include <inttypes.h> | 21 | #include <inttypes.h> |
22 | #include <math.h> | 22 | #include <math.h> |
23 | #include <stdbool.h> | ||
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | #include <stdlib.h> | 25 | #include <stdlib.h> |
25 | #include <stdbool.h> | 26 | #include <string.h> |
27 | #include <system.h> | ||
28 | #include "id3.h" | ||
26 | #include "debug.h" | 29 | #include "debug.h" |
27 | 30 | ||
28 | /* The fixed point math routines (with the exception of fp_atof) are based | 31 | /* The fixed point math routines (with the exception of fp_atof) are based |
@@ -326,3 +329,106 @@ long get_replaypeak(const char* str) | |||
326 | 329 | ||
327 | return peak; | 330 | return peak; |
328 | } | 331 | } |
332 | |||
333 | /* Compare two strings, ignoring case, up to the end nil or another end of | ||
334 | * string character. E.g., if eos is '=', "a=" would equal "a". Returns | ||
335 | * true for a match, false otherwise. | ||
336 | * TODO: This should be placed somewhere else, as it could be useful in | ||
337 | * other places too. | ||
338 | */ | ||
339 | static bool str_equal(const char* s1, const char* s2, char eos) | ||
340 | { | ||
341 | char c1 = 0; | ||
342 | char c2 = 0; | ||
343 | |||
344 | while (*s1 && *s2 && (*s1 != eos) && (*s2 != eos)) | ||
345 | { | ||
346 | if ((c1 = toupper(*s1)) != (c2 = toupper(*s2))) | ||
347 | { | ||
348 | return false; | ||
349 | } | ||
350 | |||
351 | s1++; | ||
352 | s2++; | ||
353 | } | ||
354 | |||
355 | if (c1 == eos) | ||
356 | { | ||
357 | c1 = '\0'; | ||
358 | } | ||
359 | |||
360 | if (c2 == eos) | ||
361 | { | ||
362 | c2 = '\0'; | ||
363 | } | ||
364 | |||
365 | return c1 == c2; | ||
366 | } | ||
367 | |||
368 | /* Check for a ReplayGain tag conforming to the "VorbisGain standard". If | ||
369 | * found, set the mp3entry accordingly. If value is NULL, key is expected | ||
370 | * to be on the "key=value" format, and the comparion/extraction is done | ||
371 | * accordingly. buffer is where to store the text contents of the gain tags; | ||
372 | * up to length bytes (including end nil) can be written. | ||
373 | * Returns number of bytes written to the tag text buffer, or zero if | ||
374 | * no ReplayGain tag was found (or nothing was copied to the buffer for | ||
375 | * other reasons). | ||
376 | */ | ||
377 | long parse_replaygain(const char* key, const char* value, | ||
378 | struct mp3entry* entry, char* buffer, int length) | ||
379 | { | ||
380 | const char* val = value; | ||
381 | char **p = NULL; | ||
382 | char eos = '\0'; | ||
383 | |||
384 | if (!val) | ||
385 | { | ||
386 | if (!(val = strchr(key, '='))) | ||
387 | { | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | val++; | ||
392 | eos = '='; | ||
393 | } | ||
394 | |||
395 | if (str_equal(key, "replaygain_track_gain", eos) | ||
396 | || (str_equal(key, "rg_radio", eos) && !entry->track_gain)) | ||
397 | { | ||
398 | entry->track_gain = get_replaygain(val); | ||
399 | p = &(entry->track_gain_string); | ||
400 | } | ||
401 | else if (str_equal(key, "replaygain_album_gain", eos) | ||
402 | || (str_equal(key, "rg_audiophile", eos) && !entry->album_gain)) | ||
403 | { | ||
404 | entry->album_gain = get_replaygain(val); | ||
405 | p = &(entry->album_gain_string); | ||
406 | } | ||
407 | else if (str_equal(key, "replaygain_track_peak", eos) | ||
408 | || (str_equal(key, "rg_peak", eos) && !entry->track_peak)) | ||
409 | { | ||
410 | entry->track_peak = get_replaypeak(val); | ||
411 | } | ||
412 | else if (str_equal(key, "replaygain_album_peak", eos)) | ||
413 | { | ||
414 | entry->album_peak = get_replaypeak(val); | ||
415 | } | ||
416 | |||
417 | if (p) | ||
418 | { | ||
419 | int len = strlen(val); | ||
420 | |||
421 | len = MIN(len, length - 1); | ||
422 | |||
423 | /* A few characters just isn't interesting... */ | ||
424 | if (len > 1) | ||
425 | { | ||
426 | strncpy(buffer, val, len); | ||
427 | buffer[len] = 0; | ||
428 | *p = buffer; | ||
429 | return len + 1; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | return 0; | ||
434 | } | ||