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

📄 sthru.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的外部设备的源码
💻 C
字号:
/*
 * Copyright (c) 1995-2000 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              : sthru.c    1.26
 *
 *  Last update              : 17:14:07 - 00/11/09
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <tmlib/AppModel.h>
#include <tmlib/dprintf.h>      /* for debugging with DP(()) */
#include <tmlib/tmlibc.h>       /* for _cache_copyback() */
#include <ops/custom_defs.h>    
#include <tm1/tmLibdevErr.h>
#include <tm1/tmAO.h>
#include <tm1/tmAI.h>

#include <tm1/tmHelp.h>

#define  BUFSIZE  256
static tmLibdevErr_t err = TMLIBDEV_OK;
#define  ERROR_REPORT(x)  err = (x); if (err != TMLIBDEV_OK) { printf("error 0x%08x: file %s, line %d.\n", err, __FILE__, __LINE__); exit(-1); }

#define     MODE_DEMO   0
#define     MODE_MIC    1
#define     MODE_LINE   2

#define PROGRAM_VERSION         1.01

/* used in thru IRQ's */
static int  inBuf, outBuf;
static int *b[4];

static int *capBuffer;
volatile static int capPtr;
#define CAPSIZE         256000

static void inISR(void);
static void outISR(void);

static float inputVolume = 0.0;
static float outputVolume = 0.0;
static float sRate = 44100.0;
static int  mode = MODE_LINE;
static Bool captureFlag = False;
static Bool monoFlag = False;
static Int  ao_instance;
static Int  ai_instance;
static Int  aiUnit = 0;
static Int  aoUnit = 0;
static UInt aiMMIOBase;
static UInt aoMMIOBase;

static void 
checkArgcv(int argc, char **argv)
{
    int         mark = 1;

    if (argc == 1) {
        printf(" Running in default LINE mode.\n");
        return;
    }
    argc--;
    while (argc > 0) {
        if (strcmp(argv[mark], "-mic") == 0) {    /* Test Mic input */
            mode = MODE_MIC;
            argc--;
            mark++;
        }

        else if (strcmp(argv[mark], "-line") == 0) {
            mode = MODE_LINE;
            argc--;
            mark++;
        }

        else if (strcmp(argv[mark], "-demo") == 0) {
            mode = MODE_DEMO;
            argc--;
            mark++;
        }

        else if (strcmp(argv[mark], "-c") == 0) {
            captureFlag = True;
            printf("Input Capture requested.\n");
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-m") == 0) {
            monoFlag = True;
            printf("Mono mode requested.\n");
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-i") == 0) {
            argc--;
            mark++;
            inputVolume = atof(argv[mark]);
            printf("Input volume of %2.2f dB requested\n", inputVolume);
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-o") == 0) {
            argc--;
            mark++;
            outputVolume = atof(argv[mark]);
            printf("Output volume of %2.2f dB requested\n", outputVolume);
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-r") == 0) {
            argc--;
            mark++;
            sRate = atof(argv[mark]);
            printf("Sample rate of %6.1f requested\n", sRate);
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-ai") == 0) {
            argc--;
            mark++;
            aiUnit = atoi(argv[mark]);
            if ((aiUnit > 0) && (aiUnit < 3))
            {
                printf("Audio in unit %d requested\n", aiUnit);
                aiUnit--;
            }
            else
            {
                printf("Invalid audio in unit number (%d) using defaultunit 1.\n", aiUnit);
                aiUnit = 0;
            }
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-ao") == 0) {
            argc--;
            mark++;
            aoUnit = atoi(argv[mark]);
            if ((aoUnit > 0) && (aoUnit < 3))
            {
                printf("Audio out unit %d requested\n", aoUnit);
                aoUnit--;
            }
            else
            {
                printf("Invalid audio out unit number (%d) using default unit 1.\n", aoUnit);
                aoUnit = 0;
            }
            argc--;
            mark++;
        }
        else {
            printf("unknown option '%s'\n\n", argv[mark]);
            printf("sthru: Default is demo mode.\n");
            printf("Command line options include:\n");
            printf("\t-mic     use microphone input\n");
            printf("\t-line    use line input\n");
            printf("\t-c       capture audio to capture.bin\n");
            printf("\t-m       use mono mode (default stereo)\n");
            printf("\t-i <x.y> sets input volume to x.y dB\n");
            printf("\t-o <x.y> sets output volume to x.y dB\n");
            printf("\t-r <x.y> sets sample rate to x.y Hz\n");
            printf("\t-ai <n>  sets audio in unit number to n\n");
            printf("\t-ao <n>  sets audio out unit number to n\n");
            exit(-1);
        }
    }
    if (mode == MODE_MIC)
        printf("MIC MODE:  Passing input from Mic\n");
    if (mode == MODE_LINE)
        printf("LINE MODE:  Passing input from Line input jack\n");
}


