CSRブルーコアVMでのオーディオソースとシンク間の間接(管理)接続の作成


7

このサイトとメタ(たとえば、ここここ)を見回した後、この質問はここのトピックに関するものだと思います(そうでない場合はお知らせください)

CSR8675 BluetoothチップとADK4.0.1(オーディオ開発キット、CSRオーディオチップをプログラミングするためのソフトウェアスーツ)を
使用しています(このチップは、Bluetoothを使用して他のデバイスと接続するために使用されますが、この特定の問題はBluetoothに関するものではありません)

CSRのサンプルプログラムは、オーディオソースとシンクを直接接続する方法を示していますが、間接接続を行いたいです(ソースからシンクにオーディオデータをコピーするときに必要なバッファーのサイズと構成を理解するため)。

これは私が彼らのサンプルコードに加えた変更です:

/*
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  

/* BLOCK (1) */同じ結果 でコードのブロックを有効化と無効化の両方を試みました

ラインを有効にして直接接続を有効にすると、/* PanicFalse( StreamConnect(audSrc_L, audSink_L) ); */ソースからシンクへのオーディオは問題なくルーティングされます

この場合、ソースとシンクの間接(管理)接続をどのようにセットアップできますか?ソースでオーディオデータが利用可能になると、ファームウェアが生成さMESSAGE_MORE_DATAれ、プログラムコントロールがに転送されるはずであると想定していましたaud_inp_handler()が、実際には起こりません。StreamConnect()ソースとシンクを一緒に接続するために使用するが、この接続を強制的に終了すると、ファームウェアがMESSAGE_STREAM_DISCONNECTメッセージを生成し、aud_inp_handler()関数によってキャプチャされるため、関数自体がファームウェアメッセージを検出するために適切に登録されていることを指摘します。そもそも、オーディオがオーディオハードウェアからオーディオソースバッファに送られているのではないと信じています。

ここでソースとシンクの間接(管理)接続をどのように設定できますか?


ソースを処理して結果をレシーバーに送信する可能性がなくなった場合、タスクでソースのバイト数をチェックすることにしました。私は単純なラジオ愛好家なので、これがどれだけ正しいかわかりませんが、私の場合は問題ありません。それが役立つようにあなたにできます。
ИгорьКрючковский

システムがメッセージを生成しない場合は、メッセージを目的のインジケーターと一緒に独立してタスクに送信できるため、周期性を維持し、受信側のバイトの存在を毎回確認します。 UARTまたはオーディオソース。いくつかの種類のソースに対してメッセージが生成されない理由がまだわかりません。
ИгорьКрючковский

一部のソースはそのように設計されています。オーディオソースはメッセージを生成しません。UARTはメッセージを生成します
user17915

回答:


2

このコードは、ソースからレシーバーへの制御された転送を示していますが、100ミリ秒ごとにMESSAGE_MORE_DATAメッセージを人為的または独立して生成しています。

#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;

これはオーディオソースとオーディオシンク用ではありません
user17915

1

送信する前に、次の関数を使用します。MessageSinkTask(Sink、task)main()メソッドで、最初のメッセージの前。私の場合、それは助けになりました。それがあなたを助けたかどうか書いてください。たとえば、あなたのケースでは次のようになります:MessageSinkTask(audSink_L、task)。


1
これは、オーディオソースとシンクでは動作しません
user17915
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.