5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)

标题: DIY发动机声音模拟器 [打印本页]

作者: 348826281    时间: 2011-3-31 18:21
标题: DIY发动机声音模拟器
试验版本,用电位器控制,以后要改成舵机信号控制。准备装到电车上,盖住电机的吱吱声,尽管我手头上连个玩具遥控车都没有。

用了ATmega8L、电阻、电容各一个,以后还要加功放。

原理:由ADC控制T/C0产生中断的速度,用T/C0给T/C1喂数据,用T/C1的PWM产生声音,反复播放一段声音(来自网游“飚车”的rpm.wav)。

还需要改进,希望能接近“极品飞车”的水平

[flash]http://www.tudou.com/v/Wj2ko_bLjFY/&rpid=45597529==.html[/media]

[ 本帖最后由 348826281 于 2011-3-31 18:24 编辑 ]
作者: 348826281    时间: 2011-3-31 18:22
原代码


//ICC-AVR application builder
// Target : M8
// Crystal: 8.0000Mhz
#include <iom8v.h>
#include <macros.h>
#include <STRING.H>
#include <stdlib.h>
int n;
unsigned int adc,tc0no;

//一段声音
__flash char sound[373]={0x89,0x96,0x95,0x94,0xA2,0xB3,0xBE,0xC6,0xC5,0xC2,0xC5,0xD8,
0xE5,0xE5,0xE7,0xE3,0xDE,0xE0,0xDF,0xDF,0xDA,0xDB,0xDC,0xDA,0xD5,0xD4,0xD3,0xD4,
0xD8,0xD4,0xD0,0xCE,0xCC,0xCF,0xD0,0xCC,0xB9,0xA8,0x9D,0x88,0x7B,0x70,0x5F,0x53,
0x50,0x4D,0x48,0x3F,0x47,0x60,0x69,0x60,0x56,0x44,0x41,0x4E,0x51,0x4D,0x4A,0x51,
0x56,0x49,0x46,0x44,0x44,0x4F,0x59,0x59,0x66,0x72,0x76,0x75,0x83,0x90,0x98,0xA2,
0xAD,0xB6,0xBB,0xB8,0xB8,0xBC,0xC0,0xC4,0xC2,0xBF,0xC1,0xD0,0xD2,0xCB,0xC6,0xCD,
0xCE,0xCB,0xC2,0xC2,0xC1,0xBB,0xAB,0xB0,0xB7,0xB9,0xA4,0xA4,0xB0,0xAC,0xAB,0xB2,
0xA7,0x9A,0x86,0x71,0x6A,0x6D,0x5A,0x41,0x34,0x31,0x25,0x11,0x08,0x06,0x08,0x0D,
0x11,0x14,0x16,0x12,0x13,0x13,0x1E,0x2F,0x32,0x33,0x40,0x47,0x3C,0x2B,0x26,0x21,
0x33,0x3F,0x3C,0x3F,0x3C,0x3F,0x57,0x66,0x5E,0x61,0x77,0x90,0x98,0x8B,0x88,0x90,
0x9A,0xA3,0xA5,0xA6,0xA7,0xAF,0xAE,0xB2,0xBC,0xC7,0xC6,0xCD,0xD3,0xDD,0xDA,0xDA,
0xDF,0xDE,0xDF,0xDC,0xD4,0xD4,0xD7,0xD3,0xD3,0xD3,0xD5,0xC8,0xB9,0xA4,0x97,0x8D,
0x75,0x65,0x61,0x66,0x61,0x50,0x44,0x3B,0x2E,0x2C,0x37,0x3A,0x41,0x49,0x44,0x38,
0x33,0x40,0x43,0x49,0x57,0x6C,0x6A,0x64,0x67,0x65,0x57,0x55,0x52,0x56,0x5E,0x64,
0x69,0x72,0x7B,0x8C,0x98,0x9A,0xAA,0xC1,0xC8,0xC7,0xC0,0xC6,0xD0,0xCE,0xCD,0xCA,
0xC9,0xC8,0xC8,0xC9,0xCD,0xCA,0xCD,0xC6,0xC9,0xCE,0xCE,0xCC,0xD0,0xD3,0xD7,0xCA,
0xBE,0xBB,0xB7,0xB1,0xA1,0x91,0x88,0x7E,0x7F,0x73,0x5E,0x50,0x35,0x31,0x3B,0x35,
0x29,0x24,0x11,0x0B,0x0B,0x0E,0x12,0x15,0x17,0x15,0x13,0x17,0x1C,0x20,0x20,0x2C,
0x3D,0x3A,0x31,0x29,0x1C,0x27,0x42,0x48,0x45,0x41,0x48,0x55,0x5E,0x6A,0x78,0x84,
0x8F,0x97,0x93,0x99,0xA5,0xA8,0xA6,0xB8,0xAD,0x9B,0xB2,0xC9,0xC8,0xC3,0xBB,0xBD,
0xC9,0xD5,0xD1,0xD1,0xD3,0xDB,0xDE,0xDA,0xD9,0xD8,0xD7,0xDA,0xD8,0xD4,0xCF,0xCA,
0xC7,0xC1,0xB4,0x9A,0x81,0x7A,0x70,0x67,0x5A,0x44,0x3A,0x35,0x28,0x18,0x0F,0x13,
0x28,0x31,0x24,0x1E,0x20,0x1E,0x30,0x3F,0x3D,0x3D,0x4D,0x52,0x4A,0x4A,0x4C,0x44,
0x49,0x53,0x52,0x52,0x5C,0x68,0x6E,0x75,0x80};

