⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patest.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的外部设备的源码
💻 C
字号:
/*
 * Copyright (c) 1995-1999 by TriMedia Technologies. 
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 * Module name              : patest.c    1.36
 *
 * Last update              : 17:31:45 - 00/11/09
 *
 * Description              :
 *
 * pSOS stub for audio testing: This is an example of a simple pSOS program
 * which reads in a file of audio data and plays it.
 *
 *
 */

/*----------------------------- includes ------------------------------------*/

#include <stdio.h>
#include <psos.h>
#include <ops/custom_defs.h>
#include <tmlib/tmlibc.h>
#include <tmlib/AppModel.h>
#include <tm1/mmio.h>

#include <tm1/tmInterrupts.h>
#include <tm1/tmAO.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <tmlib/dprintf.h>
#include "sys_conf.h"
#include <string.h>

#include <tm1/tmHelp.h>


/*------------------------- local definitions -------------------------------*/

#define  BUFSIZE              1536
#define  NUM_BUFS                3
#define  PRIORITY_BASE         100
#define  TM1_CACHE_BLOCK_SIZE   64

#define ENDIAN_SWAP(a) \
           ( (a<<24) + ((a&0xFF00)<<8) + ((a>>8)&0xFF00) + ((a>>24) & 0xFF) )


/*
 * The following defines two queues of packets circulating between the audio
 * decoder and the audio renderer; full buffers stream from decoder to
 * renderer, and empty ones back to the decoder to be filled again. The
 * packets streaming through the queues are allocated from the packet_pool.
 */

typedef struct {
    Pointer         pointer;
    UInt            size;
}               MixPacket_t;


static UInt32   full_q, empty_q;
static MixPacket_t *packet1, *packet2;

static MixPacket_t packet_pool[NUM_BUFS];



/*
 * The following contain the buffer of fixed audio data which will be read
 * from file at startup, to be passed repeatedly from decoder to renderer:
 */
static Int     *waveData;
static Int      waveLength;


/*------------------------- utility functions -------------------------------*/


/*
 * Attempt to load a file from the host's disk into an allocated buffer, and
 * return this buffer, with size.
 *
 * Return True upon success, False upon failure
 */
#define MAX_READ_SIZE   6000000 /* 6 meg */
static          Bool
LoadFile(String FileName, Int ** FileData, Int * FileSize)
{
    FILE           *f;
    Pointer         data;
    int             mallocSize;

    f = fopen(FileName, "rb");

    if (f == Null) {
        return False;
    }
    else {
        /* get as much memory is available (less than 6M) */
        data = NULL;
        for (mallocSize = 0x600000; !(data = (Pointer) malloc(mallocSize)); mallocSize -= 32768);
        mallocSize -= 32768;    /* leave extra space for OS */
        *FileData = data;

        if (data != Null)
            *FileSize = fread(data, 1, mallocSize, f);
        fclose(f);
        return (data != Null);
    }
}



/*
 * Attempt to load a wave file into an allocated buffer; either use the file
 * name provided by the user, or use the default "g.bin"
 *
 * Return True upon success, False upon failure Upon success, the buffer plus
 * wave length are placed into the global variables waveData resp waveLength
 */

static          Bool
LoadWaveFile()
{
    Char            input_line[80];
    Char           *cp;
    String          used_soundfile;
#ifdef __BIG_ENDIAN__
    int i;
#endif  /* __BIG_ENDIAN__ */
    /*
     * Get the data, or return failure:
     */

    printf("Enter the name of a sound file to be played. (g.bin is default)\n");

    fgets(input_line, 80, stdin);
    if (cp = strchr(input_line, '\n'))
        *cp = 0;    /* zap null byte */

    used_soundfile = input_line;
    if (!LoadFile(used_soundfile, &waveData, &waveLength)) {

        printf("  failed opening sound file %s.  Checking for default, g.bin\n", input_line);
        used_soundfile = "g.bin";
        if (!LoadFile(used_soundfile, &waveData, &waveLength)) {
            printf("\n\t!!Failed to open g.bin.\n");
            return False;
        }
    }
    /* we need the size in words */
    waveLength /= sizeof(Int);

    /*
     * assuming wave files are little endian, we can swap them for big
     * endian playback
     */
#ifdef __BIG_ENDIAN__
    for (i = 0; i < waveLength; i++)
        waveData[i] = ENDIAN_SWAP(waveData[i]);
#endif

    printf("Read %d words from file %s in 0x%08x\n", waveLength, used_soundfile, waveData);
    DP(("Read %d words from file %s in 0x%08x\n", waveLength, used_soundfile, waveData));

    return True;
}




