Audio Microcode

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

- Introduction
  Provides a brief overview of n-audio, an improved version of the old SGI audio library

- Improvements
  Describes the improvements to the audio library

- Effects
  Provides information about how to prepare the data for use with the new n_audio library

- Installing N-audio
  Provides instructions for installing n_audio

- Configuration
  Describes the directory structure for n_audio

- Cautions
  Includes information about the functionality of n_audio

- History
  This section includes a Revision History, and a copy of the Release Notes for n_audio

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

- use n_audio with Ultra 64 Development Environment, 2.0H or later.

- Only linear functions are supported for the envelope with this version of the n_audio library. Support for exponential functions is planned for the next version.

History

Version 1.0

- 12/15/1997
  Compatible with OS2.0I (for SGI)

- 4/21/1997
  n_audio released

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

Modifications

- The n_audio library, which was released as a patch for 2.0H, has been included in Version 2.0I for RCP 2.0.

- The directory structure under /usr/src/PR was revised.
  Demo software is now installed in /usr/src/PR/demos. Please see /usr/src/PR/README.txt additional information. See also, /usr/src/PR/demos/README_DEMOS_NAUDIO.txt for explanations of the demo software.

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