ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备

ADSP-21479EVB开发板:

产品链接:https://item.taobao.com/item.htm?id=555500952801&spm=a1z10.5-c.w4002-5192690539.11.151441a3Z16RLU

在这里插入图片描述

AD-HP530ICE仿真器:

产品链接:https://item.taobao.com/item.htm?id=38007242820&spm=a1z10.5-c.w4002-5192690539.11.59ae4901jeWaOn

软件准备

Visual DSP++5.1.2
CCES2.11.1

音频开发: 21479 AD1939 C Block-Based Talkthru 48 or 96 kHz(4 进 8 出)

这个程序,我们将会在开发板上实现 48Khz 或 96Khz 采样率的音频直通程序。原理上来 讲,手机或者 PC 的音源通过 1 分 2 音频线接入 21479 开发板的模拟输入接插件,将模拟音 频导入,通过 AD1938 进行模拟转数字,数字音频信号进入 21479 数字音频 DSP 中,不做任何处理,交给 AD1938 再进行数字转模拟,将模拟的音频信号送到对应的通道,实现多 通道输出。

硬件连接如下图:

在这里插入图片描述

在这里插入图片描述

为什么输入接 2/3 通道,输出接 2/3 通道(通道号在板子的背面的丝印),这是因为 程序就是这么写的的,我们来看看程序是怎么写的: 把工程拖入 VDSP 中,编译,运行,手机播放音源,输出到音响听到音乐,完成这个例程。

在这里插入图片描述

看看这个程序的 Readme,代码实现了 ADC 从 2/3 进,DAC 从 0/1 和 2/3 出。ADC 从 0/1 进,DAC 从 4/5 和 6/7 出。用户可以换一下输入输出接口,听一下效果。至于板子上哪个接 口是 0/1,哪个是 2/3?请看下图,红色的接插件是输入,2 个黑色的接插件是输出:

在这里插入图片描述

这个工程里,音频处理都在 DSP Audio Processing Routines 里,想要了解如何实现这种 直通,可以看里面的程序去理解。 程序里都有备注,比较容易看得懂,这里说的就是 4 进 8 出,1 左右声道进对应 12 左 右声道出,2 左右声道进对应 34 左右声道出。而 1 左右声道 IN 就是板子上的 0/1 IN,2 左右声道 IN 就是板子上的 2/3 IN。

核心代码分析

DSP

///
// //
// NAME: blockProcess_audio.c (Block-based Talkthrough) //
// DATE: 02/06/10 //
// PURPOSE: Process incoming AD1939 ADC data and prepare outgoing blocks for DAC. //
// //
// USAGE: This file contains the subroutines that float and fix the serial data, //
// and copy from the inputs to the outputs. //
// //
///

#include “ADDS_21479_EzKit.h”

// Define a structure to represent buffers for all 12 floating-point data channels of the AD1939
typedef struct{
float Rx_L1[NUM_SAMPLES];
float Rx_R1[NUM_SAMPLES];
float Rx_L2[NUM_SAMPLES];
float Rx_R2[NUM_SAMPLES];

float Tx_L1[NUM_SAMPLES];
float Tx_R1[NUM_SAMPLES];
float Tx_L2[NUM_SAMPLES];
float Tx_R2[NUM_SAMPLES];
float Tx_L3[NUM_SAMPLES];
float Tx_R3[NUM_SAMPLES];
float Tx_L4[NUM_SAMPLES];
float Tx_R4[NUM_SAMPLES];

} ad1939_float_data;

// SPORT Ping/Pong Data buffers
extern int TxBlock_A0[];
extern int TxBlock_A1[];

extern int RxBlock_A0[];
extern int RxBlock_A1[];

//Pointer to the blocks
int *rx_block_pointer[2] = {RxBlock_A0, RxBlock_A1};
int *tx_block_pointer[2] = {TxBlock_A0, TxBlock_A1};

// Structures to hold floating point data for each AD1939
ad1939_float_data fBlockA;

void process_audioBlocks(void);

// Unoptimized function to convert the incoming fixed-point data to 32-bit floating-point format.
// This function assumes that the incoming fixed point data is in 1.31 format
void floatData(float *output, int *input, unsigned int instep, unsigned int length)
{
int i;

for(i = 0; i < length; i++)
{
    output[i] = __builtin_conv_RtoF(input[instep*i]);
}

}

