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

📄 sine.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              : sine.c    1.23
 *
 *  Last update              : 17:14:20 - 00/11/09
 *
 *  The compilation flag USE_STATIC_SINE_WAVE can be used to avoid 
 *  recalculation of sine table in ISR.  The version that recalculates
 *  can generate any frequency.  The static version cannot.
 *
 */
#include <tmlib/dprintf.h>    /* for debugging with DP(()) */
#include <stdlib.h>			  /* for atof() */
#include <stdio.h>
#include <math.h>             /* becaues I use sin() */

#include <tm1/tmInterrupts.h>

#include <tmlib/AppModel.h>
#include <ops/custom_defs.h>
#include <tm1/tmLibdevErr.h>
#include <tm1/tmAO.h>

#include <tm1/tmHelp.h>

#define PI      (3.141592654)
#define TWO_PI  (6.283185307)


#define  BUF_SIZE  256
static int  buf1[BUF_SIZE + 16];
static int  buf2[BUF_SIZE + 16];
static int *pbuf1;
static int *pbuf2;

/* these are used by the ISR */
static	float	Arg = 0;
static 	float 	Frequency = 440.0;
static  float   PhaseInc;
/* these are set on the command line */
static 	float 	Level = -20;
static 	float 	Amplitude = 3276.8;
static  float	SampleRate = 48000.0;

static void Sine(float srate, float sineFreq, float level);
static void SineISR(void);
static void CheckArgcv(int argc, char **argv);

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

/********************************************************************
 * Parse command line options:
 */
static void CheckArgcv(int argc, char **argv)
{
    int         mark = 1;

    argc--;
    while (argc > 0) {
        if ( strcmp(argv[mark], "-freq") == 0)
        { 
            argc--;
            mark++;
            Frequency = atof(argv[mark]);
			printf("Frequency set to %g at command line.\n", Frequency);
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-level") == 0) {
            argc--;
            mark++;
            Level = atof(argv[mark]);
			printf("Level set to %g dBFS at command line.\n", Level);
            argc--;
            mark++;
        }
        else if (strcmp(argv[mark], "-srate") == 0) {
            argc--;
            mark++;
            SampleRate = atof(argv[mark]);
			printf("Sample rate set to %g hertz at command line.\n", SampleRate);
            argc--;
            mark++;
        }
		else {
			printf("Sine generator program.  Command Line Options:\n");
			printf("  -freq <frequncy in Hertz>\n  -level <in dbFS>\n  -srate <sample rate in Hertz>\n");
        }
	}
}


/*********************************************************************/
int main(int argc, char **argv)
{
    DP_START(64*1024, Null);
    DP(("sine: audio sinewave program, V2.0\n"));
    printf("sine: audio sinewave program, V2.0\n");
    DP(("Running on ")); tmHelpReportSystem(Null);
    printf("Running on "); tmHelpReportSystem(stdout);
	CheckArgcv(argc, argv);
    Sine(SampleRate, Frequency, Level);
	return 0;
}

/*********************************************************************/
static void Sine(float srate, float sineFreq, float level)
{
    aoInstanceSetup_t ao;
    Int         instance;
#ifndef __TCS_nohost__
	char		ins[80];
#endif

    pbuf1 = (int *) (((unsigned long) buf1 + 63) & ~63U);
    pbuf2 = (int *) (((unsigned long) buf2 + 63) & ~63U);

	/* default is buffers filled with zero */
    memset(pbuf1, 0, BUF_SIZE * 4);
    memset(pbuf2, 0, BUF_SIZE * 4);

	/* calculate PhaseIncrement and Amplitude */
	PhaseInc = TWO_PI * sineFreq / srate;
	Amplitude = 32767.0 * pow(10.0, 0.05 *level);
	printf("PhaseInt: %g.  Amplitude: %g\n", PhaseInc, Amplitude);

#ifdef USE_STATIC_SINE_WAVE
    for (instance = 0; instance < BUF_SIZE; instance++) 
    {   /* here frequency is fixed at a multiple of buffer size */
        float       val, arg;
        Int16       ival;

        arg = TWO_PI * (float) instance / (float) BUF_SIZE;
        val = Amplitude * sin(arg);
        ival = 0xFFFF & (int) val;
        pbuf1[instance] = pbuf2[instance] = ival + (ival << 16);
    }
    printf
    printf("Sample rate %g hertz.  Sine wave at %g hertz, %g dbFS\n",
        srate, srate/(float)BUF_SIZE, level);

#else
    printf("Sample rate %g hertz.  Sine wave at %g hertz, %g dbFS\n",
        srate, sineFreq, level);
#endif USE_STATIC_SINE_WAVE

	_cache_copyback(pbuf1, BUF_SIZE*sizeof(Int32) );
	_cache_copyback(pbuf2, BUF_SIZE*sizeof(Int32) );

    ao.audioTypeFormat      = atfLinearPCM;
    ao.audioSubtypeFormat   = apfStereo16;
    ao.isr                  = SineISR;
    ao.interruptPriority    = intPRIO_3;
    ao.sRate                = srate;
    ao.size                 = BUF_SIZE;
    ao.base1                = pbuf1;
    ao.base2                = pbuf2;
    ao.underrunEnable       = True;
    ao.hbeEnable            = True;
    ao.buf1emptyEnable      = True;
    ao.buf2emptyEnable      = True;
    ao.output               = aaaNone;

    LIBDEV(aoOpen(&instance));
    LIBDEV(aoInstanceSetup(instance, &ao));
    LIBDEV(aoStart(instance));

#ifndef __TCS_nohost__
	printf("press return to exit\n");
	gets(ins);
    LIBDEV(aoStop(instance));
    LIBDEV(aoClose(instance)); 
#else
	while (1)
		;
#endif
}