/************************************************************************/
int 
main(int argc, char **argv)
{
    aoInstanceSetup_t ao;
    aiInstanceSetup_t ai;
    Char              ins[80];
    Int               *buf;
    FILE              *fp;
    paiCapabilities_t aiCaps;
    paoCapabilities_t aoCaps;

    DPsize(1024 * 1024);

    DP(("sThru: audio pass thru program, V2.1\n"));
    printf("sThru: audio pass thru program, V2.1\n");

    DP(("Running on ")); tmHelpReportSystem(Null);
    printf("Running on "); tmHelpReportSystem(stdout);
    checkArgcv(argc, argv);

    outBuf = 1;        /* gets incremented first in ISR */
    inBuf = 3;        /* gets incremented first in ISR */

    capBuffer = (int *) malloc(4 * CAPSIZE);
    if (!capBuffer) {
        printf("FATAL ERROR:  Malloc of capture buffer failed\n");
        exit(3);
    }
    capPtr = 0;

    /* Allocate four cache-aligned buffers containing BUFSIZE ints. */
    buf = (int *)_cache_malloc(4 * BUFSIZE * sizeof(int), -1);
    if (!buf) {
        printf("FATAL ERROR:  Malloc of buffer failed\n");
        exit(1);
    }
    b[0] = buf;
    b[1] = &b[0][BUFSIZE];
    b[2] = &b[1][BUFSIZE];
    b[3] = &b[2][BUFSIZE];

    /* initialize them to eliminate noise at startup */
    memset(buf, 0, 4 * BUFSIZE * sizeof(int));
    _cache_copyback(buf, 4 * BUFSIZE * sizeof(int));

    /* setup control structure */
    ai.audioTypeFormat = ao.audioTypeFormat = atfLinearPCM;
    if (monoFlag)
    {
        printf("MONO TEST\n");
        ai.audioSubtypeFormat = ao.audioSubtypeFormat = apfMono16;
    }
    else
    {
        printf("STEREO TEST\n");
        ai.audioSubtypeFormat = ao.audioSubtypeFormat = apfStereo16;
    }

    ERROR_REPORT(aoGetCapabilitiesM(&aoCaps, (unitSelect_t) aoUnit));
    ERROR_REPORT(aiGetCapabilitiesM(&aiCaps, (unitSelect_t) aiUnit));
    aoMMIOBase = aoCaps->mmioBase;
    aiMMIOBase = aiCaps->mmioBase;

    ao.isr                  = outISR;
    ai.isr                  = inISR;
    ao.interruptPriority    = ai.interruptPriority = intPRIO_3;
    ao.sRate = ai.sRate     = sRate;
    ao.size  = ai.size      = BUFSIZE;
    ao.base1                = b[0];
    ao.base2                = b[1];
    ao.underrunEnable       = True;
    ao.hbeEnable            = True;
    ao.buf1emptyEnable      = True;
    ao.buf2emptyEnable      = True;
    ao.output               = aaaNone;
    ai.base1                = b[2];
    ai.base2                = b[3];
    ai.overrunEnable        = True;
    ai.hbeEnable            = True;
    ai.buf1fullEnable       = True;
    ai.buf2fullEnable       = True;
    ai.input                = aaaNone;

    ERROR_REPORT(aoOpenM(&ao_instance, (unitSelect_t) aoUnit));
    ERROR_REPORT(aoInstanceSetup(ao_instance, &ao));
    ERROR_REPORT(aiOpenM(&ai_instance, (unitSelect_t) aiUnit));
    ERROR_REPORT(aiInstanceSetup(ai_instance, &ai));
    aoSetVolume(ao_instance, outputVolume * 100, outputVolume * 100);
    aiSetVolume(ai_instance, inputVolume * 100, inputVolume * 100);
    if (mode == MODE_MIC) {
        ERROR_REPORT(aiSetInput(ai_instance, aaaMicInput));
    }
    else {
        ERROR_REPORT(aiSetInput(ai_instance, aaaLineInput));
    }
    ERROR_REPORT(aiStart(ai_instance));
    ERROR_REPORT(aoStart(ao_instance));

    if (mode == MODE_DEMO) {

        /*
         * self running demo mode:
         * 
         * line in, input volume 0, output volume 0 line in, input
         * volume 0, output volume -12 dB line in, input volume +12
         * dB, output volume -12 dB mic in, input volume 0, output
         * volume 0 mic in, input volume +12 dB, output volume 0
         * 
         * NOTE: due to HW bug # 21228, the 0 dB setting does not equate
         * to 0 dB pass-thru.  we noticed approximately 3 dB loss due
         * to ad1847 and 6 dB loss due to IREF board circuitry
         * (pre-filter).
         */

        printf("line in, input volume 0 dB, output volume 0 dB (for 5 seconds)\n");
        ERROR_REPORT(aiSetVolume(ai_instance, 0, 0));
        sleep(5);

        printf("line in, input volume 0 dB, output volume -12 dB (for 5 seconds)\n");
        ERROR_REPORT(aoSetVolume(ao_instance, -1200, -1200));
        sleep(5);

        printf("line in, input volume +12 dB, output volume -12 dB "
               "(for 5 seconds)\n");
        ERROR_REPORT(aiSetVolume(ai_instance, +1200, +1200));
        sleep(5);

        printf("mic in, input volume 0 dB, output volume 0 dB "
               "(for 5 seconds)\n");
        ERROR_REPORT(aoSetVolume(ao_instance, 0, 0));
        ERROR_REPORT(aiSetVolume(ai_instance, 0, 0));
        ERROR_REPORT(aiSetInput(ai_instance, aaaMicInput));
        sleep(5);

        printf("mic in, input volume +12 dB, output volume 0 dB "
               "(for 5 seconds)\n");
        ERROR_REPORT(aiSetVolume(ai_instance, +1200, +1200));
        sleep(5);

        printf("\n Test Completed\n");
    }
    else {
        printf("Audio Pass Thru is running.  Press return to exit :\n");
        gets(ins);
    }

    ERROR_REPORT(aoStop(ao_instance));
    ERROR_REPORT(aiStop(ai_instance));
    ERROR_REPORT(aoClose(ao_instance));
    ERROR_REPORT(aiClose(ai_instance));

    if (captureFlag) {
        printf("Writing %d samples of captured data to "
               "capture.bin...\n", CAPSIZE);
        fp = fopen("capture.bin", "wb");
        if (!fp) {
            printf("FATAL ERROR:  capture.bin fopen failed\n");
            exit(2);
        }
        fwrite(capBuffer, 1, CAPSIZE * 4, fp);
        fclose(fp);
        printf("Done!\n");
    }
    exit(0);
}


