Algorithm for finding nearby places - Geohash
Geohash is a well-known algorithm for searching nearby places. Today, on the regular meeting of laboratory, I talked about the idea and C implementation of this algorithm. Now, I shared the slideshow here for reference.

Download: (Chinese)

If you have looked at it, you may found there is an C implementation for geohash. Now, the basic functions of this library have been completed. After I clean it up, I will publish it together with a NMEA parser library which do not use malloc dynamic memory allocation.
Current language: English · 其他语言: 中文 (简体)
Getting the audio waveform data of media file using ffmpeg.exe in C#
Previously, I use the NAudio library to implement this function. It needs to extract the audio track of a media file to a separate WAV file to deal with. Even with the help of RAM disk, the processing speed is still very slow.

Yesterday, I searched again for the usable audio processing library in C#. But there is still no better choice. Finally, the popular cross-platform command line tools mencoder, ffmpeg and so on came into my head. The ffmpeg seems to work because it support stdout output.

At first, I tried to output the binary stream in WAV format to stdout. But I found that in this situation, ffmpeg will write a placeholder for size information in head, and seek back to rewrite it after the whole stream is outputed (source). When the output target is the stdout stream instead of a file, this rewriting operation will fail, which causes the obtained WAV stream to have wrong head information and cannot be used.

The reason that I use WAV format is just because it is the most familiar audio format that storing raw waveform data. But after read the documentation of ffmpeg, I found that it supports a great many formats. It can output integers or floats directly, without head information. At last I selected the little endian 32-bit float format.

The complete code is as follows:

  1. using System.Diagnostics;
  2. using System.IO;
  4. // ...
  6. static void Main(string[] args)
  7. {
  8.     // ...
  9.     string path = @"E:\Media\test.mp4";
  11.     Process proc = new Process();
  12.     proc.StartInfo.FileName = @"E:\ffmpeg\ffmpeg.exe";
  13.     proc.StartInfo.Arguments = "-i \"" + path + "\" -vn -ar 44100 -ac 1 -f f32le -";
  14.     proc.StartInfo.CreateNoWindow = true;
  15.     proc.StartInfo.UseShellExecute = false;
  16.     proc.StartInfo.RedirectStandardOutput = true;
  17.     proc.StartInfo.RedirectStandardError = true;
  18.     proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
  19.     proc.Start();
  20.     proc.BeginErrorReadLine();
  21.     ProcessStream(proc.StandardOutput.BaseStream);
  23.     proc.WaitForExit(10000); // 10s
  24.     if (!proc.HasExited)
  25.     {
  26.         proc.Kill();
  27.         Environment.Exit(1);
  28.     }
  29.     // ...
  30. }
  32. static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
  33. {
  34.     if (e.Data != null)
  35.     {
  36.         // Console.WriteLine(e.Data);
  37.         // do nothing
  38.     }
  39. }
  41. static void ProcessStream(Stream stream)
  42. {
  43.     int didread;
  44.     int offset = 0;
  45.     byte[] buffer = new byte[sizeof(Single) * (1024 + 1)];
  47.     int length, residual_length;
  49.     while ((didread = stream.Read(buffer, offset, sizeof(Single) * 1024)) != 0)
  50.     {
  51.         length = offset + didread;
  52.         residual_length = length % sizeof(Single);
  54.         if (residual_length == 0) {
  55.             ProcessBuffer(buffer, length);
  56.             offset = 0;
  57.         } else {
  58.             length -= residual_length;
  59.             ProcessBuffer(buffer, length);
  60.             Array.Copy(buffer, length, buffer, 0, residual_length);
  61.             offset = residual_length;
  62.         }
  63.     }
  64. }
  66. static void ProcessBuffer(byte[] buffer, int length)
  67. {
  68.     int index = 0;
  69.     float sample_value;
  71.     while (index < length)
  72.     {
  73.         sample_value = BitConverter.ToSingle(buffer, index);
  74.         index += sizeof(Single);
  75.         // to deal with sample_value
  76.     }
  77. }
  79. // ...
Current language: English · 其他语言: 中文 (简体)
Music Beat Tracker Demo
I wrote a realtime music beat tracker algorithm based on FPGA and ARM these days.

The prototype of this algorithm is written in M-code of MATLAB. The video below is the lighting effect demonstration using the result from MATLAB. Pay attention to select high definition or above quality when watching, or the intensity of frame may change due to compression.

At present, the computational load of this algorithm is too heavy and memory usage is too large. Moreover, it failed to achieve the expected effect. So I will try to develop a new algorithm with smaller computational complexity.

The video below is a few days earlier. It is the music beat tracker preview to the last song "True Romance" in the video above.