//根据电位器的数值调整播放速度
__flash char tc0start[33]={0x82,0x87,0x8C,0x91,0x95,0x99,0x9D,0xA0,0xA4,0xA7,
0xA9,0xAC,0xAF,0xB1,0xB3,0xB5,0xB7,0xB9,0xBB,0xBC,0xBE,0xC0,0xC1,0xC2,0xC4,
0xC5,0xC6,0xC7,0xC8,0xCA,0xCB,0xCC,0xCD};

void port_init(void)
{
PORTB = 0x00;
DDRB  = 0x02; //PB1 --> OC1A  output
PORTC = 0x00; //m103 output only
DDRC  = 0x00; // PC.0 ADC
PORTD = 0x00;
DDRD  = 0x00;
}
//ADC initialize
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x40; //AVcc ADC0 0100 0000
ACSR  = 0x80; //analogy comparer 1000 0000
ADCSR = 0xEF; //1110 1111  self trigger
}
#pragma interrupt_handler adc_isr:iv_ADC
void adc_isr(void)
{
adc=(unsigned int)ADCL;            //Read 8 low bits first (important)
adc|=((unsigned int)ADCH << 8); //read 2 high bits and shift into top byte
tc0no=(adc>>5);
}

//TIMER0 initialize - prescale:8
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x82; //set count
TCCR0 = 0x02; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = tc0start[tc0no]; //播放速度
    OCR1AH =0x00;
    OCR1AL = sound[n];
    n++;    //声音循环播放
     if (n-372>0)
    {
     n=0;
    }
}
//TIMER1 initialize - prescale:1
// WGM: 5) PWM fast, TOP=0xFF
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFF; //setup
TCNT1L = 0x01;
OCR1AH = 0x00;
OCR1AL = 0x80;
OCR1BH = 0x00;
OCR1BL = 0x80;
ICR1H  = 0x00;
ICR1L  = 0xFF;
TCCR1A = 0xA1; //1010 0010
TCCR1B = 0x09; //start Timer  0000 1001
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
adc_init();
timer0_init();
timer1_init();
  
MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
    n=0;tc0no=0;
init_devices();

while (1)
{
} //while(1)
} //main



