www.pudn.com > Audio.rar > swi_audio.c


/* 
 *  Copyright 2003 by Texas Instruments Incorporated. 
 *  All rights reserved. Property of Texas Instruments Incorporated. 
 *  Restricted rights to use, duplicate or disclose this code are 
 *  granted through contract. 
 *   
 */ 
/* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */ 
 
/*  
 *  ======== swi_audio.c ======== 
 *  
 *  This example demonstrates the use of IOM drivers with SIOs and SWIs by 
 *  using the DIO class driver with a user defined device mini-driver  
 *  called "codec". This is a loopback application where audio is read  
 *  from an input SIO, then sent back via an output SIO.  
 * 
 *  The following objects need to be created in the DSP/BIOS 
 *  configuration for this application: 
 * 
 *  * A UDEV object, which links in a user device driver. In this 
 *    case the UDEV object is a codec based IOM device driver. 
 *  * A DIO object, which links the UDEV object. 
 *  * A SWI object, with the function to run set to the function echo 
 *    defined in this file. 
 *  * A LOG named trace for debug and status output. 
 */ 
 
#include  
 
#include  
#include  
#include  
#include  
#include  
#include  
 
#ifdef _6x_ 
extern far LOG_Obj trace; 
extern far SWI_Obj swiEcho; 
/* 
 * Buffers placed in external memory ar aligned on a 128 bytes boundary.  
 * In addition, the buffer should be of a size multiple of 128 bytes for the  
 * cache work optimally on the C6x.  
 */ 
#define BUFLEN 128      /* number of samples in a frame */ 
#define BUFALIGN 128    /* alignment of buffer to allow use of L2 cache */ 
#else 
extern LOG_Obj trace; 
extern SWI_Obj swiEcho; 
#define BUFLEN 128      /* number of samples in a frame */ 
#define BUFALIGN 1 
#endif 
 
#define BUFSIZE (BUFLEN * sizeof(MdUns)) 
 
/* inStream and outStream are SIO handles created in main */ 
SIO_Handle inStream, outStream; 
 
/* Function prototype */ 
static Void createStreams(); 
static Void prime(); 
 
/* 
 *  ======== main ======== 
 */ 
Void main() 
{ 
    /* Call createStreams function to create I/O streams */ 
    createStreams(); 
 
    /* Call prime function to do buffer priming */ 
    prime(); 
 
    LOG_printf(&trace, "swi_audio started"); 
} 
 
/*  
 * ======== createStreams ======== 
 * 
 * This function creates the SIO streams to be used by the application  
 */ 
static Void createStreams() 
{ 
    SIO_Attrs attrs; 
    DEV_Callback callback;    /* callback used because SWIs cannot block */ 
     
    callback.fxn = (Fxn)SWI_andnHook; 
    callback.arg0 = (Arg)&swiEcho; 
    callback.arg1 = (Arg)0x1; /* This sets the IOM_INPUT mode */ 
 
    /* Align the buffer to allow it to be used with L2 cache */ 
    attrs = SIO_ATTRS; 
    attrs.align = BUFALIGN; 
    attrs.model = SIO_ISSUERECLAIM; 
    attrs.callback = (DEV_Callback *)&callback; 
 
    /* Create the I/O streams */ 
    inStream = SIO_create("/dioCodec", SIO_INPUT, BUFSIZE, &attrs); 
    if (inStream == NULL) { 
        SYS_abort("Create input stream  FAILED."); 
    } 
 
    callback.arg1 = (Arg)0x2; /* This sets the IOM_OUTPUT mode */ 
    outStream = SIO_create("/dioCodec", SIO_OUTPUT, BUFSIZE, &attrs); 
    if (outStream == NULL) { 
        SYS_abort("Create output stream FAILED."); 
    } 
} 
 
/*  
 * ======== prime ======== 
 * 
 * This function primes the streams with empty buffers so that the  
 * issue/reclaim loop can start in the application's processing thread. 
 */ 
static Void prime() 
{ 
    Ptr buf0, buf1, buf2, buf3; 
 
    LOG_printf(&trace, "Allocate buffers started"); 
 
    /* Allocate buffers for the SIO buffer exchanges */ 
    buf0 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN); 
    buf1 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN); 
    buf2 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN); 
    buf3 = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN); 
    if (buf0 == NULL || buf1 == NULL || buf2 == NULL || buf3 == NULL) { 
        SYS_abort("MEM_calloc failed."); 
    }  
     
    /* Issue the first & second empty buffers to the input stream */ 
    if (SIO_issue(inStream, buf0, SIO_bufsize(inStream), NULL) != SYS_OK) { 
        SYS_abort("Error issuing buffer"); 
    } 
    if (SIO_issue(inStream, buf1, SIO_bufsize(inStream), NULL) != SYS_OK) { 
        SYS_abort("Error issuing buffer"); 
    } 
 
    /* Issue the first & second empty buffers to the output stream */ 
    if (SIO_issue(outStream, buf2, SIO_bufsize(outStream), NULL) != SYS_OK) { 
        SYS_abort("Error issuing buffer"); 
    } 
    if (SIO_issue(outStream, buf3, SIO_bufsize(outStream), NULL) != SYS_OK) { 
        SYS_abort("Error issuing buffer"); 
    } 
} 
 
/* 
 * ======== echo ======== 
 * This function copies from the input SIO to the output SIO. You could  
 * easily replace the copy function with a signal processing algorithm.  
 */ 
Void echo() 
{ 
    unsigned short *inbuf, *outbuf; 
    Int nbytes, i; 
         
    /* Reclaim full buffer from the input stream */ 
    if ((nbytes = SIO_reclaim(inStream, (Ptr *)&inbuf, NULL)) < 0) { 
        SYS_abort("Error reclaiming full buffer from the input stream"); 
    } 
 
    /* Reclaim empty buffer from the output stream to be reused */ 
    if (SIO_reclaim(outStream, (Ptr *)&outbuf, NULL) < 0) { 
        SYS_abort("Error reclaiming empty buffer from the output stream"); 
    } 
  
    /* Do the data move. */ 
    for (i = 0; i < (nbytes / sizeof(short)); i++) { 
        outbuf[i] = inbuf[i]; 
    }      
         
    /* Issue full buffer to output stream */ 
    if (SIO_issue(outStream, outbuf, nbytes, NULL) != SYS_OK) { 
        SYS_abort("Error issuing full buffer to output stream"); 
    }            
      
    /* Issue empty buffer to input stream */ 
    if (SIO_issue(inStream, inbuf, SIO_bufsize(inStream), NULL) != SYS_OK) { 
        SYS_abort("Error issuing empty buffer to input stream"); 
    } 
}