Current language: English · 其他语言: 中文 (简体)
Screenshot supplements to "Transform Windows 7 into Windows XP"
Several supplementary screenshots for entry Transform Windows 7 into Windows XP:


Start Menu and Taskbar


Still Explorer

Control Panel

Current language: English · 其他语言: 中文 (简体)
我的 DIY 常用器件列表
先将主要的 IC 部分整理出来了,剩余的还有二极管、BJT、MOS、开关、电位器和传感器。这些器件都是个人 DIY 时容易从淘宝上少量购买的,价格便宜且性能能满足一般要求。

点击元件型号可以直接在淘宝中搜索,默认按销量从高到低排序。点击型号右侧的 PDF 图标可以通过 Google 搜索 datasheet,用搜索引擎容易找到官方网站提供的最新的 datasheet。

IC - 电源管理

FP6291 1MHz 2.5A 升压电流模式 PWM 转换器 SOT23-6
AP2953A 3A 18V 同步整流降压转换器 SOP-8
MP2359 1.2A 24V 1.4MHz 降压转换器 SOT23-6
PT1301 0.8V 低启动电压升压 DC-DC 转换器 SOT-23-6, SOT-89-5
XR2203 1.2MHz 26V 升压 DC-DC 转换器 SOT23-5
AMS1117 1.3V(max) @ 800mA 压降, 800mA LDO SOT-223, TO-252
HT73XX 0.1V(typ) @ 40mA 压降, 静态电流 3.5uA, 低功耗 LDO SOT-89, TO-92
HT75XX 0.1V(typ) @ 1mA 压降, 最高 24V 输入电压 LDO SOT-89, TO-92
XC6206 0.7V(max) @ 100mA 压降, 200mA 小体积 LDO SOT-23, SOT-89, TO-92
MIC29302 0.6V(max) @ 3A 压降, 3A 大电流 LDO TO-220-5, TO-263-5
MIC5209 0.5V(max) @ 500mA 压降, 500mA LDO SOT-223, SOP-8, TO-263-5
隔离 DC-DC
B0505S-1W 5V 输入, 5V 输出, 1W DC-DC 隔离电源 SIP, DIP
B0505S-2W 5V 输入, 5V 输出, 2W DC-DC 隔离电源 SIP
TL431A 2.5V - 36V 电压基准, 30ppm/℃, 电流 1mA - 100mA SOT-23, TO-92
LM385-1.2 1.235V 电压基准, 30ppm/℃, 工作电流 10uA - 20mA SOT-23, TO-92, SOIC-8
LM385-2.5 2.5V 电压基准, 30ppm/℃, 工作电流 20uA - 20mA SOT-23, TO-92, SOIC-8
MC1403 2.5V 电压基准, 10ppm/℃, 输入电压 4.5V - 40V DIP-8, SOIC-8
CN3058 500mA 磷酸铁锂电池充电器 SOP-8
TP4056 1A 线性锂离子电池充电器 SOP-8, MSOP-8
TP4057 500mA 线性锂离子电池充电器 SOT-23-6

IC - 线性

LM358 0.7MHz 双运放, Vcc = 3V - 32V SOP-8, DIP-8
LM324 1.2MHz 四运放, Vcc = 3V - 32V SOP-14, DIP-14
MCP6002 1MHz RRIO CMOS 双运放, I = 100uA, Ib = 1pA(max) SOP-8, DIP-8
AD8605 10MHz 高精度低噪声 RRIO CMOS 运放, Vos = 65uA(max) SOT-23-5
AD8628 2.5MHz RRIO 斩波放大器, Vos = 1uV(typ) SOT-23-5
MAX4239 6.5MHz 斩波放大器, Vos = 0.1uV(typ) SOT-23-6, SOP-8
LM393 双比较器, Vcc = 2V - 36V SOP-8, DIP-8
LM339 四比较器, Vcc = 2V - 36V SOP-14, DIP-14
LM311 双高速比较器, Vcc = 3.5V - 30V SOP-8, DIP-8
MAX9812LEXT 20dB 固定增益单输入麦克风放大器 SC-70-6
MAX9813LEKA 20dB 固定增益双输入麦克风放大器 SOT-23-8

IC - 数据采集

CS5343 24bit, 96kHz 音频 ADC, I2S 接口 TSSOP-10
TM7705 16bit Σ-Δ ADC SOP-16, DIP-16
CS5550 应用于电子秤的两通道 24bit Σ-Δ ADC SSOP-24
CS4344 24bit, 192kHz 音频 DAC, I2S 接口 TSSOP-10
TM8211 16bit 音频 DAC SOP-8

IC - 逻辑

