Tạo kết nối gián tiếp (được quản lý) giữa nguồn âm thanh và phần chìm trong CSR bluecore VM


7

Sau khi xem xung quanh trang web này và meta (ví dụ, ở đâyđây ), tôi giả sử câu hỏi này có chủ đề ở đây (nhưng hãy cho tôi biết nếu không phải vậy)

Tôi đang sử dụng chip Bluetooth CSR8675 với ADK4.0.1 (Bộ phát triển âm thanh; bộ phần mềm phù hợp để lập trình chip âm thanh CSR)
(chip sẽ được sử dụng để kết nối với các thiết bị khác bằng bluetooth, nhưng vấn đề cụ thể này không phải là về bluetooth)

Chương trình mẫu của CSR cho thấy cách thực hiện kết nối trực tiếp giữa nguồn âm thanh và phần chìm, nhưng tôi muốn thực hiện kết nối gián tiếp (để hiểu rõ hơn về kích thước và tổ chức của bộ đệm liên quan khi sao chép dữ liệu âm thanh từ nguồn sang phần chìm)

Đây là sửa đổi tôi đã thực hiện cho mã mẫu của họ:

/*
Copyright (c) 2006 - 2015 Qualcomm Technologies International, Ltd.

  An example app for routing audio through the Kalimba DSP from ADC to DAC

*/

#include <kalimba.h> 
#include <kalimba_standard_messages.h>
#include <file.h> 
#include <string.h>  
#include <panic.h>
#include <source.h>
#include <sink.h>
#include <stream.h>
#include <connection.h>
#include <micbias.h>
#include <pio.h>
#include <stdio.h>
#include <transform.h>

void PioSetPio (uint16 pPIO , bool pOnOrOff);

/* Select Amp PIO depending on board used.  If not defined, assume the CNS10001v4 board is assumed. */
#ifdef H13179V2
    #define POWER_AMP_PIO 14
#else  /* Assume CNS10001v4 */
    #define POWER_AMP_PIO 4
#endif 

/* Define the macro "BYPASS_KALIMBA" to bypass Kalimba DSP otherwise direct ADC->DAC */
/* #define BYPASS_KALIMBA */
/* Define the macro "MIC_INPUT" for microphone input otherwise line-in input */
 #define MIC_INPUT 

/* Location of DSP kap file in the file system */
static const char kal[] = "my_first_dsp_app_kalimba/my_first_dsp_app_kalimba.kap";

uint16 sampleRate = 48000; 

void start_kalimba(void);
/* void connect_streams(void); */

static TaskData aud_data_inp;
void aud_inp_handler(Task task, MessageId id, Message message);
Source audSrc_L;
Sink audSink_L;
uint16 offset_aud_inp;
uint8* dest_aud_inp;
uint16 length_aud_inp; 
uint16 srcSize;
const uint8* audSrcData_L;
uint16 length; 

#define ENABLE_MAIN_C_PRINTFx

#ifdef ENABLE_MAIN_C_PRINTF
    #define MAIN_C_MYPRINTF(x) printf x
#else
    #define MAIN_C_MYPRINTF(x) /*  */
#endif


Transform t1, t2, t3;

/* Main VM routine */
int main(void)
{
    /* Load the Kalimba */
    /* start_kalimba(); */

    aud_data_inp.handler = aud_inp_handler;

    audSrc_L = StreamAudioSource( AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A );   /* ORIGINAL */
    PanicNull(audSrc_L);
    PanicFalse( SourceConfigure(audSrc_L, STREAM_CODEC_INPUT_RATE, sampleRate) ); 
    PanicFalse( SourceConfigure(audSrc_L, STREAM_CODEC_MIC_INPUT_GAIN_ENABLE, 1) );    /* ORIGINALLY USED: 1 */
    PanicFalse(MicbiasConfigure(MIC_BIAS_0, MIC_BIAS_ENABLE, MIC_BIAS_FORCE_ON));
    PanicFalse( SourceConfigure(audSrc_L, STREAM_CODEC_INPUT_GAIN, 10) );     /* ORIGINALLY USED: 10 */

    PioSetPio(POWER_AMP_PIO, TRUE);

    audSink_L = StreamAudioSink( AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A );   /* ORIGINAL */
    PanicNull(audSink_L);
    PanicFalse( SinkConfigure(audSink_L, STREAM_CODEC_OUTPUT_RATE, sampleRate) );
    PanicFalse( SinkConfigure(audSink_L, STREAM_CODEC_OUTPUT_GAIN, 15) );     /* ORIGINALLY USED: 15 */

   #if 1
    /* BLOCK (1)   */   
    /* printf("Transconf res = 0x%x\n", TransformConfigure(t1, VM_TRANSFORM_CHUNK_CHUNK_SIZE, 1) ); */
    t1 = TransformChunk(audSrc_L, audSink_L);
    /* printf("t1 = 0x%x\n", (unsigned int)t1 ); */
    TransformConfigure(t1, VM_TRANSFORM_CHUNK_CHUNK_SIZE, 1);
    /* printf("Transconf res = 0x%x\n", TransformConfigure(t1, VM_TRANSFORM_CHUNK_CHUNK_SIZE, 1) ); */
    TransformStart( t1 );

    MessageSinkTask(audSink_L, &aud_data_inp);
    MessageSinkTask(StreamSinkFromSource(audSrc_L), &aud_data_inp);
   #endif
    /* PanicFalse( StreamConnect(audSrc_L, audSink_L) ); */


    /* Connect up the ADCs and DACS */
    /* connect_streams(); */


    /* Start the Kalimba */
   /* PanicFalse( KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0) ); */

    /* Remain in MessageLoop (handles messages) */
    MessageLoop();

    return 0;
}