// Unoptimized function to convert the outgoing floating-point data to 1.31 fixed-point format.
void fixData(int *output, float *input, unsigned int outstep, unsigned int length)
{
int i;

for(i = 0; i < length; i++)
{
    output[outstep*i] = __builtin_conv_FtoR(input[i]);
}

}

// Unoptimized function to copy from one floating-point buffer to another
void memcopy(float *input, float *output, unsigned int number)
{
int i;

for(i = 0; i < number; i++)
{
    output[i] = input[i];
}

}

/
// Audio Block Processing Algorithm for 4 IN x 8 OUT Audio System

// The inputs and outputs are held in a structure for the AD1939
// fBlockA holds stereo input (AIN) channels 0-3 and stereo output (AOUT) channels 0-7

// This function copys the data without any processing as follows
// AOUT1L <- AIN1L
// AOUT1R <- AIN1R
// AOUT2L <- AIN1L
// AOUT2R <- AIN1R

// AOUT3L <- AIN2L
// AOUT3R <- AIN2R
// AOUT4L <- AIN2L
// AOUT4R <- AIN2R
/

void process_audioBlocks()
{
memcopy(fBlockA.Rx_L1, fBlockA.Tx_L1, NUM_SAMPLES);
memcopy(fBlockA.Rx_R1, fBlockA.Tx_R1, NUM_SAMPLES);
memcopy(fBlockA.Rx_L1, fBlockA.Tx_L2, NUM_SAMPLES);
memcopy(fBlockA.Rx_R1, fBlockA.Tx_R2, NUM_SAMPLES);
memcopy(fBlockA.Rx_L2, fBlockA.Tx_R3, NUM_SAMPLES);
memcopy(fBlockA.Rx_R2, fBlockA.Tx_L3, NUM_SAMPLES);
memcopy(fBlockA.Rx_L2, fBlockA.Tx_L4, NUM_SAMPLES);
memcopy(fBlockA.Rx_R2, fBlockA.Tx_R4, NUM_SAMPLES);
}

/
// This function handles the Codec data in the following 3 steps…
// 1. Converts all ADC data to 32-bit floating-point, and copies this
// from the current RX DMA buffer into fBlockA & fBlockB
// 2. Calls the audio processing function (processBlocks)
// 3. Converts all DAC to 1.31 fixed point, and copies this from
// fBlockA & fBlockB into the current TX DMA buffer
/

void handleCodecData(unsigned int blockIndex)
{
//Clear the Block Ready Semaphore
inputReady = 0;

//Set the Processing Active Semaphore before starting processing
isProcessing = 1;

// Float ADC data from AD1939
floatData(fBlockA.Rx_L1, rx_block_pointer[blockIndex]+0, NUM_RX_SLOTS, NUM_SAMPLES);
floatData(fBlockA.Rx_R1, rx_block_pointer[blockIndex]+1, NUM_RX_SLOTS, NUM_SAMPLES);
floatData(fBlockA.Rx_L2, rx_block_pointer[blockIndex]+2, NUM_RX_SLOTS, NUM_SAMPLES);
floatData(fBlockA.Rx_R2, rx_block_pointer[blockIndex]+3, NUM_RX_SLOTS, NUM_SAMPLES);

// Place the audio processing algorithm here. 
process_audioBlocks();

// Fix DAC data for AD1939
fixData(tx_block_pointer[blockIndex]+0, fBlockA.Tx_L1, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+1, fBlockA.Tx_R1, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+2, fBlockA.Tx_L2, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+3, fBlockA.Tx_R2, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+4, fBlockA.Tx_L3, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+5, fBlockA.Tx_R3, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+6, fBlockA.Tx_L4, NUM_TX_SLOTS, NUM_SAMPLES);
fixData(tx_block_pointer[blockIndex]+7, fBlockA.Tx_R4, NUM_TX_SLOTS, NUM_SAMPLES);


//Clear the Processing Active Semaphore after processing is complete
isProcessing = 0;

}

SPORT

///
//NAME: SPORT1_isr.c (Block-based Talkthrough)
//DATE: 02/06/10
//PURPOSE: Talkthrough framework for sending and receiving samples to the AD1939.
//
//USAGE: This file contains SPORT1 Interrupt Service Routine. Four buffers are used
// for this example: Two input buffers, and two output buffers.
///
/*
Here is the mapping between the SPORTS and the ADCs/DACs
For AD1939
ADC1 -> DSP : SPORT1A : TDM Channel 0,1
ADC2 -> DSP : SPORT1A : TDM Channel 2,3
DSP -> DAC1 : SPORT0A : TDM Channel 0,1
DSP -> DAC2 : SPORT0A : TDM Channel 2,3
DSP -> DAC3 : SPORT0A : TDM Channel 4,5
DSP -> DAC4 : SPORT0A : TDM Channel 6,7
*/

