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