0%

最近买了一些新的耳机,但是买完总感觉自己被收智商税了,于是就查查查了好多资料。这篇文章介绍我理解下音频发烧友的一些词汇是什么意思,如果你不烧耳机音响,但是想了解这个群体的,这个文章也能作为一个入门参考~Hifi领域有很多词汇我也没懂的,我也写在文章里了,如果有老烧路过请指教一二。我尝试用我学过的知识来客观解释音频领域的知识,我没上过信号处理,相关课程只上过自动控制和离散控制。

发烧到底追求的是什么

刚好今天有看到一个Youtube视频讲到,为什么音乐人并不care那些高端的音频设备。视频内容本身的观点是:一方面音乐人更关注的是音乐本身能不能打动人,另一方面是音乐人很多也没有那么多闲钱哈哈哈。以及底下的评论有很多人说自己是pro musician,然后疯狂喷audiophile追求的东西是虚无飘渺的。我承认烧音频领域有很多玄学都是脑放(脑补出来的),但是做耳机解码之类的厂家也是有很多pro audo engineer,不能否认这里面也是有很多技术门道的。根据这一帮自称pro musician的发言,我估计他们也没有多牛,他们的观点也有幸存者偏差在里面,并且本身不同级别不同类型的音乐也有不同的需求,因此这些评论也就看看就好。不过有一点我是同意的,听音乐最重要的还是音乐本身,对音质的追求不应放于对音乐本身的追求之上。

再打个比方,对音质的追求和对画质的追求其实是相似的,好的(照片)画质能让我们看清楚世界更多的细节,好的音质能让我们更真切地感受到被乐器包围的感觉。音频处理和视频处理也有很多相似的地方,因为他们都经常被看作信号来处理,后文我也会经常拿画质来打比方。

Read more »

进来给实验室的服务器上装了个Minecraft服务器,给大家闲来无事上来种种菜,顺便体验一下新版本的特性。之前最高只玩过1.8,现在虽然更新到1.16了,但是听说很多Mod都还是只支持到1.12,所以就搭了1.12的服务器。基岩版的MC(Win10自带的那个)虽然性能很好,但是由于不购买就没法玩,所以考虑到大家肯定最开始都不想买,以及那个开服好像很麻烦,就还是搭了Java的服务器。

一分钟上手Minecraft开服

以前玩Minecraft的时候都觉得开服务器好麻烦,要知道各种各样的配置方法,因此很佩服服主管理这些东西。直到有一天我搜到了这个:docker-minecraft-server,瞬间感觉一键开服不是梦了!这个repo把Minecraft的服务器版本以及Bukkit/Spigot服务器端Mod框架(可以理解成服务器上的Forge)都嵌进去了,简直不要太方便。数据也是从host的硬盘里mount进去的,因此如果你的服务器要转移或者备份也很方便。有了这个,开服只需要一行命令(假设你服务器上有docker)

1
docker run -d -p 25565:25565 --name mc -e EULA=TRUE itzg/minecraft-server
Read more »

Selected notes from ROB 501 and ME 564.
$\{x_i\}^b_a$ denotes set $\{x_a, x_{a+1}, \ldots, x_b\}$
TODO: add Jordan Form

Algebraic Structures

Operation

  • Definition: an (binary, closed) operation $\ast$ on a set $S$ is a mapping of $S\times S\to S$
  • Commutative: $x\ast y=y\ast x,\;\forall x,y\in S$
  • Associative: $(x\ast y)\ast z=x\ast (y\ast z),\;\forall x,y,z\in S$

Group

  • Definition: a group is a pair $(\mathcal{S},\ast)$ with following axioms
    1. $\ast$ is associative on $\mathcal{S}$
    2. (Identity element) $\exists e\in \mathcal{S}\text{ s.t. }x\ast e=e\ast x=x,\;\forall x\in \mathcal{S}$
    3. (Inverse element) $\forall x\in \mathcal{S}, \exists x’ \in \mathcal{S}\text{ s.t. }x\ast x’=x’\ast x=e$
  • Abelian: a group is called abelian group if $\ast$ is also commutative
