diff options
Diffstat (limited to 'lib/ultralib/src/io/aisetfreq.c')
| -rw-r--r-- | lib/ultralib/src/io/aisetfreq.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/ultralib/src/io/aisetfreq.c b/lib/ultralib/src/io/aisetfreq.c index e41d6fa..2b0efca 100644 --- a/lib/ultralib/src/io/aisetfreq.c +++ b/lib/ultralib/src/io/aisetfreq.c @@ -1,12 +1,18 @@ #include "PR/rcp.h" #include "PR/ultraerror.h" -#include "../os/osint.h" +#include "PRinternal/osint.h" // TODO: not sure if this should be here extern s32 osViClock; // TODO: this comes from a header #ident "$Revision: 1.17 $" +/** + * Programs the operating frequency of the Audio DAC. + * + * @param frequency Target Playback frequency. + * @return The actual playback frequency, or -1 if the supplied frequency cannot be used. + */ s32 osAiSetFrequency(u32 frequency) { register unsigned int dacRate; register unsigned char bitRate; @@ -31,15 +37,20 @@ s32 osAiSetFrequency(u32 frequency) { } #endif + // Calculate the DAC sample period ("dperiod") (dperiod + 1 = vid_clock / frequency) f = osViClock / (float)frequency + .5f; dacRate = f; + // Upcoming division by 66. If dacRate is smaller than 2 * 66 = 132, bitrate will be 1 and AI_BITRATE_REG will be + // programmed with 0, which results in no audio output. Return -1 to indicate an unusable frequency. if (dacRate < AI_MIN_DAC_RATE) { return -1; } + // Calculate the largest "bitrate" (ABUS clock half period, "aclockhp") supported for this dacrate. These two + // quantities must satisfy (dperiod + 1) >= 66 * (aclockhp + 1), here this is taken as equality. bitRate = dacRate / 66; - + // Clamp to max value if (bitRate > AI_MAX_BIT_RATE) { bitRate = AI_MAX_BIT_RATE; } @@ -49,5 +60,7 @@ s32 osAiSetFrequency(u32 frequency) { #if BUILD_VERSION < VERSION_J IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON); #endif + // Return the true playback frequency (frequency = vid_clock / (dperiod + 1)), which may differ from the target + // frequency. return osViClock / (s32)dacRate; } |