有不对的地方请指出,我也是初学者,见笑了
作者: FAVE    时间: 2011-3-31 18:59
原帖由 llzzxxmmwwcc 于 2011-3-31 06:47 PM 发表
比电机声还难听
我觉得换一个音效+控制顺滑 就会很好听了
作者: lx51121    时间: 2011-3-31 20:05
有点像赛车
作者: wangfine1975    时间: 2011-3-31 20:22
真是高人,不过高速部分声音频率不够高
作者: 348826281    时间: 2011-3-31 20:30
就目前的效果来说,确实是这样。
原帖由 llzzxxmmwwcc 于 2011-3-31 18:47 发表
比电机声还难听


模拟的是一台4缸发动机在3000~8000转的声音,高转速段需要新的声音
作者: hjf310    时间: 2011-4-1 10:36
不错不错!特来顶之!:em26:
作者: 348826281    时间: 2011-5-15 12:05
对声音的控制不再用电位器,换成舵机信号了。
如果变速播放发动机声音,油门快速变化时会出现像电子琴的声音,否定这个方法。
[flash]http://www.tudou.com/v/s6VJ0yjooc4/&rpid=45597529==.html[/media]

在外国人的文章里,他们用波形叠加的方法,把每个气缸的声音按一定间隔叠加。
(, 下载次数: 67)

有文章介绍用GT-Suite软件的GT-power模块可以得到单缸声音的波形,可惜找不到那软件,只能现学FLUENT,建了个二维的直排管的模型,尾气排入一个半圆空间,计算压力
(, 下载次数: 67)
再用tecplot 360获得距离排气管口0.5m,偏移45度位置的压力波形。
(, 下载次数: 70)

试着发出声音,一点都不像发动机,但油门快速变化时能正常发声,说明波形叠加的方法可行

在上图中,压力的衰减相当快,如果安装消音器衰减更快,因此只要发动机转速不是很高,完全可以从实际的发动机连续工作的声音里截取波形。从ken block的漂移视频里截取了6个声音波形,
(, 下载次数: 74)
重写程序
[flash]http://www.tudou.com/v/7vrEEay5Jm8/&rpid=45597529==.html[/media]
听起来还是不爽。谁来指点下?????
也许找辆改装车,实地录制排气声音,会好点。宿舍外面的电子四路经常能听到改装车的声音,电子四路从电子西街至太白南路一段一直封闭,没车没人,六车道宽的柏油路是个很好的场地(西安)。
视频里用来产生舵机信号的板子,数码管中间一位不亮,电位器阻值跳动,弄的声音也跟着哆嗦,真是便宜没好货,工资一发就去买个控。


电路画的不标准,凑活看吧。声音信号可以直接输出到笔记本音箱,或者用LM386、TDA2422放大后输出到喇叭。还有个问题,小尺寸喇叭的频率下限,能否发出发动机的低频声音
(, 下载次数: 76)
熔丝配置,内部8M时钟,关闭看门狗计数器
(, 下载次数: 75)
代码 iccavr 写的不好,见笑了,对应2000~8000rpm的四缸机
原理:使用TC0和INT0测量舵机信号,用TC1按照声音采样率产生中断,叠加波形后由TC2的快速PWM发声。声音样本都是152长度,153~160的数值为中性点,当一段声音播放完就会指向这部分,不发出声音,直到再次开始播放
源代码 (, 下载次数: 140)
hex文件 (, 下载次数: 71)

[ 本帖最后由 348826281 于 2011-5-15 12:07 编辑 ]
作者: stillclouds    时间: 2011-5-15 23:16
怎么越搞越不靠普了呢?。。。。。:em15:
作者: 348826281    时间: 2011-5-19 19:58
略有进展

之前的变速率播放方案因为所谓的“电子琴声”而放弃,但那讨厌的声音同样出现在波形叠加方案中,分析后得出结论:“电子琴声”实际是声音的阶梯式跳变,不连续,所以出现那种声音。查出问题在那个自制的舵机测试机,更新的速度慢,导致声音模拟器出现怪声。修复后,变速率播放就能发出比较好的声音,在快速变化时也有较好表现。(舵机信号的50Hz频率足够了,不会导致电子琴声)

