0%

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

发烧到底追求的是什么

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

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

阅读全文 »

进来给实验室的服务器上装了个 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
阅读全文 »

本文是用英文写的,且尚未翻译成中文

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
阅读全文 »

本文是用英文写的,且尚未翻译成中文

$\require{mathtools}$

  • 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)$
阅读全文 »

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

ASCII 控制符

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

阅读全文 »

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

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

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

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

阅读全文 »

这次来介绍一下 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 版本。

阅读全文 »

用 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)
阅读全文 »

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 中。

阅读全文 »