自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

junguo的专栏

我想也许可以用无聊击败无聊,无聊过后再做自己喜欢的事。

  • 博客(45)
  • 资源 (2)
  • 收藏
  • 关注

原创 gtest使用简介

TEST需要两个参数:第一个是test suite的名字,test suite代表一组相关的测试脚本,比如如上的三个Test的test suite的名字都是FactorialTest,都是针对于函数Factorial的测试;这样做的目的是为了能将测试用例分成不同的层次,当在开发过程中,你只希望针对一些特殊的用例进行测试的时候,可以通过 --gtest_filter 来选择只运行指定的用例。但在一些环境下,也是一种有效的实现方式。如上的测试用例中,考虑到负数,一些特殊的数(0,1,2,3)以奇偶数的判断。

2022-12-02 22:08:34 5579 1

原创 c++11 可变参数模板得到指定类型位置

c++11 可变参数模板得到指定类型位置

2022-06-13 20:13:18 359

原创 6. 播放音频(第六部分)

之前已经提到过,中断由azx_interrupt来处理。再来看一个寄存器:* INTSTS(Interrupt Status Register)中断状态寄存器,32位。第31位,Global Interrupt Status (GIS),全局中断状态,只要有中断,它就会被置1。第30位,Controller Interrupt Status (CIS),控制器中断状态,用来标记RIRB对应的中断,代码里看起来,并没有被用到。其它位用来标记流的中断,根据流的数量来决定要使用的位数。以上函数的目的确

2022-06-11 11:39:39 711

原创 6. 播放音频(第五部分)

这段代码其实与prepare的代码流程很相似,也是通过action_ops来完成函数内容,以下是这部分代码:这段代码中,最需要理解的是trigger的回调函数。这里涉及到一些寄存器,还是先看以下具体内容。*SSYNC(Stream Synchronization) 流的同步信号,可以用来控制多个流同时开始传送数据。每一位代表一个流,如果你要同步的流是1和3,那么可以将1和3位设置为1。然后再启动DMA引擎。当DMA引擎启动后,可以再将所有的为置为0。这也是在这段代码中看到两次调用snd_hdac

2022-06-11 11:28:10 678

原创 6. 播放音频(第四部分)

理解这段代码,理解以下几个函数。这段代码是针对stream 寄存器中控制寄存器的处理。每个stream都有自己对应的寄存器,控制寄存器位于这些寄存器的开始位置。该寄存器暂用3个字节,其中0 bit位表示SRST(Stream Reset)。SRST的用法如下。1 bit 位表示RUN(Stream Run),当它置1时,表示DMA引擎使能,可以用来传送数据,0的时候表示DMA引擎停止使用。当在Reset的时候,RUN bit位必须被清除。代码基本上就是对这些要求的实现。在了解snd_hdac_stre

2022-06-11 11:24:54 515

原创 6. 播放音频(第三部分)

在tinyalsa中,写数据之前需要调用到pcm_prepare,需要向内核发送一条SNDRV_PCM_IOCTL_PREPARE命令。来看一下,在内核中的具体实现,这段代码集中在一块,集中看一下。实际动作前的预处理,这段代码的其实就是判断当前的状态,用来确定是否可以进行prepare操作。snd_pcm_sync_stop是用来等待中断结束的处理。通过substream->ops->prepare来调用驱动中的具体动作,snd_pcm_do_reset主要是用来设置runtime中的一些状态。

2022-06-11 11:16:44 775

原创 6. 播放音频(第二部分)

内存映射,可用于用户空间与内核空间之间共享数据,也可用于进程间共享数据。以下的内容的使用方法是前者,主要意图是提高系统性能。以下简单的看看原因:比如以上的代码,用户空间希望得到substream中的软件参数,通过ioctl发送SNDRV_PCM_IOCTL_SW_PARAMS命令,会调用到以上函数。内核中时常看到的两个函数copy_from_user和copy_to_user,分别读取和写数据到用户空间。内存映射可以帮助省去这些操作,通过mmap函数映射空间后,用户空间就可以直接读取或者写入内核的数据

2022-06-11 11:10:20 898

原创 6.播放音频(第一部分)

这一章将对播放音频的具体内容做讲解。我的想法是按照tinyalsa中的例子作为讲解的范本,因为tinyalsa足够简单,很多时候都忽略了它的细节。趁着这个机会再整理一下tinyalsa的内容。我使用的tinyalsa从https://github.com/tinyalsa/tinyalsa下载,从examples/writei.c开始。其中函数read_file从指定的文件中读取pcm数据到frames。这个函数里通过pcm_open打开设备,后面通过pcm_writei去写数据。这里先注意一下

2022-06-11 10:59:15 1700 1

原创 5. 打开设备(第三部分)