74HC00 四 2 输入与非门 SOP-14, DIP-14
74HC04 六反相器 SOP-14, DIP-14
74HC14 六反相施密特触发器 SOP-14, DIP-14
74HC74 双 D 触发器 SOP-14, DIP-14
74HC138 3-8 译码器 SOP-16, DIP-16
74HC595 8 位串入/串出或并出移位寄存器 SOP-16, DIP-16
74HC245 8 位总线收发器 SOP-20, DIP-20
74LVC245 8 位总线收发器, 输入输出引脚可耐压 5V SOP-20
74LVC4245 8 位总线收发器, 输入输出引脚可耐压 5V, 双路电源 SOP-24, TSSOP-24

IC - 接口

MAX3232 3V - 5.5V RS-232 收发器 SOP-16, DIP-16
PL2303HX USB to RS-232 转换器 SSOP-28
74HC4051 8 通道多路复用器, Vcc = 2V - 10V SOP-16, DIP-16
74HC4052 双 4 通道多路复用器, Vcc = 2V - 10V SOP-16, DIP-16
74HC4053 三 2 通道多路复用器, Vcc = 2V - 10V SOP-16, DIP-16


STM32F100C8T6B 中容量 24MHz MCU, 1×12bit ADC, 2×12bit DAC, 64KB Flash, 8KB SRAM LQFP-48
STM32F103C8T6 中容量 72MHz MCU, 2×12bit ADC, USB 2.0 FS, 64KB Flash, 20KB SRAM LQFP-48
STM32F103VBT6 中容量, 独立 VREF+ 引脚 72MHz MCU, 2×12bit ADC, 128KB Flash, 20KB SRAM LQFP-100
STM32F103VCT6 大容量, 独立 VREF+ 引脚 72MHz MCU, 3×12bit ADC, 2×12-bit DAC, I2S, SDIO, 256KB Flash, 48KB SRAM LQFP-100
MSP430F149 8MHz MCU, 12bit 200ksps SAR ADC, 48 GPIOs, 60KB Flash, 2KB SRAM LQFP-64, TQFP-64
MSP430F2012IPW 16MHz MCU, 10bit 200ksps SAR ADC, 10 GPIOs, 2KB Flash, 128B SRAM TSSOP-14, DIP-14

IC - 存储器

H57V2562GTR-75C 256M (16Mx16bit) SDRAM, 133MHz TSOP-54
Current language: 中文 (简体)
入手赛克 858D 热风拆焊台
买不买热风枪这个问题纠结了我两年多,因为这玩意买来后用的机会实在是太少了。业余做点东西不会选 BGA 封装的芯片,因此热风枪的用途就只剩拆元件了,还得是拆烙铁不好搞定的元件。

不过最近遇到几次需要拆 USB 插座和 LQFP 封装芯片的情况,没热风枪还真是很难弄,用烙铁拆很容易拆坏。因此决定买一个热风枪了,但毕竟用的机会还是很少,所以体积绝对不能大,这样不用的时候收到哪也省地。


第二种是这种很便宜的 8032 便携式热风枪,电机、发热芯、调节旋钮都在手柄上,光看外观就有一股浓浓的山寨气息。应该不好用,也不耐用。

第三种是有气泵的 850 气泵式热风拆焊台,这种很专业了,很多人推荐。但是这种有气泵的拆焊台的最大问题就是体积太大了,顶部还有一个提手,想在上边摞一个 936 焊台都不行。非数显的型号是 850 或 850A,数显的型号是 850+ 或 850D 等。

第四种就是我最终选择的 858 无刷风机拆焊台,风扇和发热芯在手柄中,其余控制及电源电路在机箱中。非数显的型号是 858,数显的型号是 858D。

下面这个图片中标明了尺寸,13.0cm(H)*10.0cm(W)*14.7cm(L) 的体积和前面 850 的 13.5cm(H)*18.7cm(W)*24.5cm(L) 相比小了很多。可以直接摞在 936 焊台上,很节省空间。

下面是 858 热风台和 936 焊台摆在一块时的尺寸对比。

在确定 858D 这个型号后,还要考虑买哪个牌子的。在淘宝上搜“858D”按销量排序,排在前面的有谊华、安赛、安泰信、森沃、赛克和快克这几个牌子,快克的贵出一截直接排除了,听着耳生、价格也相对低的那几个牌子看评论有反映各种小问题的。最后在安泰信和赛克中选择了赛克,安泰信的评论中有点人反映加热时味道比较大,赛克的看着是没什么问题,另外比安泰信的还稍便宜点。

EEVBlog 的 David 评测过安泰信的 858D+ 热风台,他是在 2011 年时从中国买的,机器加运费一共 82 澳元,按当时的汇率合 500 多元人民币了。大陆当时淘宝上估计最多也就卖 200 吧,咱们这买这些设备价格还是很好的。
Current language: 中文 (简体)
More entries: [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] ... [25]
« Previous page · Next page »