4. Installing n_audio

[UP]


4.1 Installation

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 (example /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

[UP]


4.2 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.

[UP]


4.3 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.

File : playseq.c

################ 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 values 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
##### Change (1) ends here #####

     .
     .
     . 
     . 

static
void gameproc(u8 *argv)
{

         .
         .

    s16
            *audioOp;
    u8
##### Change (2) starts here ##### 
            min_only_one = 1, <---In case of playback frequency of 32 kHz, it is calculated that 1 frame is needed for every 10 frames for adjusting extra sample (to be discussed later).
##### Changes (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 1 frame.
    if (frameSize < fsize)
        frameSize++;
##### Change (3) starts here#####
    frameSize = ((frameSize / SAMPLES) + 1) * SAMPLES;
                    <-------Convert the number of samples needed for 1 frames, 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 ##################

[UP]