WRC版本,前进时发声,并根据油门大小变化,倒车时声音减弱且恒定(目前不能分辨是倒车还是刹车,所以倒车无声)
[flash]http://www.tudou.com/v/KwgEcNvHAsY/&rpid=45597529==.html[/media]

坦克声音版本,双向发声,攀爬用估计合适
[flash]http://www.tudou.com/v/9UzTRJI-CmM/&rpid=45597529==.html[/media]


源代码和烧录单片机用的Hex文件
(, 下载次数: 139)
作者: freedomkiller    时间: 2011-5-20 17:20
高手
作者: 流星的残点    时间: 2011-5-20 17:45
感觉不错。
作者: 348826281    时间: 2011-6-27 19:43
多样本的方案不容易实现,中间又因为“逮捕令”和“胧村正_妖刀传”停工两周(都是小鬼子的东西),总算摆平。
之前犯了个小错,定时/计数器TC0的溢出中断等级低,导致油门大小的测量出错,换成TC1就好了,一个月才想明白,笨死了。


效果请看视频,模仿的是极品飞车9里的evo,差的比较远,目前的ATmega8只能做到这效果,凑活用吧。
还需要些小调整,收油门时声音应该逐渐减慢。
还有什么要求尽管提

[flash]http://www.tudou.com/v/WcnU5WZABkI/&rpid=45597529==.html[/media]


代码和烧录用HEX文件
(, 下载次数: 133)
(, 下载次数: 85)
作者: Nokia82    时间: 2011-6-29 10:51
:em26:
作者: 逍遥枫叶    时间: 2011-6-29 11:47
高手:em26: 对代码很头疼
作者: 348826281    时间: 2011-6-30 19:36
做了些小改动,加速和减速时的声音不会过快变化,用来模仿现实情况

重新做了兰博基尼Murcielago的声音模拟器,效果一般。原始声音文件、硬件、软件都限制了效果,录像里是用耳机发声,不知道换成笔记本音箱会怎样,也许该换成更好的单片机,配上专门的声音DAC。最大的问题是小音箱不给力,也许原始的声音是衰减过的,不能轰鸣。


[flash]http://www.tudou.com/v/Mo9OeRw3sp0/&rpid=45597529==.html[/media]



原始的声音
[flash]http://www.tudou.com/v/e_-D8RSVgAc/&rpid=45597529==.html[/media]
作者: moxingcsc    时间: 2011-7-7 03:00
牛人 厉害
作者: 348826281    时间: 2011-7-7 20:59
兰博基尼Murcielago的声音模拟器 的代码,由外部中断INT0和TC1测量油门大小(代码中的width,取值范围0~125,对应脉冲宽度1.5~2ms),并在int0的中断处理中控制播放的样本,TC0控制播放速度,最后由TC2的PWM方式输出声音
(, 下载次数: 217)

现在的问题是原始声音只是11025Hz的采样率,丢失了很多细节,不像真车声音。要想用高采样率的声音必须换芯片,准备换成stm32,需要不少时间
作者: ruoshi    时间: 2011-7-7 21:29
厉害啊厉害
作者: ywwxj    时间: 2011-7-7 21:38
:em26:
作者: 博夫曼    时间: 2011-8-14 21:03
:em26: :em26: :em26: :em26: 很酷
作者: reclife    时间: 2011-8-20 22:45
:em24:  这么牛的人进行这么学术的研究和探讨, 而且还把过程和源码放上来了, 为什么看的人那么少, 高手都不愿意站出来给点意见吗? 童鞋们都是只知道看热闹去了吗,