/*********************************************************************/
static void 
_SineISR(void)
{
    UInt        stat = MMIO(AO_STATUS);

#ifdef TM1300_BUG_WORKAROUND    
	{
		UInt32 ao_status, ao_ctl, ao_serial, ao_framing, ao_freq, ao_base1, ao_base2, ao_size, ao_cc, ao_cfc;
		static int count =0;
		if(count++ < 2)
		{
			ao_status  = MMIO(AO_STATUS);
			ao_ctl     = MMIO(AO_CTL);
			ao_serial  = MMIO(AO_SERIAL);
			ao_framing = MMIO(AO_FRAMING);
			ao_freq    = MMIO(AO_FREQ);
			ao_base1   = MMIO(AO_BASE1);
			ao_base2   = MMIO(AO_BASE2);
			ao_size    = MMIO(AO_SIZE);
			ao_cc      = MMIO(AO_CC);
			ao_cfc     = MMIO(AO_CFC);
			DP(("reseting AO\n"));
			MMIO(AO_CTL) = 0x80000000;
			DP(("restoring old values\n"));
			MMIO(AO_SERIAL)  = ao_serial;
			MMIO(AO_FRAMING) = ao_framing;
			MMIO(AO_FREQ)    = ao_freq;
			MMIO(AO_BASE1)   = ao_base1;
			MMIO(AO_BASE2)   = ao_base2;
			MMIO(AO_SIZE)    = ao_size;
			MMIO(AO_CC)      = ao_cc;
			MMIO(AO_CFC)     = ao_cfc;
			MMIO(AO_STATUS)  = ao_status;
			MMIO(AO_CTL)     = ao_ctl;
		}
	}
#endif TM1300_BUG_WORKAROUND

    if (aoUNDERRUN(stat)) {
        aoAckACK_UDR();
        DP((" UDR "));
    }
    if (aoHBE(stat)) {
        aoAckACK_HBE();
        DP((" HBE "));
    }
#ifdef USE_STATIC_SINE_WAVE
    if (aoBUF2_EMPTY(stat))
        aoAckACK2();
    if (aoBUF1_EMPTY(stat))
        aoAckACK1();
#else
    if (aoBUF2_EMPTY(stat))
	{
		Int	i;
		Int32 *buf = (Int32*)aoGetBASE2();
		for (i=0; i<BUF_SIZE; i++)
		{
			UInt32	ival;
			Float	val;

        	Arg += PhaseInc;
        	val = Amplitude * sin(Arg);
        	ival = 0xFFFF & (int) val;
        	buf[i] = ival + (ival << 16);
            if (Arg > TWO_PI) Arg -= TWO_PI;
		}
		_cache_copyback(buf, BUF_SIZE*sizeof(Int32) );
		aoAckACK2();
	}
    if (aoBUF1_EMPTY(stat))
	{
		Int	i;
		Int32 *buf = (Int32*)aoGetBASE1();
		for (i=0; i<BUF_SIZE; i++)
		{
			UInt32	ival;
			Float	val;

        	Arg += PhaseInc;
        	val = Amplitude * sin(Arg);
        	ival = 0xFFFF & (int) val;
        	buf[i] = ival + (ival << 16);
            if (Arg > TWO_PI) Arg -= TWO_PI;
		}
		_cache_copyback(buf, BUF_SIZE*sizeof(Int32) );
        aoAckACK1();
	}
#endif USE_STATIC_SINE_WAVE
}

/* wrapper so that ISR runs on system stack, not task stack */
static void SineISR(void)
{
#pragma TCS_handler
    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_SineISR, Null);
    AppModel_resume_scheduling();
}


⌨️ 快捷键说明

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