void start_kalimba(void)
{
    /* Find the codec file in the file system */
    FILE_INDEX index = FileFind( FILE_ROOT, (const char *)kal, strlen(kal) );

    /* Did we find the desired file? */
    PanicFalse( index != FILE_NONE );

    /* Load the codec into Kalimba */
    PanicFalse( KalimbaLoad( index ) );
}


void PioSetPio (uint16 pPIO , bool pOnOrOff) 
{
    uint16 lPinVals = 0 ;
    uint16 lWhichPin  = (1<< pPIO) ;

    if ( pOnOrOff )    
    {
        lPinVals = lWhichPin  ;
    }
    else
    {
        lPinVals = 0x0000;/*clr the corresponding bit*/
    }

    /*(mask,bits) setting bit to a '1' sets the corresponding port as an output*/
    PioSetDir32( lWhichPin , lWhichPin );   
    /*set the value of the pin*/         
    PioSet32 ( lWhichPin , lPinVals ) ;     
}

#if 1
/* original app handler */
void aud_inp_handler(Task task, MessageId id, Message message){
   task = task;
   MAIN_C_MYPRINTF(("\nENTERED aud_inp_handler() HANDLER\n"));
   switch(id){
      case MESSAGE_MORE_DATA:
         MAIN_C_MYPRINTF(("Received MESSAGE_MORE_DATA Message in aud_inp_handler()\n"));
         srcSize = SourceSize( audSrc_L );
         MAIN_C_MYPRINTF(("srcSize = %d ( aud_inp_handler() )\n", srcSize));
         audSrcData_L = SourceMap(audSrc_L);
         if( srcSize == 0 || srcSize < 128) break;     /* srcSize == 0 -> invalid source */
         else if( srcSize == 128){
            MAIN_C_MYPRINTF(("Inside else if( srcSize == 64){\n" ));
            length = srcSize;
            offset_aud_inp = SinkClaim(audSink_L, length);
            if(offset_aud_inp == 0xFFFF) Panic(); /* Space not available; this is a memory error, should not happen */
            /* Map the sink into memory space */
            dest_aud_inp = SinkMap(audSink_L);
            (void) PanicNull(dest_aud_inp);
            /* Copy the string into the claimed space */
            memcpy(dest_aud_inp+offset_aud_inp, audSrcData_L, length);
            /* Flush the data out to the uart */
            PanicZero(SinkFlush(audSink_L, length));        /* L_Src -> kalSink(0) */
            /* Source can be dropped after sending all the data in source to the sink */
            SourceDrop(audSrc_L, srcSize);
         }
         break;

      case MESSAGE_MORE_SPACE:
         break;

      default:
         MAIN_C_MYPRINTF(("Ignored Message in aud_inp_handler()\n"));
         break;

   }
}
#endif  

Tôi đã thử cả bật và tắt khối mã /* BLOCK (1) */với cùng một kết quả

Nếu tôi kích hoạt kết nối trực tiếp bằng cách bật đường truyền /* PanicFalse( StreamConnect(audSrc_L, audSink_L) ); */thì âm thanh từ nguồn đến chìm sẽ được định tuyến mà không gặp sự cố nào

Làm cách nào tôi có thể thiết lập kết nối gián tiếp (được quản lý) nguồn và chìm trong trường hợp này? Tôi đã giả định rằng khi dữ liệu âm thanh có sẵn tại nguồn, phần sụn sẽ tạo ra MESSAGE_MORE_DATAvà điều khiển chương trình sẽ chuyển vào aud_inp_handler(), nhưng điều đó không xảy ra. Tôi nên chỉ ra rằng khi tôi sử dụng StreamConnect()để kết nối nguồn và chìm với nhau, nhưng chấm dứt mạnh mẽ kết nối này, phần sụn sẽ tạo ra một MESSAGE_STREAM_DISCONNECTthông báo, được aud_inp_handler()chức năng này nắm bắt , do đó, chính chức năng đã được đăng ký đúng cách để phát hiện các thông báo phần sụn, dẫn đến Tôi tin rằng âm thanh không đến từ phần cứng âm thanh đến bộ đệm nguồn âm thanh ở nơi đầu tiên.