/********************************************************/
/* Used for sound thru */
static void 
_outISR(void)
{
    UInt        stat;

    outBuf++;
    outBuf &= 0x3;

    /* DP (("Out-b%d  ", outBuf));    */

    stat = MMIO(aoMMIOBase);
    if (aoUNDERRUN(stat)) {
        aoAckACK_UDRM(aoMMIOBase);
        DP((" UDR "));
    }
    if (aoHBE(stat)) {
        aoAckACK_HBEM(aoMMIOBase);
        DP((" out HBE "));
    }
    if (aoBUF2_EMPTY(stat)) {
        aoSetBASE2M(aoMMIOBase, b[outBuf]);
        aoAckACK2M(aoMMIOBase);
    }
    if (aoBUF1_EMPTY(stat)) {
        aoSetBASE1M(aoMMIOBase, b[outBuf]);
        aoAckACK1M(aoMMIOBase);
    }
}


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

/********************************************************/
/* used for sound thru */
static void 
_inISR(void)
{
    Int        *foo;
    Int         i;
    UInt        stat;

    inBuf++;
    inBuf &= 0x3;

    /*
     * DP( ("In -b%d  ", inBuf)); if (inBuf == 0) DP(("\n"));
     */

    stat = MMIO(aiMMIOBase);
    if (aiOVERRUN(stat)) {
        aiAckACK_OVRM(aiMMIOBase);
        DP((" OVR "));
    }
    if (aiHBE(stat)) {
        aiAckACK_HBEM(aiMMIOBase);
        DP((" in HBE "));
    }
    if (aiBUF2_FULL(stat)) {
        foo = (int *) aiGetBASE2();
        aiSetBASE2M(aiMMIOBase, b[inBuf]);
        aiAckACK2M(aiMMIOBase);
    }
    if (aiBUF1_FULL(stat)) {
        foo = (int *) aiGetBASE1();
        aiSetBASE1M(aiMMIOBase, b[inBuf]);
        aiAckACK1M(aiMMIOBase);
    }

    /*
     * the cache invalidation is needed so that we ignore any lines from
     * the buffers that might be in the cache and fetch the new data from
     * SDRAM, just captured from Audio In.
     * 
     */
    _cache_invalidate(foo, BUFSIZE*4);

    for (i = 0; i < BUFSIZE; i++) {
        if (capPtr >= CAPSIZE)
            break;
        capBuffer[capPtr++] = foo[i];
    }
    /* DP(("capPtr at %d\n", capPtr)); */
}

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

⌨️ 快捷键说明

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