/*
 * Print processor information
 *
 */

static void
print_banner()
{
    UInt            id;
    paoCapabilities_t ao_caps;

    boardGetID(&id);
    aoGetCapabilities(&ao_caps);

    /* --- . --- */

    DP_START(32768, Null);

    DP(("\npatest:  TM-1 audio example program using pSOS.\n"));
    tmHelpReportSystem(Null);
    printf("\npatest:  TM-1 audio example program using pSOS.\n\n");
    tmHelpReportSystem(stdout);

    /* --- . --- */


    printf("* Audio Interface v%d.%d (%d)\n",
           ao_caps->version.majorVersion,
           ao_caps->version.minorVersion,
           ao_caps->version.buildVersion);

}




/*--------------------------- Audio Renderer --------------------------------*/



static void
_arendISR(void)
{
    UInt32          message[4];
    MixPacket_t    *tempak;
    UInt            stat;


    stat = MMIO(AO_STATUS);

    if (q_receive(full_q, Q_NOWAIT, 0, message)) {
	DP(("underrun in arendISR\n"));
	if (aoBUF1_EMPTY(stat))
	    aoAckACK1();
	if (aoBUF2_EMPTY(stat))
	    aoAckACK2();

    }
    else {

	tempak = (MixPacket_t *) message[0];

	if (aoBUF1_EMPTY(stat)) {
	    message[0] = (unsigned int) packet1;
	    packet1 = tempak;

	    aoSetBASE1((unsigned long) packet1->pointer);
	    aoAckACK1();
	}
	if (aoBUF2_EMPTY(stat)) {
	    message[0] = (unsigned int) packet2;
	    packet2 = tempak;

	    aoSetBASE2((unsigned long) packet2->pointer);
	    aoAckACK2();
	}
	q_send(empty_q, message);
    }
}

static void
arendISR(void)
{
#pragma TCS_handler
    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_arendISR, Null);
    AppModel_resume_scheduling();
}





/*
 * The following is the psos task function of the audio rendererer. This task
 * sets up the audio out interrupt stream which keeps itself going receiving
 * buffers from the full queue, and giving these to the audio out device.
 */

static void
a_rend()
{
    aoInstanceSetup_t ao;
    UInt32          message[4];
    Int             instance;

    printf("\n\n\tAudio Renderer is running:\n");


    /* need two buffers before we can start the hardware */
    q_receive(full_q, Q_WAIT, 0, message);
    packet1 = (MixPacket_t *) message[0];
    q_receive(full_q, Q_WAIT, 0, message);
    packet2 = (MixPacket_t *) message[0];

    /* setup control structure */
    ao.audioTypeFormat      = atfLinearPCM;
    ao.audioSubtypeFormat   = apfStereo16;
    ao.isr                  = arendISR;
    ao.interruptPriority    = intPRIO_3;
    ao.sRate                = 48000.0;
    ao.size                 = packet1->size;
    ao.output               = aaaNone;
    ao.base1                = packet1->pointer;
    ao.base2                = packet2->pointer;
    ao.underrunEnable       = False;
    ao.hbeEnable            = False;
    ao.buf1emptyEnable      = True;
    ao.buf2emptyEnable      = True;

    if (aoOpen(&instance) != TMLIBDEV_OK) {
        printf("aoOpen failed.  Audio Renderer suspending.\n");
        t_suspend(0L);
    }
    if (aoInstanceSetup(instance, &ao) != TMLIBDEV_OK) {
        printf("aoInstanceSetup failed.  Audio Renderer suspending.\n");
        t_suspend(0L);
    }
    /* start audio hardware */

    if (aoStart(instance) != TMLIBDEV_OK) {
        printf("aoStart failed\n");
    }
    /* sets output volume to default (no attenuation) */
    aoSetVolume(instance, 0, 0);


    printf("\tPlease press return to exit.\n");

    getchar();
    aoStop(instance);
    aoClose(instance);

    _psos_exit(0);
}