表示愤怒, 5imx的学习气氛太差了, 顶楼主, 希望你此中翘楚。
作者: 无双    时间: 2011-9-14 20:47
楼主现在进展怎么样啊,一直在关注啊。。。能不能把全部画个电路图啊``很想给电十也装个这个东西``
作者: bananad    时间: 2011-9-14 22:09
潜了一辈子水,今天特来顶楼主,中 国太需要楼主这样肯钻的玩家了,说难听点,外国人就是赚我们的傻钱
作者: flux    时间: 2011-9-21 15:18
真NB
就是减速的声音稍有点 肉 再利落点就完美了 从此电动也可以很亢奋!
能模拟个GT500的声音吗
作者: 小小小菜鸟    时间: 2011-9-21 15:42
俺大学的时候一舍友也对发动机引擎声感兴趣
   无奈找不到声音的灵感
   一日,舍友都在午休,一哥们“唔~~~”声音低沉,悠长————是个长屁,
   该舍友豁然开朗~~
   于是晚上召集大家开卧谈会,
   跟大家说要打屁的时候跟他说声~~
   自己也拿着屁5随时准备录音
   终于功夫不负有心人,几天之后得到长达十几兆的声音源文件
   经过筛选,编辑,最后跟跑跑卡丁车融合到一起,
   得一视频,其名为---帅帅的屁

   该视频在曾经在俺宿舍风靡一时,
    卡丁车独有的引擎轰鸣声确实非同一般
   传到优酷上之后,
   发现很多人喝倒彩,
   郁闷至极,
    遂删之。。。。。。。。。。
作者: slbbs    时间: 2011-9-22 00:57
可以做个飞机俯冲/拉起的声音,状态用水银开关出控制
作者: lcp1220    时间: 2011-9-22 10:54

作者: lcp1220    时间: 2011-9-22 10:55


这个声浪不错,不知可否模仿一个出来?
作者: andnnong    时间: 2011-9-22 17:35
很精致,很有想法啊。人才人才
作者: 348826281    时间: 2011-9-22 19:38
先同情下“小小小菜鸟”的经历,很搞笑滴说


关于“slbbs”的“飞机俯冲/拉起的声音”,那实际是多普勒效应,模型和真飞机一样快时才能有相同效果,设想用GPS跟踪飞机距离操作手的距离,并改变音调,这是后话,现在飞机的声音还模拟不好。


也看过那两段视频,自认为已达到那种音质,但音量绝对赶不上,笔记本音箱顶多6W功率,没办法“轰鸣”。


一直处在停工状态,正在恶补单片机的知识,有进展随时更新
作者: 348826281    时间: 2011-12-13 23:32
更新一下。

启动声音是Ford GT 的,运转声音是camaro的,只是单声音样本。亮点是启动声
程序有点问题,不开控时会发出“达达”的声音。

[flash]http://www.tudou.com/v/XhUCNiWHqGU/&rpid=45597529==.html[/media]


芯片换成ATmega16,声音采样率翻倍到22050Hz,多声音样本方法的效果不行,所用没拍视频。多声音样本不适合RC,油门变化太快,需要寻找新的方法
作者: singcee    时间: 2011-12-21 17:19
标题: 回复 34楼 348826281 的帖子
咱俩做的东西有点相似,不过我是用单片机直接控制一个MP3解码发声的,这样声音的效果很好,不过声音的变化完全取决于声音的样本多少,也不是很理想。 还有就是中间有间隔

[flash]http://www.tudou.com/v/cAABwol1tNM/&rpid=101663317==.html[/media]

(, 下载次数: 28)


(, 下载次数: 54)
(, 下载次数: 37)




最近看了 soundracer 的声音模拟器觉得 做的很太牛了 感觉方案和你的应该类似。 准备研究一下
http://www.soundracer.se/?p=98
希望能和你交流 QQ 158-567-554

[ 本帖最后由 singcee 于 2011-12-21 17:34 编辑 ]
作者: singcee    时间: 2011-12-21 17:38
标题: 回复 34楼 348826281 的帖子
达达”的声音 有可能不是程序的问题 有可能是连接功放的电路问题
作者: 348826281    时间: 2011-12-21 18:52
是程序的问题,看门狗的使用不到位造成的,修改后就没了(放弃看门狗)

原帖由 singcee 于 2011-12-21 17:38 发表
达达”的声音 有可能不是程序的问题 有可能是连接功放的电路问题

