📄 sine.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 + -