这个函数的主要作用是为pcm_hw_constraints进行初始化的操作。找一个例子,看看rule的具体实现:还以声道数为例子,来看看snd_pcm_hw_rule_div做了什么:针对例子,a 可以理解为帧bit数,b就是采样bit数,而c就是要返回的声道的区间值。代码里的细节,自行理解吧,算不上难。snd_interval_refine将新值赋予对应的参数。关于snd_pcm_hw_constraints的使用,是一个比较好玩的事情,这里索性一起看了吧。参数由用户空间通过ioctl传入:

2022-06-11 00:58:41 676

原创 5. 打开设备(第二部分)

名字类型作用举例trigger_mastersnd_pcm_substream指向所属的substream对象trigger_tstamptimespec64当音频开始,暂停,停止的时候都会记录时间trigger_tstamp_latchedbool是否要从底层的硬件得到时间overrangeint录制过程中,ADC转换超出范围的次数好像没几个硬件支持该功能avail_maxsnd_pcm_uframes_t记录avail的最大值返回给用户空间的状态有该值,不是太明白有什么用hw_ptr_basesnd_p

2022-06-11 00:49:04 743

原创 5.打开设备(第一部分)

在文件相关的章节中,已经介绍过打开文件的过程。但还没介绍完,这一章将继续这个话题,具体看看还有哪些操作

2022-06-11 00:35:29 1244

原创 4.hda设备中的pcm文件 (第七部分)

接着上节的内容,现在来看看构建pcm的过程。

2022-06-09 10:46:13 442 1

原创 4. hda设备中的pcm文件 (第六部分)

hda_codec对象构建成功后,并没有直接为它构建pcm文件,而是放到codec的驱动中去完成。这样做的目的,可能是为了能方便的替换不同的驱动程序,就可以少一些在代码中的硬编码。

2022-06-09 10:38:41 671

原创 4. hda设备中的pcm文件 (第五部分)

理解Codec的概念后,接着看构建Codec的代码。在azx_probe_continue的代码中,调用了azx_probe_codecs。

2022-06-09 10:16:40 341

原创 4. hda设备中的pcm文件(第四部分)

之前介绍过,codec支持一定数量的命令,在每个帧周期中SDO中的前40bit都会保留下来作为发送给codec的命令,而SDI中也保留了36bit作为codec对命令的响应。这一切都需要controller的参与,命令是由软件以DMA的方式传到controller。我们在之前也看到了帮hdac_bus中分配了DMA内存rb。这一小节,我们具体看看这一部分的内容。CORB(Command Outbound Ring Buffer)用来保存发送到codec的命令。CORB是分配在系统内存上(DMA类型的),当有

2022-06-09 10:09:32 541

原创 4. hda设备中的pcm文件 (第三部分)

回顾一下azx_create中最后部分的一行代码:INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);初始化了一个延时work。

2022-06-07 20:37:21 972

原创 4. hda设备中的pcm文件(第二部分)

上一小节,我们看了硬件的简图,现在要看它们如何被组织成软件视图。snd_card的框架简图基本就是一个软件的视图。下面我们去了解它们的组织过程,以及各个模块的作用。这部分涉及到代码,都在 sound/pci/hda和sound/hda下。之所以有两个目录,是因为hda其实也可以连接到其它总线上。在pc上一般都是用pci总线来连接的,我们也以这部分代码来展开。我们首先看hda_intel.c中的代码,虽说命名是intel,其实其它厂商的实现也在这儿,源于hda是统一标准,大部分的接口其实是通用的。但是文不尽意

2022-06-07 17:17:50 844

原创 4. hda设备中的pcm文件(第一部分)

这节开始介绍hda中如何组织pcm文件,从理解hda结构开始。之前介绍的内容,基本属于框架结构的内容,并不涉及硬件。从这里开始会介绍一些硬件相关的内容,但基本限于对流程有影响的部分,更详细的内容到intel网站下载High Definition Audio Specification。 ...

2022-06-07 17:05:00 755

原创 3. alsa中的文件(第三部分)

在pcm 文件结构简图中,可以看到与pcm相关的一些结构snd_pcm、snd_pcm_str、snd_pcm_substream。以下将去整理这部分的内容,看看它们是如何生成,怎么去使用的。如果把alsa理解为一个框架(主要是sound/core下的代码),如简图中所表示的一样,其实有一个整体的模型在哪儿,驱动开发者需要构建这个模型。而框架的另一个功能就是提供构建模型的工具,其实就是一些导出函数。snd_pcm_new就是这么一个函数:这里的参数snd_card,我们后面再展开。id和device其

2022-06-07 15:30:27 518

原创 3. alsa中的文件(第二部分)

