main.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:7k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /*
  9.  *  ======== main.c ========
  10.  * 
  11.  *  This example demonstrates the use of IOM drivers with SIOs and tasks by 
  12.  *  using the DIO class driver with a user defined device mini-driver 
  13.  *  called "codec" and a class driver DIO instance called "dio_codec". This is 
  14.  *  the loopback application where audio is read from an input SIO, then sent 
  15.  *  back via an output SIO.
  16.  *  The following objects need to be created in the DSP/BIOS
  17.  *  configuration for this application:
  18.  *
  19.  *  * A UDEV object, which links in a user device driver. In this
  20.  *    case the UDEV is a codec based IOM device driver.
  21.  *  * A DIO object, which links the UDEV object.
  22.  *  * A TSK object, with the function to run set to the function demo
  23.  *    defined in this file.
  24.  *  * A LOG named trace for debug and status output.
  25.  */
  26. #include <std.h>
  27. #include <log.h>
  28. #include <sys.h>
  29. #include <mem.h>
  30. #include <sio.h>
  31. #include <csl.h>
  32. #include <csl_cache.h>
  33. #include <evmdm642.h>
  34. #include <evmdm642_led.h>
  35. #include <evmdm642_edma_aic23.h>
  36. #define NUM_CODEC_CHANNELS  2 /* stereo: left + right */
  37. #define SAMPLEING_RATE 48 /* 48 samples/ms */
  38. #define FRAME_SIZE 10 /* 10 ms */
  39. #define NFRAMES 100 /* 100 frames = 1 second */
  40. #define BUFLEN (NUM_CODEC_CHANNELS*SAMPLEING_RATE*FRAME_SIZE)
  41. #ifdef _6x_
  42. extern far LOG_Obj trace;
  43. /* 
  44.  * Buffers placed in external memory are aligned on a 128 bytes boundary.
  45.  * In addition, the buffer should be of a size multiple of 128 bytes for 
  46.  * the cache work optimally on the C6x.
  47.  */
  48. #define BUFALIGN 128    /* alignment of buffer to allow use of L2 cache */
  49. #else
  50. extern LOG_Obj trace;
  51. #define BUFALIGN 1
  52. #endif
  53. #define BUFSIZE (BUFLEN * sizeof(short)) 
  54. /*
  55.  *  ======== EVMDM642_DEVPARAMS ========
  56.  *  This static initialization defines the default parameters used for
  57.  *  EVMDM642_EDMA_AIC23 IOM driver
  58.  */
  59. EVMDM642_EDMA_AIC23_DevParams EVMDM642_CODEC_DEVPARAMS =
  60.         EVMDM642_EDMA_AIC23_DEFAULT_DEVPARAMS;
  61. /* inStream and outStream are SIO handles created in main */
  62. SIO_Handle inStream, outStream;
  63. /* Function prototype */
  64. static Void createStreams();
  65. static Void prime();
  66. /*
  67.  * ======== main ========
  68.  */
  69. Void main()
  70. {
  71. EVMDM642_LED_init();
  72.     LOG_printf(&trace, "echo started");
  73. }
  74. short *pEchoBuf;
  75. const int echoBufSize = NFRAMES * BUFLEN;
  76. int echoBufOffset = 0;
  77. int delayTime = 500;
  78. int echoAtt = 64;
  79. /*
  80.  *  ======== initEchoBuffer ========
  81.  * Allocate echo buffer and fill with silence
  82.  */
  83. int initEchoBuffer()
  84. {
  85. pEchoBuf = MEM_calloc(0, echoBufSize * sizeof(short), BUFALIGN);
  86. return (pEchoBuf == MEM_ILLEGAL) ? -1 : 0;
  87. }
  88. /*
  89.  *  ======== copyWithEcho ========
  90.  * Copy an incoming buffer with stereo audio samples into an outgoing
  91.  * buffer, mixing with samples from the echo buffer indexed by
  92.  * the parameter timeDelay.  The parameter "a" indicates the mix
  93.  * attenuation * 256 (i.e. 64 = 0.25).
  94.  */
  95. void copyWithEcho(short *inBuf, short *outBuf, int timeDelay, int a)
  96. {
  97. int i;
  98. int echoDelayOffset;
  99. int srcSample;
  100. int echoSample;
  101. /*
  102.  * Clamp timeDelay to a reasonable range
  103.  */
  104. if (timeDelay < 0)
  105. timeDelay = 0;
  106. if (timeDelay > (NFRAMES * 10))
  107. timeDelay = NFRAMES * 10;
  108. /*
  109.  * Compute initial offset into echo buffer
  110.  */
  111. echoDelayOffset = echoBufOffset - (timeDelay * NUM_CODEC_CHANNELS*SAMPLEING_RATE);
  112. if (echoDelayOffset < 0)
  113. echoDelayOffset += echoBufSize;
  114. /*
  115.  * Now copy and mix everything...
  116.  */
  117. for (i = 0; i < BUFLEN; i++) {
  118. srcSample = (int) *inBuf++;
  119. echoSample = srcSample + ((a * pEchoBuf[echoDelayOffset++]) >> 8);
  120. if (echoSample < -32768)
  121. echoSample = -32768;
  122. else if (echoSample > 32767)
  123. echoSample = 32767;
  124. *outBuf++ = (short) echoSample;
  125. pEchoBuf[echoBufOffset++] = (short) srcSample;
  126. if (echoDelayOffset > echoBufSize)
  127. echoDelayOffset = 0;
  128. }
  129. if (echoBufOffset > echoBufSize)
  130. echoBufOffset = 0;
  131. }
  132. /*
  133.  * ======== createStreams ========
  134.  */
  135. static Void createStreams()
  136. {
  137.     SIO_Attrs attrs;
  138.     
  139.     /* align the buffer to allow it to be used with L2 cache */
  140.     attrs = SIO_ATTRS;
  141.     attrs.align = BUFALIGN;
  142.     attrs.model = SIO_ISSUERECLAIM;
  143.     /* open the I/O streams */
  144.     inStream = SIO_create("/dio_codec", SIO_INPUT, BUFSIZE, &attrs);
  145.     if (inStream == NULL) {
  146.         SYS_abort("Create input stream FAILED.");
  147.     }
  148.     outStream = SIO_create("/dio_codec", SIO_OUTPUT, BUFSIZE, &attrs);
  149.     if (outStream == NULL) {
  150.         SYS_abort("Create output stream FAILED.");
  151.     }
  152. }
  153. /*
  154.  * ======== prime ========
  155.  */
  156. static Void prime()
  157. {
  158.     Ptr buf0, buf1, buf2, buf3;
  159.     LOG_printf(&trace, "Allocate buffers started");
  160.     /* Allocate buffers for the SIO buffer exchanges */
  161.     buf0 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
  162.     buf1 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
  163.     buf2 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
  164.     buf3 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
  165.     if (buf0 == NULL || buf1 == NULL || buf2 == NULL || buf3 == NULL) {
  166.         SYS_abort("MEM_calloc failed.");
  167.     } 
  168.     
  169.     /* Issue the first & second empty buffers to the input stream */
  170.     if (SIO_issue(inStream, buf0, SIO_bufsize(inStream), NULL) != SYS_OK) {
  171.         SYS_abort("Error issuing buffer to the input stream");
  172.     }
  173.     if (SIO_issue(inStream, buf1, SIO_bufsize(inStream), NULL) != SYS_OK) {
  174.         SYS_abort("Error issuing buffer to the input stream");
  175.     }
  176.     /* Issue the first & second empty buffers to the output stream */
  177.     if (SIO_issue(outStream, buf2, SIO_bufsize(outStream), NULL) != SYS_OK) {
  178.         SYS_abort("Error issuing buffer to the output stream");
  179.     }
  180.     if (SIO_issue(outStream, buf3, SIO_bufsize(outStream), NULL) != SYS_OK) {
  181.         SYS_abort("Error issuing buffer to the output stream");
  182.     }
  183. }
  184. /*
  185.  * ======== tskAudioDemo ========
  186.  * This function copies from the input SIO to the output SIO. You could
  187.  * easily replace the copy function with a signal processing algorithm. 
  188.  */
  189. Void tskAudioDemo()
  190. {
  191.     Int nmadus;         /* number of minimal addressable units */
  192.     short *inbuf, *outbuf;
  193. /* Call createStream function to create I/O streams */
  194.     createStreams();
  195.     
  196.     /* Call prime function to do priming */
  197.     prime();
  198.     
  199.     initEchoBuffer();
  200.     /* Loop forever looping back buffers */
  201.     for (;;) {
  202.         /* Reclaim full buffer from the input stream */
  203.         if ((nmadus = SIO_reclaim(inStream, (Ptr *)&inbuf, NULL)) < 0) {
  204.             SYS_abort("Error reclaiming full buffer from the input stream");
  205.         }
  206.         /* Reclaim empty buffer from the output stream to be reused */
  207.         if (SIO_reclaim(outStream, (Ptr *)&outbuf, NULL) < 0) {
  208.             SYS_abort("Error reclaiming empty buffer from the output stream");
  209.         }
  210. /* process echo algorithm */
  211. copyWithEcho(inbuf, outbuf, delayTime, echoAtt);
  212. EVMDM642_LED_toggle(0);
  213.         /* Issue full buffer to the output stream */
  214.         if (SIO_issue(outStream, outbuf, nmadus, NULL) != SYS_OK) {
  215.             SYS_abort("Error issuing full buffer to the output stream");
  216.         }
  217.         /* Issue an empty buffer to the input stream */
  218.         if (SIO_issue(inStream, inbuf, SIO_bufsize(inStream), NULL) != SYS_OK) {
  219.             SYS_abort("Error issuing empty buffer to the input stream");
  220.         }
  221.     }
  222. }