Después de mirar alrededor de este sitio y el meta (por ejemplo, aquí y aquí ), supongo que esta pregunta es sobre el tema aquí (pero avíseme si no es así)
Estoy usando el chip Bluetooth CSR8675 con ADK4.0.1 (Kit de desarrollo de audio; el traje de software para programar chips de audio CSR)
(el chip se usará para conectarse con otros dispositivos usando bluetooth, pero este problema en particular no se trata de bluetooth)
El programa de muestra de CSR muestra cómo hacer una conexión directa entre la fuente de audio y el receptor, pero quiero hacer una conexión indirecta (para comprender mejor el tamaño y la organización de los buffers involucrados al copiar datos de audio de la fuente al receptor)
Esta es la modificación que hice a su código de muestra:
/*
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
He intentado habilitar y deshabilitar el bloque de código /* BLOCK (1) */
con el mismo resultado
Si habilito la conexión directa al habilitar la línea /* PanicFalse( StreamConnect(audSrc_L, audSink_L) ); */
, el audio de la fuente al receptor se enruta sin ningún problema
¿Cómo puedo configurar la conexión indirecta (administrada) de la fuente y el receptor en este caso? Estaba asumiendo que cuando los datos de audio estén disponibles en la fuente, el firmware debería generarse MESSAGE_MORE_DATA
y el control del programa debería transferirse aud_inp_handler()
, pero no está sucediendo. Debo señalar que cuando uso StreamConnect()
para conectar la fuente y hundirnos juntos, pero finalizo con fuerza esta conexión, el firmware genera un MESSAGE_STREAM_DISCONNECT
mensaje, que es capturado por la aud_inp_handler()
función, por lo que la función se ha registrado correctamente para detectar mensajes de firmware, lo que conduce En primer lugar, creo que el audio no proviene del hardware de audio al búfer de la fuente de audio.
¿Cómo puedo configurar la conexión indirecta (administrada) de la fuente y el receptor aquí?
fuente
Respuestas:
El código muestra una transferencia controlada desde la fuente al receptor, pero tenga en cuenta que genero artificial o independientemente un mensaje MESSAGE_MORE_DATA cada 100 milisegundos.
fuente
Antes de enviar, use la función: MessageSinkTask (Sink, task) En el método main (), antes del primer mensaje. En mi caso, ayudó. Escribe si te ayudó. Por ejemplo, en su caso se ve así: MessageSinkTask (audSink_L, tarea).
fuente