RSS Feed

February, 2012

  1. 音乐中调号的区别

    February 22, 2012 by xudifsd

    最近研究了下音乐中调号的区别,写篇博客就当做是科普了(以后可以给妹子教学,至少这比编程之类的话题更吸引她们),顺便也可以证明一下一直2B的我曾经也文艺过。。

    首先推荐一本书:《五线谱入门》。这书虽然自称是入门,但是只要你全看懂了基本上五线谱的所有知识都会了,所以说书名有些谦虚,而且我总是感觉这书的用词非常口语化,可能是我看计算机技术类的书看多了吧。摘一句:“过去很多人学读谱学不会,究其原因,一是方法不对头,而是下功夫不够。”这种话你是绝对不可能在其他技术书籍里看见的!

    好了,不废话了,进入正题。

    调号的区别

    要想明白为什么调号有区别就必须知道相邻两个唱名(所谓唱名就是Do Re Mi Fa Sol La Si)之间的音高差别是不同的,具体的不同就是Mi和Fa,Si和Do差一个半音,其余相邻的音都是差一个全音。

    如下图的钢琴键盘:

    钢琴琴键

    最左边的C键和D键中间有个黑键,这说明C和D差一个全音,而E键和F键中间没有黑键则说明E键和F键只差一个半音。
    所以说如果C是Do,那么D E F G A B则分别是Re Mi Fa Sol La Si,因为就像上面说的Mi和Fa,Si和Do差一个半音,其余相邻的音都是差一个全音。钢琴的琴键的排列还是很规律的。

    那么调号又是怎么回事呢?简单地说调就是Do的音高位置。如果Do=C那么就是C调(如上面的举例),如果Do=D那么就是D调,以此类推。
    下面就是钢琴C大调和五线谱对应的图:

    钢琴C大调

    而钢琴的D大调就如下图所示:

    钢琴D大调

    可以看出两个图的不同就是D大调需要按两个黑键,而C大调只需要按白键,除此之外白键对应的音在五线谱上的位置都是一样。这样一来,C大调和D大调在按键方面只需要将F改为#F,将C改为#C就行了,除此之外按键没有任何区别。

    另外,要在五线谱上记录调号就靠五线谱最左边那个音乐符号(谱号)旁边的#或b来表示,它们分别表示升调和降调。而D大调上有两个#是因为在所有唱名中只有两个需要用黑键来弹。而A调对应的谱号旁边就应该有3个#,因为它的唱名有3个需要用黑键弹。

    小提琴的话就要复杂一些了,因为小提琴不像钢琴有键,弦上也没有任何标识,所以一旦手指偏移了几毫米都会有音的误差,这就是小提琴的苦逼之处啊。

    小提琴的C大调指法如下图:

    小提琴C大调

    从图中可以看出小提琴有四根弦,分别为G弦,D弦,A弦和E弦(通俗点叫就是4弦,3弦,2弦和1弦)。叫这个名字就是因为它们空弦的音与钢琴琴键的音是对应的:例如4弦空弦对应的音就是钢琴的G键发出的音。所以4弦一指对应的音就应该是A,二指对应B,三指对应C。和钢琴一样,小提琴的B和C也只差一个半音,所以它们距离上更接近。同样和钢琴一样,小提琴的C大调就是C对应的唱名为Do,之后再按照Mi和Fa,Si和Do差一个半音,其余相邻的音都是差一个全音这样的规则来分布指法。

    对应的,小提琴的D大调指法如下图:

    小提琴D大调

    其他调的方法都以此类推,其实最常用的调号也就A调,D调和C调了,练习曲子时在五线谱上标记#再练习就能非常快速的记住需要按哪个指或按哪个键了。


  2. 如何让Git的clone实现断点续传

    February 10, 2012 by xudifsd

    在下载大文件时最重要的功能恐怕就是断点续传了。如果在一个网络环境十分不稳定的环境下使用git克隆一个大型代码库绝对是个痛苦的经历,一旦下载中断,之前下载的内容全都不复存在。

    git提供断点续传的难处

    根据git的传输协议,在使用非HTTP进行传输时客户端和服务器端会进行一个复杂的通信:首先服务器端会列出它的所有内容,然后客户端根据服务器端的提示找出自己需要哪些数据,再向服务器索取,之后服务器端再调用“git upload-pack”将客户端想要的commits进行打包并传输。整个过程比较复杂,而且传输协议也不像HTTP协议那么简单,并且最麻烦的就是git传输的不是静态文件而是动态生成的,这样就造成了git的传输很难修改成支持断点续传。

    解决方法

    用HTTP来获取静态的文件时使用断点续传实在是再简单不过的了,只要在HTTP头加一行RANGE属性即可。所以如果能将git的整个仓库转换成一个静态文件再使用普通的HTTP协议传输就能非常简单地实现断点续传了。

    git其实有packfile这样的文件格式,这种文件会在运行“git gc”时或进行传输时生成,生成之后的文件包括了整个git所管理的全部内容,但仅仅只靠这样一个文件还是不能解决问题,因为这种文件只包含仓库中所有对象的内容和SHA1值,除此之外没有任何仓库元信息(分支,tag等)。所以就算得到了packfile也不能重建一个仓库。

    但是git除了packfile外还有另外一种格式的文件:bundle,这种文件只是在packfile的基础上再包括刚刚提到的仓库的元信息,所以根据bundle文件我们可以完整地clone出一个仓库。

    不过这和断点续传有什么关系呢?因为bundle可以用来将整个仓库变成一个静态文件,所以如果在服务器上创建bundle再用普通的HTTP来得到这个文件,就可以重创整个仓库,这也是android仓库的做法。不过这个方法需要服务器端提供clone.bundle文件,一旦服务器提供不一样的文件名这样的方法就失效了。而且这样的方法需要用户对服务器有控制权,如果不能控制服务器这一切都是空谈。一般用户常常只是在github这样的网站托管仓库,或者想要克隆一个Linux内核代码,这样只要服务器端不提供bundle,就算用户知道有这个东西也不能利用它来进行断点续传。不过为何不让别人帮你创建bundle呢?最终的解决方案就是这个网站,它接受你提供的代码仓库的url,之后它会将你想要的仓库克隆并创建一个bundle文件,之后你只需从该服务器上下载静态的bundle文件即可。下载完整个bundle文件后根据这里的举例就能得到整个仓库了,不过之后需要使用“git remote”修改一下远程仓库的地址,修改完后为了确保仓库内容最新最好还要执行一下“git pull”。