Nachdem ich mich auf dieser Site und im Meta umgesehen habe (zum Beispiel hier und hier ), gehe ich davon aus, dass diese Frage hier zum Thema gehört (aber lassen Sie es mich wissen, wenn dies nicht der Fall ist).
Ich verwende den CSR8675-Bluetooth-Chip mit ADK4.0.1 (Audio Development Kit; der Software-Anzug zum Programmieren von CSR-Audio-Chips)
(der Chip wird verwendet, um über Bluetooth eine Verbindung mit anderen Geräten herzustellen, bei diesem speziellen Problem handelt es sich jedoch nicht um Bluetooth.)
Das Beispielprogramm von CSR zeigt, wie eine direkte Verbindung zwischen Audioquelle und Senke hergestellt wird. Ich möchte jedoch eine indirekte Verbindung herstellen (um die Größe und Organisation der Puffer beim Kopieren von Audiodaten von Quelle zu Senke besser zu verstehen).
Dies ist die Änderung, die ich an ihrem Beispielcode vorgenommen habe:
/*
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
Ich habe versucht, den Codeblock /* BLOCK (1) */
mit demselben Ergebnis zu aktivieren und zu deaktivieren
Wenn ich die direkte Verbindung durch Aktivieren der Leitung aktiviere, /* PanicFalse( StreamConnect(audSrc_L, audSink_L) ); */
wird das Audio von der Quelle zur Senke ohne Probleme weitergeleitet
Wie kann ich in diesem Fall eine indirekte (verwaltete) Verbindung von Quelle und Senke einrichten? Ich ging davon aus, dass, wenn Audiodaten an der Quelle verfügbar werden, die Firmware generiert MESSAGE_MORE_DATA
und die Programmsteuerung übertragen werden sollte aud_inp_handler()
, aber dies geschieht nicht. Ich sollte darauf hinweisen, dass StreamConnect()
die Firmware beim Verbinden von Quelle und Senke, aber gewaltsames Beenden dieser Verbindung, eine MESSAGE_STREAM_DISCONNECT
Nachricht generiert , die von der aud_inp_handler()
Funktion erfasst wird , sodass die Funktion selbst ordnungsgemäß registriert wurde, um Firmware-Nachrichten zu erkennen, die dazu führen Ich glaube, dass Audio überhaupt nicht von der Audio-Hardware zum Audio-Quellpuffer kommt.
Wie kann ich hier eine indirekte (verwaltete) Verbindung von Quelle und Senke einrichten?
quelle
Antworten:
Der Code zeigt eine kontrollierte Übertragung von der Quelle zum Empfänger, aber beachten Sie, dass ich alle 100 Millisekunden künstlich oder unabhängig eine MESSAGE_MORE_DATA-Nachricht generiere.
quelle
Verwenden Sie vor dem Senden die Funktion: MessageSinkTask (Sink, task) In der Methode main () vor der ersten Nachricht. In meinem Fall hat es geholfen. Schreiben Sie, ob es Ihnen geholfen hat. In Ihrem Fall sieht es beispielsweise so aus: MessageSinkTask (audSink_L, task).
quelle