作者: 120542121    时间: 2012-3-3 11:38
支持楼主,我也正考虑做这个,:em24:
作者: gzaboy    时间: 2012-5-18 20:21
我也在搞,已经成功了,效果非常好。用51做的。
作者: lll8    时间: 2012-5-18 20:26
高手
作者: gzaboy    时间: 2012-5-18 21:02
http://www.tudou.com/programs/view/w9JbUE5tuGo/

这个是我做的。
因为声音采样不好。出来的效果也是和采样时一样的。
只要采样好些,声音就行了。
作者: omoikanesrw    时间: 2012-5-21 17:10
原帖由 llzzxxmmwwcc 于 2011-3-31 18:47 发表
比电机声还难听

可 可能是拾音的问题!
作者: wow99    时间: 2012-7-19 10:49
还是去盗用田宫声组声效吧,这个真的非常难听。
作者: 273243103    时间: 2012-7-19 23:11
:em26: :em26:
作者: wang272754020    时间: 2012-7-21 17:01
http://v.youku.com/v_show/id_XNDI1NDQxOTYw.html
这个是我朋友做的 P51 野马 发动机的模拟声 , 换个汽车的样本,应该能有不错的效果。
大伙给点意见
作者: nansen    时间: 2012-8-11 05:52
坚决学习:em07: :em07:
作者: nansen    时间: 2012-8-12 22:55
疯狂恶补单片机的知识,我们就是要在折腾中不断进步!
希望楼主能给些最新及更详细的介绍!:loveliness:
作者: aband    时间: 2012-8-13 01:15
DIY贴必须顶
作者: zgchen    时间: 2012-8-15 19:43
不错的技术贴!!:em15:
作者: nansen    时间: 2012-8-17 00:18
标题: 你好
ATmega8L 你这个是8pu的吗?
作者: nansen    时间: 2012-8-17 00:18
希望楼主能给些最新及更详细的介绍:em00: :em00:
作者: 348826281    时间: 2012-8-19 21:39
原帖由 nansen 于 2012-8-17 00:18 发表
ATmega8L 你这个是8pu的吗?


应该是,用的是内部rc振荡器,最大只能到8MHz。
电路一直是9楼的那个。
程序在19楼,原理是波表合成(wave table)和自己瞎编的算法:
1.先对原始声音做频谱分析(我用的是Adobe Audition),确定基频的变化范围。然后选几个频率点,截取声音(用Matlab),一般多截取几个周期的波形,声音就不会太单调
2.声卡的波表合成用的是DSP,单片机没那速度,原始声音需要事先调整采样率。用Matlab把高频率的声音插值到低频率的声音时长,就是程序里开头acl1_hi[470]命名声音,那是高频的acl2_lo[386]插值到470点的声音,以此类推
3.声音准备好后,就写单片机的程序。
在过渡时,减小一个声音,增大另一个声音,就是timer0_ovf_isr(void)里的temp=((temp1*c_lo+temp2*c_hi)>>4);
从某两个声音合成跳到另两个声音合成时,使用了相位调整,而不是从头播放样本。就是int0_isr里那个多层判断的n=(n*n_reorder[n_from][0])>>6。为避免使用除法,提前算好结果存在n_reorder[7][7],是放大64后的整数,所以会需要右移6位。估计不调整相位也不会有问题

[ 本帖最后由 348826281 于 2012-8-19 21:42 编辑 ]
作者: huaerbao    时间: 2012-8-19 23:41
不错啊!!!!!!!!!!
作者: 晨曦问    时间: 2012-9-6 20:06
真的不得不佩服LZ,对这方面我是不很了解
作者: 120542121    时间: 2012-12-2 22:41
楼主,如果换成m16效果会好点吗?有没有试过?
作者: youyou19861224    时间: 2012-12-9 14:25
才华横溢          字数你妹         




欢迎光临 5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年) (http://bbs.5imx.com/) Powered by Discuz! X3.3