Làm cách nào tôi có thể thiết lập kết nối gián tiếp (được quản lý) nguồn và chìm ở đây?


Tôi quyết định rằng nó đã kiểm tra số byte của nguồn, trong tác vụ, nếu không còn khả năng xử lý nguồn và gửi kết quả cho người nhận. Tôi không biết điều này đúng bao nhiêu, vì tôi là một người yêu radio đơn giản, nhưng nó hoạt động trong trường hợp của tôi. Có thể cho bạn như nó giúp.
Игорь Крючковский

Tôi đang nói về thực tế là nếu hệ thống không tạo ra các thông báo, thì chúng có thể được gửi độc lập, với chỉ báo mong muốn, đến nhiệm vụ, do đó duy trì tính tuần hoàn, kiểm tra mỗi lần có sự hiện diện của byte trong máy thu, bất kể Nguồn UART hoặc Audio. Tôi vẫn không hiểu tại sao tin nhắn không được tạo cho một số loại nguồn.
Игорь Крючковский

Một số nguồn được thiết kế theo cách đó. Nguồn âm thanh không tạo ra tin nhắn. UART tạo tin nhắn
user17915

Câu trả lời:


2

Mã này cho thấy việc chuyển được kiểm soát từ nguồn sang người nhận, nhưng lưu ý rằng tôi tạo một cách giả tạo hoặc độc lập một thông báo MESSAGE_MORE_DATA cứ sau 100 mili giây.

#include <panic.h>
#include <stdio.h>
#include <stream.h>
#include <pio.h>
#include <source.h>
#include <string.h>
#include <sink.h>
#include <csrtypes.h>
#include <connection.h>
#include <message.h>

#define VM_UART_(RATE)        (uint16)((RATE*0.004096)+0.5)
#define VM_UART_RATE_1K2       0x0005
#define VM_UART_RATE_1K2       0x0005
#define VM_UART_RATE_2K4       0x000a
#define VM_UART_RATE_4K8       0x0014
#define VM_UART_RATE_76K8      0x013b
#define VM_UART_RATE_1843K2    0x1d7e
#define VM_UART_RATE_2764K8    0x2c3d

#define LED1     0x01       /* bit 1 */
#define DELAY1   200        /* ms */

#define LED2     0x02       /* bit 2 */
#define DELAY2   100        /* ms */

static void led_controller1( Task t, MessageId id, Message payload )
{
        PioSet( LED1, (PioGet() ^ LED1) );
        MessageSendLater( t, 0, 0, DELAY1 );
}

static void led_controller2( Task t, MessageId id, Message payload )
{    
    Source source= StreamUartSource();
    uint16 length = SourceSize (source) ;
     if(MESSAGE_MORE_DATA==id )
     {
        char *string;
        uint16 offset;
        uint8 *dest;
        Sink sink=StreamUartSink();
        PanicNull(sink);
        string=(char *)SourceMap(source);
        /* Claim space in the sink, getting the offset to it */
        offset = SinkClaim(sink, length);
        if(offset == 0xFFFF) Panic(); /* Space not available */
        /* Map the sink into memory space */
         dest = SinkMap(sink);
        (void) PanicNull(dest);
        /* Copy the string into the claimed space */
        memcpy(dest+offset,SourceMap (source), length);
        /* Flush the data out to the uart */
        PanicZero(SinkFlush(sink, length));
        SourceDrop (source, length);
    }
    PioSet( LED2, (PioGet() ^ LED2) );
    MessageSendLater( t, MESSAGE_MORE_DATA, 0, DELAY2 );
}
static TaskData taskSPP1 ={led_controller1};
static TaskData taskSPP2 = {led_controller2};

int main(void)
{
    PioSetDir(0xFF, 0xFF);         /* Set all PIO to be output */
    PioSet(0xFF, 0);               /* Set all PIO off (0) */

    MessageSend( &taskSPP1,  0 , 0 );
    MessageSend( &taskSPP2,  MESSAGE_MORE_DATA , 0 );  

    MessageLoop();

    return 0;

đây không phải là nguồn âm thanh và âm thanh chìm
user17915

1

Trước khi gửi, sử dụng chức năng: MessageSinkTask (Chìm, tác vụ) Trong phương thức main (), trước tin nhắn đầu tiên. Trong trường hợp của tôi, nó đã giúp. Viết nếu nó giúp bạn. Ví dụ: trong trường hợp của bạn, nó trông như thế này: MessageSinkTask (audSink_L, task).


1
điều này không hoạt động với nguồn âm thanh và chìm
dùng17915
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.