Audio Microcode

The following topics related to the Audio Microcode, are discussed in this section:

Note: Please see Section 28, "n_audio Library," for additional information, examples, and a sample program.


Installing n_audio

Installation Procedure
Following is the procedure for installing the n_audio library.

  1. Log-in to the hardware to which this will be installed using the root.

  2. Copy the following 3 files to the appropriate directory:

    Example
        /usr/tmp/dist
              naudio
              naudio.dev
              naudio.idb

  3. Start Software Manager from the menu.

  4. Specify the directory to which the files were just copied (/usr/tmp/dist), then select "Customize Installation.."

  5. After selecting the check boxes, execute the installation.

Note: When this product is installed uncompress/usr/src/PR/n_aspMain.o.Z will be executed automatically. If an error occurs, go to the directory in which n_aspMain.o.Z is installed, and type the following:  uncompress n_aspMain.o.Z

Header Files and Libraries
When using n_audio, include the following header files:

n_libaudio.h Header file for n_audio
n_libaudio_s_to_n.h macros to convert previous audio functions to n_audio functions

Link the following libraries:

libn_audio.a n_audio library
n_aspMain.o Audio microcode for n_audio

Note: When using n_audio, do not use n_libaudio_s_to_n.h, but rewrite the audio function to n_audio directly.

Sample

As an example of setting the required number of data that is created in a frame to a multiple of 184, the sample program "playseq" (which is included with the N64 development software) has been changed to be compatible with n_audio. The changes are presented in "red."


################ Sample Program starts here  ##################
.
.

##### Change (1) starts here #####
#include "n_libaudio.h" <---------- include 
file of header file for n_audio.  
Always include this before the header file, n_libaudio_s_to_n.h.
#include "n_libaudio_s_to_n.h" <--- include file of header file for n_audio.  
This file has macros to convert previous audio functions to 
n_audio functions.  When using n_audio permanently, do not 
include this file, but rewrite each audio function to n_audio functions.
#define SAMPLES  184   <------ Define process unit of sound as 184 samples.  
#define EXTRA_SAMPLES   0   <------ When 
sound breaks are obvious, make an adjustment by setting this 
value as you think fit. (Details to be discussed later.)
extern u8 n_aspMainTextStart[], n_aspMainTextEnd[];
extern u8 n_aspMainDataStart[], n_aspMainDataEnd[];
             <------ These four declarations 
are necessary to use n_audio microcodes. 
##### Change ends (1) here #####
.
.
. 
.

