当前位置: 首页 > article >正文

内核dpc定时器

第一种方式是dpc定时器,这种方式是应用层主动拉流

KDPC                channel0AudioDpc;

KTIMER              channel0AudioTimer;

KeInitializeTimer(&devext->channel0AudioTimer); //初始化定时器对象

KeInitializeDpc( &devext->channel0AudioDpc, channel0AudioDpcRoutine, devext );//初始化dpc对象,注意最后一个参数就是channel0AudioDpcRoutine中的第二个参数。

NTSTATUS DispatchProcess (IN PKSPIN  pin)
{
    PDEVICE_EXTENSION devext = (PDEVICE_EXTENSION)(KsPinGetDevice(pin)->Context);
    LARGE_INTEGER        largetime;
    largetime.QuadPart=-10 * 1000 *2;     //number of 100 ns intervals ,so here is 2ms
    KeSetTimer(&devext->channel0AudioTimer,largetime,&devext->channel0AudioDpc);

//开始DPC定时器,3个参数,第一个参数是KTIMER对象,第二个参数是时间间隔,第三个参数是dpc对象
    return STATUS_PENDING;
}

//dpc 函数

void  channel0AudioDpcRoutine(struct _KDPC* p_dpc,PVOID context,PVOID arg1,PVOID arg2)

eg: void OnDPCTimer(IN PKDPC pDPC,
IN PVOID pContext,//这就是KeInitializeDpc传入的参数
IN PVOID SysArg1,
IN PVOID SysArg2)

在需要停止的地方调用KeCancleTimer来取消定时器

第二种方式,中断函数中有中断到来时把它入队dpc,驱动往上推流

有中断时:KeInsertQueueDpc(&devext->channel0AudioDpc,NULL,NULL);

NTSTATUS DispatchProcess (IN PKSPIN  pin)
{
    return STATUS_PENDING; //此处直接返回,在dpc处理函数里向应用层写入。
}

第二种方法只能正确处理48K的声音:

总数据量:48000*2*2=192000,应用程序每次请求1920个字节,驱动中的CELL刚好也是1920,这样就每一个中断往应用层写入一次,每秒刚好有100个中断(192000/1920)。

这个时候两种方法的效果是一样的,第二种方法又不依赖系统的时钟分辨率(win10 64位中setTimer有15ms的误差)。所以处理48K的声音没有问题。

当源是44.1K时,44100*2*2=176400, 176400/1920=91.875

应用程序每次只请求1764个字节,每一个中断对应有1920个字节,这样每一个中断就会在驱动中累积156个字节而导致数据在驱动中溢出。解决这个问题只能更改驱动中的CELL刚好也是1764,但是它不是128的倍数又不满足fpga的要求。所以处理44.1K的声音是个问题。

第一种方法拉数据依赖应用程序的请求,不对应中断的个数去一对一的送数据就没这个限制。

另外,应用程序每次取声音的数据量是根据系统的声音设置而定的,系统声音设置“录制”属性中设置44100每次取1764,设置48000每次取1920。默认值是第一次安装驱动中的接口而定的。使用过程中如果信号源有改变,系统声音设置没办法同步更改,这样就会导致播放声音不正常。所以声音这一块驱动中要把44.1转为48最好,最好只有一种48K输出。


http://www.kler.cn/a/9255.html

相关文章:

  • 使用Matlab神经网络工具箱
  • Vue 中的定时刷新与自动更新实现
  • LeetCode 40-组合总数Ⅱ
  • 闯关leetcode——3206. Alternating Groups I
  • 【Python】解析 XML
  • 在双显示器环境中利用Sunshine与Moonlight实现游戏串流的同时与电脑其他任务互不干扰
  • Python 虚拟环境迁移到其他电脑
  • 2023最新8个电脑必装软件,新电脑装完好用又高效
  • 静态工具类中如何注入spring容器
  • AttributeError: module ‘torch‘ has no attribute ‘compile‘
  • HTML5 <head> 标签、HTML5 <i> 标签
  • OBCP第八章 OB运维、监控与异常处理-灾难恢复
  • 数据结构之线性表3
  • 【中级软件设计师】—操作系统考点总结篇(二)
  • 蓝桥杯嵌入式第十二届初赛题目解析
  • Baumer工业相机堡盟相机如何使用BGAPI SDK实现相机资源的正确释放(C++)
  • Redis使用教程之jedis客户端sendCommand方法的byte[]入参,防止混淆string的byte与数值byte的区别
  • 电脑误删除的文件怎么恢复
  • 从零开始学习Blazor
  • SHELL函数可课后作业
  • 使用Schrödinger Python API系列教程 -- 介绍 (一)
  • 6.S081——虚拟内存部分——xv6源码完全解析系列(2)
  • 用于语义分割模型的t-SNE可视化
  • ftp传输文件大小有限制吗 ftp文件传输工具有哪些
  • fate-serving-server增加取数逻辑并源码编译
  • vue3中tsx语法一些了解