| 511 | } |
| 512 | |
| 513 | Result csndPlaySound(int chn, u32 flags, u32 sampleRate, float vol, float pan, void* data0, void* data1, u32 size) |
| 514 | { |
| 515 | if (!(csndChannels & BIT(chn))) |
| 516 | return 1; |
| 517 | |
| 518 | u32 paddr0 = 0, paddr1 = 0; |
| 519 | |
| 520 | int encoding = (flags >> 12) & 3; |
| 521 | int loopMode = (flags >> 10) & 3; |
| 522 | |
| 523 | if (!loopMode) flags |= SOUND_ONE_SHOT; |
| 524 | |
| 525 | if (encoding != CSND_ENCODING_PSG) |
| 526 | { |
| 527 | if (data0) paddr0 = osConvertVirtToPhys(data0); |
| 528 | if (data1) paddr1 = osConvertVirtToPhys(data1); |
| 529 | |
| 530 | if (data0 && encoding == CSND_ENCODING_ADPCM) |
| 531 | { |
| 532 | int adpcmSample = ((s16*)data0)[-2]; |
| 533 | int adpcmIndex = ((u8*)data0)[-2]; |
| 534 | CSND_SetAdpcmState(chn, 0, adpcmSample, adpcmIndex); |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | u32 timer = CSND_TIMER(sampleRate); |
| 539 | if (timer < 0x0042) timer = 0x0042; |
| 540 | else if (timer > 0xFFFF) timer = 0xFFFF; |
| 541 | flags &= ~0xFFFF001F; |
| 542 | flags |= SOUND_ENABLE | SOUND_CHANNEL(chn) | (timer << 16); |
| 543 | |
| 544 | u32 volumes = CSND_VOL(vol, pan); |
| 545 | CSND_SetChnRegs(flags, paddr0, paddr1, size, volumes, volumes); |
| 546 | |
| 547 | if (loopMode == CSND_LOOPMODE_NORMAL && paddr1 > paddr0) |
| 548 | { |
| 549 | // Now that the first block is playing, configure the size of the subsequent blocks |
| 550 | size -= paddr1 - paddr0; |
| 551 | CSND_SetBlock(chn, 1, paddr1, size); |
| 552 | } |
| 553 | |
| 554 | return csndExecCmds(true); |
| 555 | } |
| 556 | |
| 557 | void csndGetDspFlags(u32* outSemFlags, u32* outIrqFlags) |
| 558 | { |
nothing calls this directly
no test coverage detected