个人项目总结:C++播放器脚本语言

这个项目大概是我做的最有创新性的一个项目。由于我对音乐比较感兴趣,在收到项目要求后,我就想尝试把硬件播放音频的功能加入到项目中,并且最终完成了一个可以把编写的乐谱播放出来的脚本。除了算法的实现以外,我成功地把近期《操作系统》学习的线程和信号量引入了程序并实现了音符的同步与并行问题,最终完成了多音符同时播放的功能。

一、项目的定位与规划

我将这款脚本语言命名为“Essence”,目的是让音乐爱好者在发现创作灵感时,可以先用脚本把自己的灵感记录下来,并且运行脚本还可以听到乐谱的效果。首先,这款脚本语言的受众并不是计算机从业人员,而是没有编程经验的音乐爱好者,所以这注定是一款高度面向用户的脚本语言。对此,我基本上完全没有按照一般编程语言的开发结构,而是按一种类似于简谱的编程方式来进行语法设计。另外,我用空格和标点符号来实现各个音符的对齐来解决演奏时机的问题。整个项目中设计脚本和规定语法是最简单的,重要的是如何实现编译和运行。

二、播放器发声的硬件支持问题

这是一个相对新颖的问题,因为之前我在做其它项目的时候,没有尝试调用过硬件。调用硬件本身是一个比较容易的问题,它不需要在代码上进行太多改动,只需要在生成可执行文件时,加入扬声器硬件链接即可。

在成功链接好硬件之后,出现了新的问题:硬件一次只能发出一个音高的声音,而一般的音乐主要是由和弦(一次发出多个音符)组成的。这代表我们必须使用多线程对原程序进行编译。我引入了c++ stread库来完成这个过程。

当然,在用线程解决多个音符同时发生之前,还需要把所有的音符尽可能组成最少的队列,从而实现用最少的线程进行演奏。这对应的算法非常简单,只需要把所有需要的音符排成一个队列,并且依次放入一个线程即可,如果和每个已经创建的线程发生冲突,则新建一个线程。这样就可以实现把全部的音符放入最少的线程。

在处理完这个问题后,虽然解决了问题,但却带来了新的问题:由于不同的线程是异步运行的,在运行一段时间后,必然会带来时间上的差异,导致整体的播放出现问题。此时,最好的方法就是每一个小节实现一次同步,即用信号量来完成这个校正过程。具体的方法是:准备和线程数量同样多的信号量,再另外设置一个时间线程。演奏线程每一个小节请求一次信号量,而时间线程每个小节的时间释放足够的信号量,让线程继续运行。这样就完成了全部的设计过程。

你可能感兴趣的:(c++)