#include “ADDS_21479_EzKit.h”
#include <sru.h>

// Counter to choose which buffer to process
int buffer_cntr = 1;
// Semaphore to indicate to main that a block is ready for processing
int inputReady = 0;
// Semaphore to indicate to the isr that the processing has not completed before the
// buffer will be overwritten.
int isProcessing = 0;

//If the processing takes too long, the program will be stuck in this infinite loop.
void ProcessingTooLong(void)
{
while(1);
}

void TalkThroughISR(int sig_int)
{
int i;

if(isProcessing)
    ProcessingTooLong();

//Increment the block pointer
buffer_cntr++;
buffer_cntr %= 2;
inputReady = 1;

}

MAIN

/

#include “ADDS_21479_EzKit.h”

void main()
{

initPLL_SDRAM(); //Initialize the PLL and SDRAM controller

// Initialize DAI because the SPORT and SPI signals
// need to be routed
InitDAI();

// This function will configure the AD1939 codec on the 21479 EZ-KIT
Init1939viaSPI();

// Turn on SPORT0 TX and SPORT1 RX for Multichannel Operation
InitSPORT();

// Unmask SPORT1 RX ISR Interrupt 
interrupt(SIG_SP1,TalkThroughISR);

// Be in infinite loop and do nothing until done.
while(1)
{
	if(inputReady)
		handleCodecData(buffer_cntr);
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/561245.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【leetcode面试经典150题】64. 删除排序链表中的重复元素 II(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

4.6 CORS 支持跨域

CORS (Cross-Origin Resource Sharing &#xff09;是由 W3C 制定的一种跨域资源共享技术标准&#xff0c;其目的就是为了解决前端的跨域请求。在 Java EE 开发中&#xff0c;最常见的前端跨域请求解决方案是 JSONP &#xff0c;但JSONP 只支持 GET 请求&#xff0c;这是 个很大…

毅速:一文说清金属3D打印与传统制造的优劣势

在制造业的演进历程中&#xff0c;传统制造与金属3D打印技术分别代表着不同生产方式。二者各具特色&#xff0c;各有优势&#xff0c;但也存在着明显的差异。毅速为您深入剖析这两种制造方式的核心特点&#xff0c;揭示它们在不同应用场景中的优劣&#xff0c;以期为制造业的未…

二维码门楼牌管理应用平台建设:核实与审核的关键作用

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、核实与审核在二维码门楼牌管理中的应用三、核实与审核的重要性四、优化建议 前言 随着信息技术的快速发展&#xff0c;二维码门楼牌管理应用平台在社区管理中发挥着越来越重要的作用。本文将深入探讨该平台建设过程中…

二维图像的双线性插值

1. 原理 见下图,假设原图为单通道的灰度图,想求图像中某点Q(x,y)的灰度值。 2. 代码实现 #include <iostream> #include <stdio.h> #include <stdint.h> #include <string> #include<opencv2/opencv.hpp> #include<opencv2/core.hpp>…

黑马程序员Linux简单入门学习笔记

Linux介绍 内核提供系统最核心的功能&#xff0c;如: 调度CPU、调度内存、调度文件系统、调度网络通讯、调度等系统级应用程序&#xff0c;可以理解为出厂自带程序&#xff0c;可供用户快速上手操作系统&#xff0c;如:文件管理器、任务管理器、图片查看、音乐播放等 目录结构 …

专题【二分查找】刷题日记

题目列表 4. 寻找两个正序数组的中位数 33. 搜索旋转排序数组 34. 在排序数组中查找元素的第一个和最后一个位置 35. 搜索插入位置 69. x 的平方根 167. 两数之和 II - 输入有序数组 209. 长度最小的子数组 222. 完全二叉树的节点个数 287. 寻找重复数 2023.04.14 4. 寻找两…

列表控件列表表格树

QListWidget QListWidget 是 Qt 框架中的一个部件&#xff0c;用于在图形用户界面中显示一个列表。这个列表可以包含文本项、图标或者其他自定义的部件。它非常适合用于呈现一系列可选择的元素。 基本属性和设置 NoSelection&#xff1a;不允许选择。用户无法选择任何项。 S…

项目风险管理

风险&#xff0c;简单来说&#xff0c;就是在特定环境下、特定时间段内&#xff0c;某种损失发生的可能性。它是客观存在的&#xff0c;不以人的意志为转移&#xff0c;具有损失性、不确定性、普遍性、社会性等特点。风险的特点可以用几个“不知道”来概括&#xff1a;不知道什…

suse15 系统分区信息损坏修复案例一则

关键词 suse linux、系统分区fdisk、分区类型testdisk、grub2、bios There are many things that can not be broken&#xff01; 如果觉得本文对你有帮助&#xff0c;欢迎点赞、收藏、评论&#xff01; 一、问题现象 业务反馈一台suse服务器&#xff0c;因错误执行了fdisk分区…

【Hadoop3.3.6全分布式环境搭建】

说明: 完成Hadoop全分布式环境搭建,需准备至少3台虚拟机(master slave01 slave02)环境: VMWare + Centos7 + JDK1.8+ Hadoop3.3.6主机规划: 主节点:master从节点:slave01 , slave02 一、准备工作 1、所有主机安装jdk 上传jdk-8u171-linux-x64.tar.gz到/root目录下,然后…

OJ:数字三角形(搜索)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;每日一练 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f337;1.问题描述&#xff1a; ⛳️题目描述&#xff1a; 示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路…

声明式 GUI 工具包:响应式、跨平台、多语言 | 开源日报 No.230

slint-ui/slint Stars: 14.5k License: NOASSERTION slint 是一个声明式的 GUI 工具包&#xff0c;用于为 Rust、C 或 JavaScript 应用程序构建原生用户界面。 可扩展性&#xff1a;支持响应式 UI 设计&#xff0c;跨操作系统和处理器架构的跨平台使用&#xff0c;并支持多种…

Linux 服务器硬件及RAID配置实战

服务器详解 服务器分类 可以分为&#xff1a;塔式服务器、机架服务器、刀片服务器、机柜服务器等。 其中以机架式居多 服务器架构 服务器品牌&#xff1a; 戴尔、AMD、英特尔、惠普、华为、华3&#xff08;H3C&#xff09;、联想、浪潮、长城 服务器规格&#xff1a; 规格…

*Linux系统的进程和计划任务管理

目录 一、查看进程 1、程序和进程的关系 *2、ps查看静态进程信息 1&#xff09;ps aux 2&#xff09;ps -elf *3、top查看动态进程信息 4、pgrep查看进程信息 5、pstree查看进程树 二、控制进程 1、进程启动方式 2、进程的前后台调度 3、终止进程的运行 三、计划任…

SQLite R*Tree 模块(三十三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite FTS3 和 FTS4 扩展(三十二) 下一篇:SQLite轻量级会话扩展&#xff08;三十四&#xff09; 1. 概述 R-Tree 是一个特殊的 专为执行范围查询而设计的索引。R-树最常见的是 用于地理空间系统&#xff0c;其中…

[论文阅读链接]

CVPR2023&#xff1a;Learning Human-to-Robot Handovers from Point Clouds http://t.csdnimg.cn/OfSnShttp://t.csdnimg.cn/OfSnS仿真工具&#xff1a;dm_control: Software and Tasks for Continuous Control dm_control 翻译: Software and Tasks for Continuous Control…

Idea中使用Git详细教学

目录 一、配置 Git 二、创建项目远程仓库 三、初始化本地仓库 方法一&#xff1a; 方法二&#xff1a; 四、连接远程仓库 五、提交与拉取到本地仓库 六、推送到远程仓库 七、克隆远程仓库到本地 方法一&#xff1a; 方法二&#xff1a; 八、Git分支操作 一、配置 G…

嵌入式学习57-ARM7(字符设备驱动框架led)

知识零碎&#xff1a; kernel 内核 printk 内核打印 cat /proc/devices mknod ? 查看指令 gcc -oapp hello.c 字符设备驱动流程 字符设备程序运行流程 gcc中-c和-o是编译时可选的参数 -c …

使用python-can和cantools实现arxml报文解析、发送和接收的完整指南

文章目录 背景一、硬件支持二、环境准备1、python解释器安装2、python库安装 三、 收发案例四、 方法拓展1、canoe硬件调用2、回调函数介绍 结论 背景 在汽车行业中&#xff0c;CAN (Controller Area Network) 总线是用于车辆内部通信的关键技术。arxml文件是一种用于描述CAN消…