我们先辨别两个函数:snd_register_device 与snd_device_register。snd_register_device在前面已经介绍过了,负责保存snd_minor对象。snd_device_register其实里也是为这个目的存在的,最后它会调用到snd_register_device。直接调用snd_register_device有以下一些函数:snd_pcm_dev_register注册pcm设备snd_ctl_dev_register注册control设备snd_rawmidi

2022-06-07 15:17:53 434

原创 3. alsa中的文件(第一部分)

这里以pcm文件在hda(High Definition Audio architecture)协议中的实现给出一个简图。选择hda的原因是intel给出的文档比较详细,而且是公开的。而其它一些硬件,没办法得到说明书,有代码也很难理解其中的一些内容。 ...

2022-06-07 15:11:34 852

原创 2. 关于文件(第三部分)

先来整理一下打开文件的基本过程: 以上是打开文件时候需要用到的函数的基本调用流程,从系统调用开始,这些函数集中在fs/open.c 和 fs/namei.c中。

2022-06-06 23:03:38 361

原创 2. 关于文件(第二部分)

之前提到过,音频相关的文件保存在/dev/snd目录下。dev 目录是基于ramfs文件系统构建的,是一个纯内存的文件系统。它的实现与磁盘文件系统比起来并不完全相同,不过会更简单一些。ramfs的代码在fs/ramfs目录下。而具体构建工作在driver/base/devtmpfs.c中完成,另外它提供了一些结口去生成子目录文件等。以上是devtmpfs.c中的代码,在系统启动过程中,会被调用到它负责文件系统初始化的一些工作,比如通过vfs_kern_mou...

2022-06-06 22:49:39 324

原创 2. 关于文件 (第一部分)

文件系统也是一个复杂的话题,这部分的内容是希望能勾勒出一个简单的模型,便于理解在alsa中碰到的文件相关的内容。

2022-06-06 22:39:37 292

原创 1. 从文件开始

Linux设计哲学之,一切皆是文件。感觉上这个论点更多的是针对驱动来说的,从使用者的角度来说,大多的驱动程序的使用与操作文件的方式类似,也就是使用open,read,write,ioctl这些通用的文件操作接口来操作驱动。而对于驱动开发者来说,就需要按照文件的方式来组织驱动接口,以文件的形式来呈现驱动程序。以下我们来具体看看ALSA所呈现的形式......

2022-06-06 22:18:13 480

原创 理解binder--内核层.pdf

csdn不支持doc,pdf等格式直接上传。所以放在github上。https://github.com/youjunguo/android-binder/blob/master/%E7%90%86%E8%A7%A3binder--%E5%86%85%E6%A0%B8%E5%B1%82.pdf感兴趣的话,可以看看。...

2019-11-15 20:03:13 169

原创 TREE RCU实现之三 —— 定期调用

上一节,介绍过了RCU实现中用到的主要函数。不过还需要定期的运行这些函数,整个机制才完整。       RCU的实现是通过在update_process_times() 中调用rcu_check_callbacks()来达到这个目的的。每个CPU都会定期的调用update_process_times()。rcu_check_callbacks()会去检查当前的RCU机制中是否有需要处理的内容,

2012-12-07 11:17:52 10201

原创 TREE RCU实现之二 —— 主干函数

RCU的实现集中在以下几个步骤:         1, 调用call_rcu,将回调函数增加到列表。         2,   开始一个宽限期。         3,   每个CPU报告自己的状态,直到最后一个CPU,结束一个宽限期。         4, 宽限期结束,每个CPU处理自己的回调函数。call_rcu的实现  static void__call_rcu(st

2012-12-06 18:36:50 8723

原创 TREE RCU实现之一 —— 数据结构

代码分布        在分析代码之前, 先看看代码的分布情况。RCU实现的代码包含在下列一些文件中,此处用到的是linux 3.6.4的代码。                RCU实现的头文件,所有使用RCU的代码都需要包含它                           包含rcupdate.h中没有包含的函数声明。

2012-12-05 02:36:29 12349 3

原创 RCU机制

简介        RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用。RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作。这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁)。RCU适用于需要频繁的读取数据,而相应修

2012-12-02 01:33:55 31703 2

原创 STL中迭代器的实现

 STL中迭代器的实现junguo           最近在看候捷先生的《STL源码剖析》,侯先生写的挺好的。但我读起来总感觉有些拗,理解起来有些费劲,可能他看问题的观点和我不一样造成的。开始的时候总是不太理解,后来理顺了自己的思路,发现有些东西其实并不难。在此把我对迭代器的理解整理一下,也是帮助自己消化一下,因为我发现不动手,很多东西容易遗忘。      文章里提供的一些例子程序是在D

2006-04-21 01:11:00 18779 5

原创 乱砍设计模式之十一