/*--------------------------- Audio Decoder (Stub) --------------------------*/


/*
 * The following is the psos task function of the audio decoder; the decoder
 * continuously reads a buffer from the empty_q, puts decoded  audio data in
 * it, and places it into the full_q to be picked up by the audio renderer.
 *
 * In this example, the data is simply obtained from the fixed waveData buffer,
 * which has been read in by the root task.
 */

static void
dec_stub()
{
    Int            *curData = waveData;

    printf("\n\n\tAudio Decoder is running:\n");

    while (True) {
        UInt32          message[4];
        MixPacket_t    *mixpak;
        Int32          *dPtr;
        Int             i;

        /*
         * Get an empty buffer; if not yet available, then wait until
         * one can be obtained:
         */
        q_receive(empty_q, Q_WAIT, 0, message);

        mixpak = (MixPacket_t *) message[0];


        /*
         * Fill the buffer, and copy it back to SDRAM (the Audio Out
         * does not read its data via the cache):
         */
        dPtr = (Int32 *) mixpak->pointer;
        for (i = 0; i < mixpak->size; i++) {
            dPtr[i] = *curData++;
            if (curData >= &waveData[waveLength])
                curData = waveData;
        }
        _cache_copyback(mixpak->pointer, mixpak->size * sizeof(Int));

        /*
         * Send it to the renderer:
         */
        q_send(full_q, message);
    }

}






/*------------------------------ pSOS root task -----------------------------*/


extern void
root(void)
{

    UInt32          audio_decoder, audio_render;

    Int            *bufPtr, i;
    UInt32          message[4];



    /*-------------------------------
         * Print header including processor info:
         */
    print_banner();


    /*-------------------------------
         * Load the wave file from disk;
         * the data is returned in global
         * variables waveData resp waveLength:
         */

    if (!LoadWaveFile()) {
        _psos_exit(0x47);
    }
    /*-------------------------------
         * Create the buffer queues.
         * Initialise the 'empty' buffer queue
         * with cache aligned packet buffers;
         * the assumption here is that
         * BUFSIZE * sizeof(Int) is a multiple
         * of the data cache page size (64):
         */

    q_create("frat", NUM_BUFS, Q_LOCAL | Q_FIFO | Q_NOLIMIT, &full_q);
    q_create("erat", NUM_BUFS, Q_LOCAL | Q_FIFO | Q_NOLIMIT, &empty_q);


    bufPtr = (Pointer) _cache_malloc(NUM_BUFS * BUFSIZE * sizeof(Int), -1);

    if (bufPtr == Null) {
        printf("!!dec_stub:  Failed to allocate buffer memory.\n");
        t_suspend(0L);
    }
    for (i = 0; i < NUM_BUFS; i++) {
        packet_pool[i].pointer = bufPtr;
        packet_pool[i].size = BUFSIZE;

        message[0] = (UInt) & packet_pool[i];

        q_send(empty_q, message);
        bufPtr += BUFSIZE;
    }



    /*-------------------------------
         * Create and start psos tasks,
         * and get things going:
         */

    t_create("adec", PRIORITY_BASE + 6, 40000, 40000, T_LOCAL, &audio_decoder);
    t_start(audio_decoder, T_PREEMPT | T_TSLICE | T_NOASR | T_ISR, dec_stub, Null);

    t_create("arnd", PRIORITY_BASE + 8, 10000, 10000, T_LOCAL, &audio_render);
    t_start(audio_render, T_PREEMPT | T_TSLICE | T_NOASR | T_ISR, a_rend, Null);


    printf("Thank you!  Now deleting root...\n");
    t_delete(0L);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -