在 WSL 中使用 pulseaudio 播放声音

虽说微软最初发布 WSL 的时候就明确表示这是一个只针对开发者的平台,而现在的战略也只是更进一步支持服务器级别的应用,并没有支持桌面应用的计划(可是 CUDA 和 OpenCl 你总得支持吧),但我在很愉快地用它开发之余,也在很愉快地看热闹不嫌事大地企图让各种 GUI 应用跑起来. 得益于类 unix 系统上显示与音频的网络化设计,可以在 Linux 完全没有相关硬件资源的情况下通过网络方式用 Windows 上的服务器显示与播放,再加上 WSL 和 Win32 本身就是同一内核上的两个子系统,这样做相当于就是在原生 Linux 上正常使用声音与显示,只是没有高效的 unix socket 罢了.

关于 WSL 上跑 GUI 的相关文章已经相当多了,然而播放声音的却没有一篇完整的教程. 这里将介绍如何使用 pulseaudio 来让 WSL 播放声音.

继续阅读 »

Windows 10 + OS X 硬盘升级无损迁移记实

注:本篇是对我自己做系统迁移的整理并不是一篇教程,仅供参考

注2:仅可应用于 EFI 安装的 Windows,也就是说 Windows 7 以下绝对不是

注3:数据无价 谨慎操作 —— Disk Genius

前情提要

出于一些原因我的 mid 2014 11″ MacBook Air 用的是 128G 的硬盘,这显然不够我装 Windows + macOS 双系统并且各种 IDE 和 runtime 全部装上的. 光是 Visual Studio 和 XCode 就要占掉 30G – 40G 的空间,而 Windows 又是个吃硬盘的怪兽,随着补丁的增加留给 macOS 的空间越来越小,最终变成了 70G Windows + 40G macOS 的划分. 就这么凑合用了两年,最终省吃俭用抠下来的空间都不够 Windows 装个补丁以及 XCode 跑过升级了. 想想这台电脑除去硬盘用个五年没问题,就这么换新未免有些 overkill.

因此就有了硬盘升级的需求. 淘宝上现在有很多原厂的 mac 硬盘可以更换(甚至主板都能换,也就是连带 CPU 和内存),有些店家甚至提供了店内帮你更换的服务并回收完好的老硬盘帮你节省一点成本,免去了自行操作的风险和麻烦. 所以剩下的工作就只有系统迁移了.

基本思路

分区示意

硬盘里有几个不能动也不用动的分区,比如引导用的 EFI 分区、Windows 需要的 MSR 预留分区、macOS 的恢复分区,装了 Linux 的话还可能会有 grub 和 swap 分区. 这些分区只需要原样复制过去就行. 剩下的就是装着系统的分区了,硬盘升级后最主要的用途就是扩大系统分区的容量,所以它们都需要扩容. 每个操作系统和文件系统的扩展工具都不同.

扩容

所以 Macbook 做硬盘升级 + 系统迁移的基本思路就是:先在移动硬盘里做老硬盘的全盘备份,然后升级硬盘,再把不用动的分区原样复制(按扇区复制)到相应的位置,预留下需要扩容的分区空间,再把需要扩容的分区复制到相应的位置并扩容.

继续阅读 »

Lambert W function 数值计算

由于一些很蠢的原因,我写了一份完全用不着的用于计算 Lambert W function 的 C# 代码. 具体原理是很粗暴的牛顿法求解,但有几个特别处理的地方:

首先是估算. W0比较好处理,其实随便给个初始值就好,我这里选择了偏移后的 ex. 而 W-1 则比较特殊,首先在 x < -2 的部分变成了 concave 的,而且越往左斜率越小,所以一律从 x = -2 开始尝试;而在 -2 < x < -1 的区间内其实也是随便给个初始值就好,我这里选择了偏移后的 cos 函数.

其次是精度处理. 通过 log2x 做差可以求出二进制下的有效数位,然而当 y 值较大的时候其实并不能把完整的 52 位双精度浮点数的小数部分求完整,大概只能求到 47 位左右,所以这里我保守选择了 42 位有效数字.

继续阅读 »

CanvasRenderingContext2d bug 2 则,附解决方案

前言:这篇文章本来是上上次在 Autodesk 实习结束的时候 (2015.12) 就要发的,后来存在草稿箱给忘了,现在这两个 bug 并不知道还存不存在,本来是有计划写详细的代码示例的也搁置了.

第一个 bug 仅影响 Windows 平台的 Firefox.

当在 clip 过的 context 中绘制阴影时,如果在本次渲染周期前没有任何 fill 操作,clip 会失效. 后果是 clip 外的内容会被覆盖.

解决方案是在所有渲染操作前绘制一个透明的像素.

第二个 bug 有关于 IE 的 CORS.

IE 是部分支持 CORS 的,比如如果请求头设置正确的话图像是可以在 <img> 中正确加载并显示的,也可以通过 Image 类加载并绘制到 canvas 中. 然而,通过后者绘制的 canvas 将不能使用 toDataUrl (会报 SecurityError 异常).

解决方案是先使用 XHR 载入图像数据,然后将 ObjectUrl 赋值给 Image.src. 感谢微软,至少 XHR 的 CORS 还是能用的. (此处应有一颗药丸)

.NET Core 调用 native library 的 project.json 写法

太长不看版:

一点废话:最近在用 ASP.NET Core 练手,想把去年 CS246 (C++) 的期末大作业做个 web interface. 当时选做了国际象棋,整个 C++ 代码从设计到完成,还附带一个不带 WebSocket 的用 ASP.NET Core beta5 (当时还叫 ASP.NET 5) 写的简易 web interface 作为附加分,一共也就用了 50 小时 (虽然忘记做王车移位时不能被将的判断了) 其中还有至少 4 小时花在了将 还处在 beta 的 ASP.NET Core 部署在 Amazon Linux 上. 而现在,我花在这个 web interface 上的时间可能都超过 100 小时了,看来核心业务逻辑果然是只占有非常少的比例啊…

这次要说的是,如果 C# 中要调用 native library,也就是要用 DllImport,那在 project.json 中应该如何导出这个 dll. 撰写此文的时候是 2016/09/10 版本是 .NET Core 1.0. (按照微软的尿性谁知道下个版本这么写还对不对)

继续阅读 »

Amazon Linux 编译安装 mono 并后台运行 ASP.NET5 应用(supervisor)

目前 ASP.NET5 环境仅对 Ubuntu 支持得比较好,而使用 yum 的几个 Linux 则需要花一些时间去安装了(理论上讲 mono 提供了 yum 的包,但实际安装的时候报缺少 libpng15.so,并没有找到任何方法修复). OS X 和 Windows 当然是一路绿灯并没有什么问题. 不巧的是我的 Amazon EC2 跑的是 Amazon Linux,折腾了一个礼拜才最终搞定.

首先当然是安装 mono. 安装过程可以参考 mono 官方的教程. (需要先安装 git 和 make)

注意:编译安装 mono 需要花费较长的时间.

继续阅读 »

As3 使用 FlvEncoder 输出 1080p 视频

话接上回,这次真刀真枪输出1080p的视频了. 前前后后折腾了一天,终于顺利输出无报错了,注意点有两个:

1. 不要使用 FlvEncoder 的 Alchemy 模式,我每次渲染都会在进行到一分多钟的时候报错,排查下来是使用 Alchemy 的 helper 不能正常生成 ArrayByte (长度为0,位于 VideoPayloadMakerAlchemy.as Line 74). Adobe 自己也反复表明不建议将其用于生产环境中,看来还是有道理的.

继续阅读 »

AIR 及 Flv Encoder 初体验