剩余的模式 junguo     FACADE(外观)模式:是为子系统中的一组接口提供一个一致的界面。该模式理解起来还是比较容易的,举个例子: class Eye{public: Draw(){}};class Mouse{public: Draw(){}};class Nose{public: Draw(){}};     我们

2006-04-17 20:18:00 7129 11

原创 乱砍设计模式之十

COMMAND 模式——诸葛亮造木牛流马 junguo     Command模式,中文名称是命令模式。该模式的目的是将不同的请求封装成不同的对象,这样可以用来做请求队列,请求日志,以及撤销的操作。该模式的核心是把请求封装成对象,这里的请求有些不好理解,我们还是看完例子后再说这个。先看例子。      这次没找到太好的例子,只好把木牛流马改造一下来说明我们的例子。《三国演义》上介绍诸葛亮造过这样的

2006-04-17 20:16:00 6255 6

原创 乱砍设计模式之八

BRIDGE模式 —— 所谓伊人,在水一方 junguo     Bridge模式的中文名称是桥接模式,该模式的目的是将抽象部分和它的实现部分分离,使它们都可以独立的变化。继续以例子来完成对该模式的学习。     蒹葭苍苍,白露为霜。所谓伊人,在水一方。      溯洄从之,道阻且长。溯游从之,宛在水中央。           蒹葭凄凄,白露未晞。所谓伊人,在水之湄。      溯洄从之,道阻且济

2006-04-13 23:06:00 6580 1

原创 抽象工厂的例子

抽象工厂没有讲明白,这里填加一个比较完整的例子.我觉得明白了抽象工厂目标是通过一个抽象工厂的子类来建立一系列同一性质的产品这点,就理解该模式了.#include #include using namespace std;class General{public: virtual void Assault() = 0;};class GirlGeneral : public Genera

2006-04-12 21:55:00 6769 3

原创 乱砍设计模式之七

VISITOR模式 —— 齐天大圣闹天宫 junguo     Visitor模式的中文名称是访问者模式,该模式的目的是提供一个类来操作其它类型中的对象结构中的元素(也就是专门帮助其它类来实现原本属于它的函数)。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。是不是不明白这段话的意思?没关系,还是通过例子来理解该模式。我们先来简述一下例子。      呵呵,好不容易想到这么个土的掉渣

2006-04-12 20:37:00 6368 4

原创 乱砍设计模式之六

OBSERVER 及 ITERATOR 模式 —— 知我者谓我心忧,不知我者谓我何求 junguo     Observer模式的中文译名是观察者模式,定义是:定义对象间一种一对多的关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。COM中的连接点事实上就是一种观察者模式,COM中的连接点主要是为过程化语言提供的,如果我们使用C++调用COM组件,那么我们可以直接利用回调函

2006-04-10 22:29:00 6552 6

原创 乱砍设计模式之五

FACTORY 与 ABSTRACT FACTORY模式 —— 号令秦姬驱赵女,艳李秾桃临战场 junguo     这一次,将集中讲一下创建型模式,主要以Factory和Abstract Factory模式为主。按上次的惯例,还是以例子开始。这次的例子仍以战场和美女为例,呵呵,和战场及美女死磕上了。采用这样的例子,只是想帮助大家更好的记忆,我最简化自己的例子,以帮助大家认识模式之形。写完这个系列

2006-04-09 04:45:00 8377 10

原创 乱砍设计模式之四

COMPOSITE与BUILDER模式 —— 忠义堂石碣受天文 梁山泊英雄排座次junguo     Composite模式的中文名字是组合模式,该模式的目的是使单个对象和它的对象组合(一般是数组或者链表的结构)拥有统一的操作方式,这样可以简化客户的使用。我们还是通过具体的例子来理解该模式。还是先来一段例子背景介绍:      话说,宋江带人攻陷东平东昌两郡,收降了双枪将董平和没羽箭张清,而后皇甫

2006-04-08 02:11:00 7494 6

原创 乱砍设计模式之三

DECORATOR模式———小轩窗,正梳妆junguo    DECORATOR中文的意思是装饰,该模式的动机是帮助对象动态的添加一些功能。它强调是为对象而不是为类添加功能。为类添加功能最有效的方式是通过继承来实现,但继承的缺点是不够灵活。下面我们还是通过例子来理解该模式。     十年生死两茫茫,不思量,自难忘。     千里孤坟,无处话凄凉。     纵使相逢应不识,尘满面,鬓如霜。     

2006-04-06 00:59:00 7997 9

Solutions Manual for Digital Signal Processing using Matlab - Second Edition

Solutions Manual for Digital Signal Processing using Matlab - Second Edition

2018-08-28

Real-Time Digital Signal Processing

Combines both the DSP principles and real-timeimplementations and applications, and now updated with the neweZdsp USB Stick, which is very low cost, portable and widelyemployed at many DSP labs.

2018-08-15

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除