A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 654 lines 18 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2005 by Linus Nielsen Feltzing 11 * Copyright (C) 2007 by Christian Gmeiner 12 * Copyright (C) 2013 by Michael Sevakis 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License 16 * as published by the Free Software Foundation; either version 2 17 * of the License, or (at your option) any later version. 18 * 19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 * KIND, either express or implied. 21 * 22 ****************************************************************************/ 23 /* Indicate it's the sound.c file which affects compilation of audiohw.h */ 24#define AUDIOHW_IS_SOUND_C 25#include "config.h" 26#include "system.h" 27#include "sound.h" 28 29#ifndef BOOTLOADER 30#include "settings.h" /* sound_current */ 31#endif 32 33#ifdef HAVE_SW_VOLUME_CONTROL 34#include "pcm_sw_volume.h" 35#endif /* HAVE_SW_VOLUME_CONTROL */ 36 37/* Define sound_setting_entries table */ 38#define AUDIOHW_SOUND_SETTINGS_ENTRIES 39#include "audiohw_settings.h" 40 41/* Implements sound_val2phys */ 42#define AUDIOHW_SOUND_SETTINGS_VAL2PHYS 43#include "audiohw_settings.h" 44 45/* Returns current sound settings from global_settings */ 46#define SOUND_CUR_SET(name, var) \ 47 case SOUND_##name: return var; 48 49extern bool audio_is_initialized; 50 51static const struct sound_setting_entry * get_setting_entry(int setting) 52{ 53 static const struct sound_settings_info default_info = 54 { "", 0, 0, 0, 0, 0 }; 55 56 static const struct sound_setting_entry default_entry = 57 { &default_info, NULL }; 58 59 if ((unsigned)setting >= ARRAYLEN(sound_setting_entries)) 60 return &default_entry; 61 62 const struct sound_setting_entry *e = &sound_setting_entries[setting]; 63 return e->info ? e : &default_entry; /* setting valid but not in table? */ 64} 65 66static const struct sound_settings_info * get_settings_info(int setting) 67{ 68 return get_setting_entry(setting)->info; 69} 70 71const char * sound_unit(int setting) 72{ 73 return get_settings_info(setting)->unit; 74} 75 76int sound_numdecimals(int setting) 77{ 78 return get_settings_info(setting)->numdecimals; 79} 80 81int sound_steps(int setting) 82{ 83 return get_settings_info(setting)->steps; 84} 85 86int sound_min(int setting) 87{ 88 return get_settings_info(setting)->minval; 89} 90 91int sound_max(int setting) 92{ 93 return get_settings_info(setting)->maxval; 94} 95 96int sound_default(int setting) 97{ 98 return get_settings_info(setting)->defaultval; 99} 100 101sound_set_type * sound_get_fn(int setting) 102{ 103 return get_setting_entry(setting)->function; 104} 105 106void sound_set(int setting, int value) 107{ 108 sound_set_type *sound_set_val = sound_get_fn(setting); 109 110 if (sound_set_val) 111 sound_set_val(value); 112} 113 114int sound_current(int setting) 115{ 116 switch(setting) 117 { 118#ifndef BOOTLOADER 119#ifndef PLATFORM_HAS_VOLUME_CHANGE 120 SOUND_CUR_SET(VOLUME, global_status.volume) 121#endif 122#if defined(AUDIOHW_HAVE_BASS) 123 SOUND_CUR_SET(BASS, global_settings.bass) 124#endif 125#if defined(AUDIOHW_HAVE_TREBLE) 126 SOUND_CUR_SET(TREBLE, global_settings.treble) 127#endif 128 SOUND_CUR_SET(BALANCE, global_settings.balance) 129 SOUND_CUR_SET(CHANNELS, global_settings.channel_config) 130 SOUND_CUR_SET(STEREO_WIDTH, global_settings.stereo_width) 131#if defined(AUDIOHW_HAVE_BASS_CUTOFF) 132 SOUND_CUR_SET(BASS_CUTOFF, global_settings.bass_cutoff) 133#endif 134#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 135 SOUND_CUR_SET(TREBLE_CUTOFF, global_settings.treble_cutoff) 136#endif 137#if defined(AUDIOHW_HAVE_DEPTH_3D) 138 SOUND_CUR_SET(DEPTH_3D, global_settings.depth_3d) 139#endif 140#if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF) 141 SOUND_CUR_SET(FILTER_ROLL_OFF, global_settings.roll_off) 142#endif 143#if defined(AUDIOHW_HAVE_POWER_MODE) 144 SOUND_CUR_SET(POWER_MODE, global_settings.power_mode) 145#endif 146 147#if 0 /*WRONG -- these need to index the hw_eq_bands[AUDIOHW_EQ_BAND_NUM] struct*/ 148/* Hardware EQ tone controls */ 149#if defined(AUDIOHW_HAVE_EQ) 150 SOUND_CUR_SET(EQ_BAND1_GAIN, global_settings.hw_eq_band1_gain) 151#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) 152 SOUND_CUR_SET(EQ_BAND1_FREQUENCY, global_settings.hw_eq_band1_frequency) 153#endif 154#if defined(AUDIOHW_HAVE_EQ_BAND2) 155 SOUND_CUR_SET(EQ_BAND2_GAIN, global_settings.hw_eq_band2_gain) 156#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) 157 SOUND_CUR_SET(EQ_BAND2_FREQUENCY, global_settings.hw_eq_band2_frequency) 158#endif 159#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) 160 SOUND_CUR_SET(EQ_BAND2_WIDTH, global_settings.hw_eq_band2_width) 161#endif 162#endif /* AUDIOHW_HAVE_EQ_BAND2 */ 163#if defined(AUDIOHW_HAVE_EQ_BAND3) 164 SOUND_CUR_SET(EQ_BAND3_GAIN, global_settings.hw_eq_band3_gain) 165#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) 166 SOUND_CUR_SET(EQ_BAND3_FREQUENCY, global_settings.hw_eq_band3_frequency) 167#endif 168#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) 169 SOUND_CUR_SET(EQ_BAND3_WIDTH, global_settings.hw_eq_band3_width) 170#endif 171#endif /* AUDIOHW_HAVE_EQ_BAND3 */ 172#if defined(AUDIOHW_HAVE_EQ_BAND4) 173 SOUND_CUR_SET(EQ_BAND4_GAIN, global_settings.hw_eq_band4_gain) 174#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) 175 SOUND_CUR_SET(EQ_BAND4_FREQUENCY, global_settings.hw_eq_band4_frequency) 176#endif 177#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) 178 SOUND_CUR_SET(EQ_BAND4_WIDTH, global_settings.hw_eq_band4_width) 179#endif 180#endif /* AUDIOHW_HAVE_EQ_BAND4 */ 181#if defined(AUDIOHW_HAVE_EQ_BAND5) 182 SOUND_CUR_SET(EQ_BAND5_GAIN, global_settings.hw_eq_band5_gain) 183#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) 184 SOUND_CUR_SET(EQ_BAND5_FREQUENCY, global_settings.hw_eq_band5_frequency) 185#endif 186 187#endif /* AUDIOHW_HAVE_EQ_BAND5 */ 188#endif /* AUDIOHW_HAVE_EQ */ 189#endif /*IF 0*/ 190 191#endif /*ndef BOOTLOADER*/ 192#ifdef INT_MIN 193 default: 194 return INT_MIN; 195#else 196 default: 197 return -32768; 198#endif 199 200 201 } /* switch(setting) */ 202}/* sound_current */ 203 204#if !defined(AUDIOHW_HAVE_CLIPPING) 205/* 206 * The prescaler compensates for any kind of boosts, to prevent clipping. 207 * 208 * It's basically just a measure to make sure that audio does not clip during 209 * tone controls processing, like if i want to boost bass 12 dB, i can decrease 210 * the audio amplitude by -12 dB before processing, then increase master gain 211 * by 12 dB after processing. 212 */ 213 214/* Return the sound value scaled to centibels (tenth-decibels) */ 215static int sound_value_to_cb(int setting, int value) 216{ 217 int shift = 1 - sound_numdecimals(setting); 218 if (shift < 0) do { value /= 10; } while (++shift); 219 if (shift > 0) do { value *= 10; } while (--shift); 220 return value; 221} 222 223static struct 224{ 225 int volume; /* tenth dB */ 226 int balance; /* percent */ 227#if defined(AUDIOHW_HAVE_BASS) 228 int bass; /* tenth dB */ 229#endif 230#if defined(AUDIOHW_HAVE_TREBLE) 231 int treble; /* tenth dB */ 232#endif 233#if defined(AUDIOHW_HAVE_EQ) 234 int eq_gain[AUDIOHW_EQ_BAND_NUM]; /* tenth dB */ 235#endif 236} sound_prescaler; 237 238#if defined(AUDIOHW_HAVE_BASS) || defined (AUDIOHW_HAVE_TREBLE) \ 239 || defined(AUDIOHW_HAVE_EQ) 240#define TONE_PRESCALER 241#endif 242 243static void set_prescaled_volume(void) 244{ 245#if defined(TONE_PRESCALER) || !defined(AUDIOHW_HAVE_MONO_VOLUME) 246 const int minvol = sound_value_to_cb(SOUND_VOLUME, sound_min(SOUND_VOLUME)); 247#endif 248 int volume = sound_prescaler.volume; 249 250#if defined(TONE_PRESCALER) 251 int prescale = 0; 252 253 /* Note: Having Tone + EQ isn't prohibited */ 254#if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE) 255 prescale = MAX(sound_prescaler.bass, sound_prescaler.treble); 256#endif 257 258#if defined(AUDIOHW_HAVE_EQ) 259 for (int i = 0; i < AUDIOHW_EQ_BAND_NUM; i++) 260 prescale = MAX(sound_prescaler.eq_gain[i], prescale); 261#endif 262 263 if (prescale < 0) 264 prescale = 0; /* no need to prescale if we don't boost 265 bass, treble or eq band */ 266 267 /* Gain up the analog volume to compensate the prescale gain reduction, 268 * but if this would push the volume over the top, reduce prescaling 269 * instead (might cause clipping). */ 270 const int maxvol = sound_value_to_cb(SOUND_VOLUME, sound_max(SOUND_VOLUME)); 271 272 if (volume + prescale > maxvol) 273 prescale = maxvol - volume; 274 275 audiohw_set_prescaler(prescale); 276 277 if (volume <= minvol) 278 prescale = 0; /* Make sure the audio gets muted */ 279 280#ifndef AUDIOHW_HAVE_MONO_VOLUME 281 /* At the moment, such targets have lousy volume resolution and so minute 282 boost won't work how we'd like */ 283 volume += prescale; 284#endif 285#endif /* TONE_PRESCALER */ 286 287#if defined(AUDIOHW_HAVE_MONO_VOLUME) 288 audiohw_set_volume(volume); 289#else /* Stereo volume */ 290 int l = volume, r = volume; 291 292 /* Balance the channels scaled by the current volume and min volume */ 293 int balance = sound_prescaler.balance; /* percent */ 294 295 if (balance > 0) 296 { 297 l -= (l - minvol) * balance / 100; 298 } 299 else if (balance < 0) 300 { 301 r += (r - minvol) * balance / 100; 302 } 303 304 audiohw_set_volume(l, r); 305#endif /* AUDIOHW_HAVE_MONO_VOLUME */ 306 307#if defined(AUDIOHW_HAVE_LINEOUT) 308 /* For now, lineout stays at unity */ 309 audiohw_set_lineout_volume(0, 0); 310#endif /* AUDIOHW_HAVE_LINEOUT */ 311} 312#endif /* AUDIOIHW_HAVE_CLIPPING */ 313 314void sound_set_volume(int value) 315{ 316 if (!audio_is_initialized) 317 return; 318 319#ifndef BOOTLOADER 320 global_status.volume = value; 321#endif 322 323#if defined(AUDIOHW_HAVE_CLIPPING) 324 audiohw_set_volume(value); 325#else 326 sound_prescaler.volume = sound_value_to_cb(SOUND_VOLUME, value); 327 set_prescaled_volume(); 328#endif 329} 330 331void sound_set_balance(int value) 332{ 333 if (!audio_is_initialized) 334 return; 335 336#if defined(AUDIOHW_HAVE_BALANCE) 337 audiohw_set_balance(value); 338#else 339 sound_prescaler.balance = value; 340 set_prescaled_volume(); 341#endif 342} 343 344#if defined(AUDIOHW_HAVE_BASS) 345void sound_set_bass(int value) 346{ 347 if (!audio_is_initialized) 348 return; 349 350 audiohw_set_bass(value); 351 352#if !defined(AUDIOHW_HAVE_CLIPPING) 353 sound_prescaler.bass = sound_value_to_cb(SOUND_BASS, value); 354 set_prescaled_volume(); 355#endif 356} 357#endif /* AUDIOHW_HAVE_BASS */ 358 359#if defined(AUDIOHW_HAVE_TREBLE) 360void sound_set_treble(int value) 361{ 362 if (!audio_is_initialized) 363 return; 364 365 audiohw_set_treble(value); 366 367#if !defined(AUDIOHW_HAVE_CLIPPING) 368 sound_prescaler.treble = sound_value_to_cb(SOUND_TREBLE, value); 369 set_prescaled_volume(); 370#endif 371} 372#endif /* AUDIOHW_HAVE_TREBLE */ 373 374#if defined(AUDIOHW_HAVE_BASS_CUTOFF) 375void sound_set_bass_cutoff(int value) 376{ 377 if (!audio_is_initialized) 378 return; 379 380 audiohw_set_bass_cutoff(value); 381} 382#endif /* AUDIOHW_HAVE_BASS_CUTOFF */ 383 384#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF) 385void sound_set_treble_cutoff(int value) 386{ 387 if (!audio_is_initialized) 388 return; 389 390 audiohw_set_treble_cutoff(value); 391} 392#endif /* AUDIOHW_HAVE_TREBLE_CUTOFF */ 393 394void sound_set_channels(int value) 395{ 396 if (!audio_is_initialized) 397 return; 398 399 audiohw_set_channel(value); 400} 401 402void sound_set_stereo_width(int value) 403{ 404 if (!audio_is_initialized) 405 return; 406 407 audiohw_set_stereo_width(value); 408} 409 410#if defined(AUDIOHW_HAVE_DEPTH_3D) 411void sound_set_depth_3d(int value) 412{ 413 if (!audio_is_initialized) 414 return; 415 416 audiohw_set_depth_3d(value); 417} 418#endif /* AUDIOHW_HAVE_DEPTH_3D */ 419 420#if defined(AUDIOHW_HAVE_FILTER_ROLL_OFF) 421void sound_set_filter_roll_off(int value) 422{ 423 if (!audio_is_initialized) 424 return; 425 426 audiohw_set_filter_roll_off(value); 427} 428#endif 429 430#if defined(AUDIOHW_HAVE_POWER_MODE) 431void sound_set_power_mode(int value) 432{ 433 if (!audio_is_initialized) 434 return; 435 436 audiohw_set_power_mode(value); 437} 438#endif 439 440#if defined(AUDIOHW_HAVE_EQ) 441int sound_enum_hw_eq_band_setting(unsigned int band, 442 unsigned int band_setting) 443{ 444 static const int8_t 445 sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] = 446 { 447 [AUDIOHW_EQ_GAIN] = 448 { 449 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, 450 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN, 451 #ifdef AUDIOHW_HAVE_EQ_BAND2 452 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN, 453 #endif 454 #ifdef AUDIOHW_HAVE_EQ_BAND3 455 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN, 456 #endif 457 #ifdef AUDIOHW_HAVE_EQ_BAND4 458 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN, 459 #endif 460 #ifdef AUDIOHW_HAVE_EQ_BAND5 461 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN, 462 #endif 463 }, 464#ifdef AUDIOHW_HAVE_EQ_FREQUENCY 465 [AUDIOHW_EQ_FREQUENCY] = 466 { 467 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, 468 #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY 469 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY, 470 #endif 471 #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY 472 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY, 473 #endif 474 #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY 475 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY, 476 #endif 477 #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY 478 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY, 479 #endif 480 #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY 481 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY, 482 #endif 483 }, 484#endif /* AUDIOHW_HAVE_EQ_FREQUENCY */ 485#ifdef AUDIOHW_HAVE_EQ_WIDTH 486 [AUDIOHW_EQ_WIDTH] = 487 { 488 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1, 489 #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH 490 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH, 491 #endif 492 #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH 493 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH, 494 #endif 495 #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH 496 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH, 497 #endif 498 }, 499#endif /* AUDIOHW_HAVE_EQ_WIDTH */ 500 }; 501 502 if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM) 503 return sound_hw_eq_band_setting[band_setting][band]; 504 505 return -1; 506} 507 508static void sound_set_hw_eq_band_gain(unsigned int band, int value) 509{ 510 if (!audio_is_initialized) 511 return; 512 513 audiohw_set_eq_band_gain(band, value); 514 515#if !defined (AUDIOHW_HAVE_CLIPPING) 516 int setting = sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN); 517 sound_prescaler.eq_gain[band] = sound_value_to_cb(setting, value); 518 set_prescaled_volume(); 519#endif /* AUDIOHW_HAVE_CLIPPING */ 520} 521 522void sound_set_hw_eq_band1_gain(int value) 523{ 524 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value); 525} 526 527#if defined(AUDIOHW_HAVE_EQ_BAND2) 528void sound_set_hw_eq_band2_gain(int value) 529{ 530 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value); 531} 532#endif 533 534#if defined(AUDIOHW_HAVE_EQ_BAND3) 535void sound_set_hw_eq_band3_gain(int value) 536{ 537 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value); 538} 539#endif 540 541#if defined(AUDIOHW_HAVE_EQ_BAND4) 542void sound_set_hw_eq_band4_gain(int value) 543{ 544 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value); 545} 546#endif 547 548#if defined(AUDIOHW_HAVE_EQ_BAND5) 549void sound_set_hw_eq_band5_gain(int value) 550{ 551 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value); 552} 553#endif 554 555#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY) 556void sound_set_hw_eq_band1_frequency(int value) 557{ 558 if (!audio_is_initialized) 559 return; 560 561 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value); 562} 563#endif 564 565#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY) 566void sound_set_hw_eq_band2_frequency(int value) 567{ 568 if (!audio_is_initialized) 569 return; 570 571 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value); 572} 573#endif 574 575#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY) 576void sound_set_hw_eq_band3_frequency(int value) 577{ 578 if (!audio_is_initialized) 579 return; 580 581 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value); 582} 583#endif 584 585#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY) 586void sound_set_hw_eq_band4_frequency(int value) 587{ 588 if (!audio_is_initialized) 589 return; 590 591 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value); 592} 593#endif 594 595#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY) 596void sound_set_hw_eq_band5_frequency(int value) 597{ 598 if (!audio_is_initialized) 599 return; 600 601 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value); 602} 603#endif 604 605#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH) 606void sound_set_hw_eq_band2_width(int value) 607{ 608 if (!audio_is_initialized) 609 return; 610 611 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value); 612} 613#endif 614 615#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH) 616void sound_set_hw_eq_band3_width(int value) 617{ 618 if (!audio_is_initialized) 619 return; 620 621 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value); 622} 623#endif 624 625#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH) 626void sound_set_hw_eq_band4_width(int value) 627{ 628 if (!audio_is_initialized) 629 return; 630 631 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value); 632} 633#endif 634#endif /* AUDIOHW_HAVE_EQ */ 635 636#if defined(HAVE_PITCHCONTROL) 637void sound_set_pitch(int32_t pitch) 638{ 639 if (!audio_is_initialized) 640 return; 641 642 audiohw_set_pitch(pitch); 643 /* filter out invalid by grabbing the value actually set */ 644 global_status.resume_pitch = audiohw_get_pitch(); 645} 646 647int32_t sound_get_pitch(void) 648{ 649 if (!audio_is_initialized) 650 return PITCH_SPEED_100; 651 652 return audiohw_get_pitch(); 653} 654#endif /* HAVE_PITCHCONTROL */