Read more »

  • This note combines content from ME 564 Linear Systems and ME 561 Discrete Digital Control
  • Please read the Algebra Basics notes first if you are not familiar with related concepts.
  • In this note, $f\in\mathbb{F}^\mathbb{G}$ stands for a function with domain in $\mathbb{G}$ and co-domain in $\mathbb{F}$, i.e. $f:\mathbb{F}\to\mathbb{G}$, $H(x)$ generally stands for Heaviside function (step function)

Transforms

Laplace Transform

  • Definition: $F(s)=\mathcal{L}\{f(t)\}(s)=\int^\infty_0 f(t)e^{-st}\mathrm{d}t$

    Note that the transform is not well defined for all functions in $\mathbb{C}^\mathbb{R}$. And the transform is only valid for $s$ in a region of convergence, which is usually separated by 0.

  • Laplace Transform is a linear map from $(\mathbb{C}^\mathbb{R}, \mathbb{C})$ to $(\mathbb{C}^\mathbb{C}, \mathbb{C})$ and it’s one-to-one.
  • Properties: (see Wikipedia or this page for full list)
    • Derivative: $f’(t) \xleftrightarrow{\mathcal{L}} sF(s)-f(0^-)$
    • Integration: $\int^t_0 f(\tau)d\tau \xleftrightarrow{\mathcal{L}} \frac{1}{s}F(s)$
    • Delay: $f(t-a)H(t-a) \xleftrightarrow{\mathcal{L}} e^{-as}F(s)$
    • Convolution: $\int^t_0 f(\tau)g(t-\tau)\mathrm{d}\tau \xleftrightarrow{\mathcal{L}} F(s)G(s)$
  • Stationary Value: $\lim\limits_{t\to 0} f(t) = \lim\limits_{s\to \infty} sF(s), \lim\limits_{t\to \infty} f(t) = \lim\limits_{s\to 0} sF(s)$
Read more »

之前碰到过很多终端工具可以显示非常好看的进度条,或者显示丰富的颜色,甚至还有的直接可以在终端通过字符绘制UI(a.k.a. TUI),我一直都很好奇是怎么做到的。之后又知道了curses这个Python库和它的一些高层封装(例如asciimatics),然后最终在Stack Overflow里面查到了这些都是通过特殊的终端控制符来实现的。本文就介绍这些终端控制符的使用方法,他们很适合用来写一个简单无依赖的TUI。如果需要更复杂和全面的TUI功能,还是最好使用封装好的库。

ASCII 控制符

在最开始接触编程的时候,如果你学的是C,那你一定很熟悉\n,这就是一个”换行“的转义字符,代表终端光标令起一行。有时你还会碰到\r,这是”回车“。“回车”这个名字来源于打字机时代,在使用打字机的时候,如果你需要新起一行,那么需要的操作是:转动滚筒把纸往外抽一行,再把字车(相当与打印机的打印头)移到最左端。这两个操作的名字分别是“换行”和“回车”。因此严格来说另起一行的字符串应该是\r\n,这也是Windows的标准,而在Unix中则简化成\n会自动执行回车。

Read more »

近来由于项目需要,接触了一下一直没去了解过的Python异步语法,发现和之前我熟悉的C#有很多不同。在深入Python的异步逻辑之后,由于Python在语法上保留了很多语言机制的细节(比如成员函数的self参数),我反而对C#的异步有了更深的了解。这里就来重新梳理一下各种并行方法的区别,以及他们在C#和Python上实现的区别。(这里只讨论单机的并行机制。)

总的来说,并行机制主要有进程(Process)、线程(Thread)和协程(Coroutine),其并行实现的开销依次递减,但是他们对每个任务的鲁棒性也是依次递减的。进程是操作系统资源分配的最小单元,线程则是能够被CPU并行处理的最小单元,而协程则是目前实现“并行”的最简单方法。一个进程中可以有多个线程,而一个线程中可以有多个协程。他们具体在特性上有以下区别