作为一个 AS 起手的 Coder,代码写来写去还是 AS3 写起来最舒服,只是由于不能文件操作等问题,再加上现在做网页前端也基本用不到 Flash 了,便荒废了很久. 这次终于把录了半年的 Rain Stops, Goodbye (音频部分)杀青了,着手做 PV ,却又不想像以前那样用 Windows Live Movie Maker 随便做做了事,所以就想到用 as3 来动态生成一些内容最终做成视频.

其中涉及到的一个重要的问题就是视频编码,我稍稍 Google 了一圈,能找到的现成的编码器不多,其中 zero point nine 的 Flv Encoder 感觉还不错:第一,这是无损编码;第二,它支持在AIR环境下直接把视频写入硬盘.

AIR 环境算是让 AS3 摆脱了一些束缚,使其能作为一门常规的语言来开发,或者说终于能用 AS3 写软件了. 而且只要把运行环境改成 AIR 就可以直接使用原来的 Flash. 但是有一点要注意,在 Windows 下不能将源文件和发布的文件保存在中文路径下,不然会提示“Test Movie terminated. application descriptor not found”. 建议发布的时候选 Application with runtime embedded 不然的话还要很二地“安装”完才能用. 我用 Flash Builder 的时候就觉得这个设定很二,为何不干脆一点生成个能直接运行的二进制文件,真要搞什么安装可以作为可选附件.

Flv Encoder 的使用很简单,基本上把作者提供的 Example 改一改就能用了,基本没有其他需要翻文档的地方. FlvEncoder.addFrame() 是 Flv Encoder 用来写入帧的函数,第一个参数是图像数据(bitmapData),第二个参数是音频数据(ByteArray). 图像数据只要创建一个 ENTER_FRAME 的事件,每帧用 bitmapData.draw() 把舞台上的东西截下来就行了. 音频数据则比较复杂:作者提供的 Demo 做的是一个记录摄像头的工具,音频来自于输入设备;而我是要从本地读取 mp3 再读出每一帧之间的采样点.

继续阅读 »

在用循环生成的匿名函数中使用jquery选择器 – JS函数式编程

群里有人问怎么生成一个包含调用一系列jquery对象里函数的数组,其实首选方案是数组里直接存对象,不过这个问题值得研究一下.

首先贴上一段简单的html:

其中的 your_codes(); 则是接下来要说的实现代码.

一开始我的写法是这样:

但最后生成的函数会随着 i 从栈中的消失而失去作用. 也就是说,在匿名函数内的变量 i 不能是循环里那个 i 的引用,否则最后数组里所有元素都和最后一个元素相同了.

继续阅读 »

Windows 8 + Ubuntu 12 双系统 Legacy BIOS 转 UEFI 启动纪实

注意:这是一篇记录性质的日志,并不是一篇教程. 我最后成功将两个系统由 UEFI 引导了,但是花了不少功夫,绝对不是最佳步骤,本文仅供要做同样事情的人参考.

在帮弟弟装系统的时候发现他的笔记本不支持 UEFI 启动,回去随手看了一下自己的主板发现居然可以,但是我的 win8.1 和 ubuntu12.10 已经以 Legacy BIOS 方式安装了,网上找了一圈也没见到如何转换的教程.

我有两块硬盘,一块 SSD 内安装着 Windows 8.1 与 Ubuntu 12.10 ,由 Windows 的 Bootmgr 引导 Grub Legacy , 一块 HDD 内安装着 Windows 7.

首先 Legacy BIOS 方式安装的系统是安装在 MBR 分区格式上的,如果要用 UEFI 方式启动 Windows 8 ,则必须将硬盘分区改成 GPT 格式的. Windows 下有 diskpart 工具可以完成转换工具,于是找了篇教程:

http://www.iruanmi.com/convert-gpt-to-mbr-or-convert-mbr-to-gpt-use-diskpart-tool/

但是,注意教程中的以下语句:

继续阅读 »