static
void gameproc(u8 *argv)
{

   .       
   .

 s16
    *audioOp;
 u8
##### Change (2) starts here ##### 
            min_only_one = 1, <--- In case 
of playback frequency of 32kHz, it is calculated that 1 frame 
is needed for every 10 frames for adjusting extra sample 
(to be discussed later).
##### Change (2) ends here #####
            *seqPtr,
            *midiBankPtr;
    OSMesgQueue
            seqMessageQ;

        .
        .
        .

    /*
     * Initialize DAC output rate
     */

    c.outputRate = osAiSetFrequency(OUTPUT_RATE);
    fsize = (f32) NUM_FIELDS * c.outputRate / (f32) 60;
    frameSize = (s32) fsize; <------ Look 
for the number of samples needed for ‚Pframe.
    if (frameSize < fsize)
        frameSize++;
##### Change (3) starts here #####
    frameSize = ((frameSize / SAMPLES) + 1) * SAMPLES;
                    <------- Convert 
the number of samples needed for 1 frame, which was found above, 
to the multiple of 184.   

    minFrameSize = frameSize - SAMPLES;
                    <------ frameSize 
will be a multiple of 184, and will be larger than the number of
samples actually needed for 1 frame.  Therefore, there will be 
extra sample for every frame.  This minFrameSize is set in order to
adjust this extra sample. 

##### Change (3) ends here #####

    /*
     * Audio synthesizer initialization
     */

    c.maxVVoices = MAX_VOICES;
    c.maxPVoices = MAX_VOICES;

        .
        .
        .

    /*
     * Note that this must be a do-while in order for seqp's state
     * to get updated during the alAudioFrame processing.
     */

    do {
        frame++;

        /*
         * Where the task list goes in DRAM
         */

        tlistp = tlist[curBuf];
        cmdlp = cmdList[curBuf];

        /*
         * Where the audio goes in DRAM
         */

        buf = curAudioBuf % 3;
        audioOp = (s16 *) osVirtualToPhysical(audioBuffer[buf]);
##### Change (4) starts here  #####
        (void)osRecvMesg(&retraceMessageQ, NULL, OS_MESG_BLOCK);
                    <-------Retrace 
stand-by is here for easy understanding of the process.

        /*
         * Find out how many samples left in the currently running
         * audio buffer
         */

        samplesLeft = IO_READ(AI_LEN_REG)>>2;
                    <------- The number of remaining samples in the audio buffer 
that is currently being referenced.  This will be called 
as an extra sample from now on. 

        (void)osRecvMesg(&taskMessageQ, NULL, OS_MESG_BLOCK);
                    <------- Before 
registering the next audio buffer, 
check if the previous audio task is completed.
        /*
         * Set next AI buffer made in previous loop
         */

        osAiSetNextBuffer(audioBuffer[pbuf],audioSamples[pbuf]<<2);
                    <------- Registers 
the next audio buffer in AI.  Therefore, if the value of samples
Left found above is 0, there is the possibility that the sound 
has breaks.  The 4 commands so far are in the same order as 
the previous playseq, though they are placed in a different location.

        if((samplesLeft > (SAMPLES + EXTRA_SAMPLES)) & min_only_one)
              <------- If the number 
of extra samples when retracing is 184 or more, this frame will be
regarded as an adjusting frame in order to adjust the extra portion.
Samples of the quantity of mifFrameSize are created in an adjusting frame. 
However, it is controlled by min_only_one so that an adjusting 
frame does not succeed more than once. 
When the sound breaks are apparent, it may be because the 
extra sample is 0.  On that occasion, set the value of 
EXTRA_SAMPLES and adjust the extra of the sample.  
However, even if the value of EXTRA_SAMPLES is too large, 
the sound will not be played back properly.  
Please adjust the suitable value using the application. 
        {
            audioSamples[buf] = minFrameSize;
            min_only_one = 0;
        }
        else   <------------ Normal frame is here.
        {
            audioSamples[buf] = frameSize;
            min_only_one = 1;
        }
##### Change (4) ends here #####

        /*
         * Call the frame handler
         */

        cmdlp=alAudioFrame(cmdlp,&clcount,audioOp,audioSamples[buf]);
                
        /*
         * Build the audio task
         */
                
        tlistp->t.type = M_AUDTASK;
        tlistp->t.flags = 0x0;
        tlistp->t.ucode_boot = (u64 *) rspbootTextStart;
        tlistp->t.ucode_boot_size = ((s32)rspbootTextEnd -
                                        (s32)rspbootTextStart);
##### Change (5) starts here  #####
        tlistp->t.ucode = (u64 *) n_aspMainTextStart;
        tlistp->t.ucode_data = (u64 *) n_aspMainDataStart;
    <------ These 2 lines need to be rewritten to n_aspMain to use n_audio microcode. 
##### Change (5) ends here  #####
        tlistp->t.ucode_size = 4096;
        tlistp->t.ucode_data_size = SP_UCODE_DATA_SIZE;
        tlistp->t.data_ptr = (u64 *) cmdList[curBuf];
        tlistp->t.data_size = (cmdlp - cmdList[curBuf]) * sizeof(Acmd);

            .
            .
            .

        /*
         * Flush the cache and start task on RSP
         */

        osWritebackDCacheAll();
        osSpTaskStart(tlistp);
        CleanDMABuffs();

            .
            .
            .

    } while (seqp->state != AL_STOPPED);

        .
        .
        .
}
############# Sample Program ends here ##########


Configuration
When this product is installed using Software Manager, the following directory structure is created.

/usr/lib/libn_audio.a :n_audio library
/usr/lib/PR/n_aspMain.o :Microcode for n_audio
/usr/include/n_libaudio.h :n_libaudio_s_to_n.h: header file for n_audio
/usr/src/PR/libnaudio/* :Source file of n_audio
/usr/src/PR/playseq_naudio/* :Sample application (playseq was changed to be used for n_audio.)
/usr/src/PR/playseq_naudio/data/* :Data for the above sample

Note: When making the sample program, execute make in the data directory for the sample program (i/usr/src/PR/playseq_naudio/data) in advance, and the create .ctl file and .tbl file.


Cautions


History

Version 1.0


Release Notes
Released 12/15/1997 from n_audio (naudio.dev)

Modifications

The following changes were made to the header file, n_libaudio.h.

  1. extern declarations of n_audio microcodes were contained. Specifically, the following 2 lines were added.
    extern long long int n_aspMainTextStart[], n_aspMainTextEnd[];
    extern long long int n_aspMainDataStart[],n_aspMainDataEnd[];
    

  2. A declaration of function, n_alSynFreeFX() was added. However, please note that this function is not implemented in the same manner as in the SGI audio library.

  3. A declaration of function, n_alSynSetFXtype(), was deleted. This is because the SGI audio library function, alSynSetFXtype(), which is compatible with this function does not exist. Also, the function itself is incomplete.

The following changes were made to the header file, n_libaudio_s_to_n.h.

  1. A macro to convert the SGI audio library function, alSynFreeFX() to the n_audio library function, n_alSynFreeFX() was added.

  2. A macro to convert the SGI audio library function, alSynSetFXtype() to n_audio library function, n_alSynSetFXtype() was deleted.


Copyright © 1999
Nintendo of America Inc. All Rights Reserved
Nintendo and N64 are registered trademarks of Nintendo
Last Updated January, 1999