进程线程协程
独立内存堆××
独立处理器(可硬件并行)×
独立上下文×
独立栈、寄存器状态
Read more »

Cython提供了很多方法来搭建C/C++内存和Python对象间的桥梁,但是官方的教程只介绍了一些基础的方法。这篇文章就介绍一下我在各个场合学到和用到的Cython封装(多维)数组的技巧。一般而言这个桥梁会分为两部分,Python与Cython和Cython与C/C++。其中Python中的数组主要形式是listarray.arraynumpy.ndarray;Cython中的数组形式有[:,:,:]Memoryview/Buffer)和cython.view.array;C/C++的数组形式有**(指针)、vectorEigen::Vector/Matrix

本篇介绍的主要内容也来自于Cython的文档:Typed Memoryviews

Read more »

这次来介绍一下Cython中的特殊函数定义,Cython相比Python本身的特殊函数之外还增加了一些新的函数,用来满足对C特性的支持,其中有些内容还经常令人混淆。关于Python中特殊变量和特殊函数名的内容,请参考Python官方文档

def, cdefcpdef

首先最开始需要分清的便是Cython中的三种函数类型。def定义的对象(包括变量、函数、类型)都是普通的Python对象,是Python可以直接调用的,因此其参数都只能是Python类型或对象;cdef定义的对象则是C/C++层面的,可以直接用C/C++对象作为参数,因此不能被普通Python代码调用,这样减少了很多overhead因此可以提高运行效率。另外尽管cdef的函数不是Python对象,无法当作变量使用,但还是可以获取函数指针的。而cpdef则是同时兼具两方面特性,其本质是用cdef定义函数后再用def定义一个函数封装,使得在Cython中调用时可以调用高效的cdef版本,而在Python中调用的是与Python兼容的def版本。

Read more »

用Cython也用了很有一段时间了,这次就介绍一下它的最重要功能——使用Cython来封装C/C++代码。最基本的封装方法可以参见Cython文档中的相关页面:Interfacing with External C CodeUsing C++ in Cython,本文介绍主要是比较重要和常用的Cython/C++交互特性,而自定义Python拓展类(而不是封装现有C++)的一些操作可以参考官方教程

封装C++代码时,最重要的关键词就是extern,在定义函数时使用这个关键字就说明该声明是外部的,而使用cdef extern from语句就能指定声明对应的头文件。例如如果要封装函数func,对应的Cython语句是

1
2
cdef extern from "func.c":
void func(int arg)
Read more »

Python作为一门胶水语言,它与C/C++之间的兼容性(Interoperability)我认为是它相比其他动态语言脱颖而出的最大原因。Python原生支持的是与C语言的接口,Python的发行版自带有Python.h头文件,里面提供了在C中调用Python和反过来在Python中调用C的接口定义。但是C++就不一样了,虽然C++ ⇔ C ⇔ Python的通道是可行的,但是想要完整兼容C++的特性的话需要很多额外的重复代码(boilerplate)。因此相应针对Python/C++绑定的库也就应运而生了,我所了解的库主要有四个:Boost.PythonCythonpybind11SWIG。虽然网上也有不少比较三者的页面,但是我觉得都不够详细,这篇博客就介绍一下我基于使用这几个库的经验比较。

上面说到的这些库我基本都有接触过,其中用过的有pybind11和Cython,分别用在了我正在写的CGALPCL的绑定上。另外二者则是在其他库的代码中有读过(如Caffe和CGAL的官方绑定)。总的来说,Boost.Python和pybind11主要用于给现有C++代码提供Python绑定,并且不用学习新的语法;SWIG提供一个给C++代码编写多种语言绑定的框架,它本质上是一种代码生成器,基于SWIG自定义的语法;Cython则是基于Python的C/C++代码封装器,其本质也是代码生成器,但是Cython的语法是Python的超集,也就是说Python的代码可以零成本移植到Cython中。

Read more »