资讯动态

微机原理课设必备:基于C++与MFC的键盘电子琴完整实现指南

发布时间:2026/8/31 14:14:31 来源:尧图企业网站定制
简介本资源是西安电子科技大学微机原理课程设计典型项目——基于C与MFC框架实现的键盘电子琴演奏程序面向高校计算机/电子信息类专业学生解决课程设计中接口编程、定时器控制、声频合成与人机交互等核心实践问题。压缩包共95个文件含6个核心CPP源码、8个H头文件、17个BMP琴键界面图、26个MP3示例音频、1个可执行EXE及完整实验报告与设计文档总大小9.78MB其中MFC对话框资源RC/ICO/BMP、调试产物PDB/OBJ与帮助系统HLP/HM/HPJ体现工程完整性。已有551人学习下载资源提供从C/D调切换、21键图形化响应、P键自动演奏20秒以上乐曲到声卡直驱输出等分层功能实现代码结构清晰、注释充分配套文档涵盖音频率计算依据、键盘映射逻辑、MFC消息响应机制及硬件抽象层HWControl模块设计说明便于理解微机原理中定时/中断/IO端口与软件协同的底层原理。 每年微机原理课设一到,总有人被电子琴这个题目卡住。看似就是个按键发声的小程序,但真要交源代码、文档说明加实验报告,还得在答辩时把原理讲明白,这里面牵扯的东西比想象中多得多。我前前后后带过不少学弟学妹做这个题,自己也完整叠过一遍基于C和MFC框架的实现,所以对这个项目的坑和套路实在太熟了。这篇就把我实际用的方案、代码组织的思路、报告该怎么写、答辩会被问什么,一次性讲透。如果你正在做西电或者其他学校的微机原理课设,题目恰好是键盘电子乐器演奏程序设计,或者你只是想用MFC做个带界面的小项目练手,这篇文章可以直接当参考。完整走一遍之后,你手里会有四样东西:能跑起来的源代码、能说服老师的实验报告、能应对答辩的原理理解,以及一套把需求拆成代码模块的思路。1. 项目全貌与需求拆解很多同学拿到题目第一反应是电子琴?那不就是按键发个声吗。这句话对了一半,但课设评分的重点恰恰在另一半——你是怎么把键盘输入变成声音的,这个链路里每一步用了什么机制,对应微机原理里的哪些知识点。这才是这门课要考察的东西,而不是单纯看你写了个能响的程序。1.1 这个课设到底要做什么先拆题目本身:键盘电子乐器演奏程序设计(电子琴)。载体是PC键盘,不是MIDI键盘。也就是说,你要把标准键盘上的某些按键映射成琴键。交互方式是演奏,按下发声、松开停止,最好支持多个键同时按下(和弦)。交付物是程序设计,不只是一个demo。要有界面、有操作逻辑、有代码规范。技术栈是C配合MFC框架,这意味着你要处理窗口、消息、消息映射、控件,而不是在控制台里print一下完事。额外要交文档说明和实验报告,所以设计思路、原理框图、流程图这些都得留好素材。核心链路拆开是这样的:按键按下 - 识别键位 - 映射为音高 - 计算频率 - 驱动音频输出 - 扬声器发声这里每一步都能和微机原理挂上钩:键位扫描对应并行接口读入,音高映射对应编码表,频率计算对应分频逻辑(类比8253/8254定时器的工作方式),音频输出对应端口操作或DMA传输。虽然MFC封装了底层窗口消息,但在实验报告里,你得把这层对应关系写清楚,这才是课设的微机原理含量所在。1.2 需求映射到功能模块我把题目需求拆成了五个模块,这个拆分方式直接决定代码目录怎么组织、报告怎么分段、答辩怎么自圆其说。功能需求对应模块实现要点按键识别键盘输入模块捕获WM_KEYDOWN/WM_KEYUP消息,维护按键状态表音高映射音符映射模块建立键位到MIDI音符编号的映射表,支持查表声音生成音频输出模块根据音符编号计算频率,驱动发声API界面展示界面模块绘制钢琴键位视觉效果,显示当前音名扩展功能曲谱播放/录音用定时器驱动预置曲谱,记录演奏序列并回放这个模块划分不是拍脑袋定的,它对应了输入—处理—输出—显示—扩展这条标准链路。课设报告里的系统结构图直接用它画,答辩时老师问你系统分成哪几个部分,你按这个说,思路会非常清晰。2. 整体设计与文档规划写代码之前先规划交付物的样子,这是很多人忽略的一步。课设评分看的是你交出去的那个文件夹,不是你的源码有多炫。一个结构清晰的工程目录加一份体面的实验报告,分数下限就保住了。2.1 项目交付物的组织方式我建议的目录结构长这样:KeyboardPiano/ ├── KeyboardPiano.sln ├── KeyboardPiano/ │ ├── KeyboardPiano.h / .cpp // 应用主类 │ ├── KeyboardPianoDlg.h / .cpp // 主对话框 │ ├── PianoCtrl.h / .cpp // 钢琴键盘绘制控件 │ ├── MusicEngine.h / .cpp // 音频引擎封装 │ ├── NoteTable.h / .cpp // 音符频率表与映射表 │ ├── ScorePlayer.h / .cpp // 曲谱播放扩展 │ ├── resource.h │ └── res/ ├── 文档说明/ │ ├── 需求分析.md │ ├── 设计文档.md │ └── 使用说明.md └── 实验报告/ └── 实验报告.docx源代码里把音频引擎和界面分开,这个习惯非常重要。我见过太多人把Beep直接写进对话框的消息处理函数里,导致后面想加曲谱播放、想加录音,代码乱成一锅粥。界面和功能解耦,这是工程意识的第一步,也是课设报告里能写出来的加分项。文档说明和实验报告分开建目录,用Markdown写需求分析和设计文档,到时候往Word里粘贴也方便。实验报告单独放一个地方,里面要有完整的原理图和流程图。2.2 为什么选MFC框架这个题目用MFC,其实是个很自然的选择,但也确实是个带着镣铐跳舞的选择。MFC(Microsoft Foundation Classes)是微软对Win32 API的C封装,它的核心价值在两点:一是消息映射机制,让你不用写巨大的switch-case来处理窗口过程;二是文档视图结构,把数据和界面分离。对于课设这种规模的项目,MFC的Dialog应用模板(基于对话框的应用程序)最合适,因为主界面就是一个窗口,不需要复杂的视图切换。但MFC也有两个坑。第一,它太老了,VS2022里创建MFC工程需要单独安装适用于最新v143生成工具的C MFC(x86和x64)组件。第二,字符集问题,MFC默认走Unicode,你写字符串字面量时要用_T(...)或者L...,不然一堆乱码和编译错误等着你。如果你问能不能不用MFC,当然可以。纯Win32 API自己写窗口过程,大概多写200行样板代码;用Qt也能做,但那就偏离题目指定的框架了。课设的第一原则是完成题目要求,而不是展示你觉得更好的技术。用MFC,该踩的坑踩完,答辩时反而有话可说。3. 核心实现:从按键到音符这一节是整个项目的技术核心。我会把从按键捕获到声音输出的完整链路拆开讲,每个环节都给出可复用的代码思路和关键代码。3.1 音符频率的计算与存储首先解决音高到频率的问题。乐理上,标准音A4(中央C上方的A)的频率是440Hz。每个半音的频率关系是十二平均律,相邻半音的频率比是2的12次方根,约等于1.059463。所以任意音符的频率可以这样算:double NoteToFrequency(int midiNote) { // midiNote 69 对应 A4 440Hz return 440.0 * pow(2.0, (midiNote - 69) / 12.0); }这个公式就是实验报告里频率计算原理那部分的插图内容。但实际程序里我不会实时调用pow去算,而是提前生成一张查表。原因很简单:电子琴演奏时按键触发极其频繁,动不动几十个键同时按,每次都做浮点指数运算,虽然是微秒级,但完全没有必要。查表是最简单、最稳定、最能体现用空间换时间思路的做法。表的大小我定成88个键,对应标准钢琴A0到C8,用一个数组存频率,再用一个映射表把键盘按键映射到音符编号:// NoteTable.h const int NOTE_NUM 88; extern double g_freqTable[NOTE_NUM]; // 键盘键位 - 音符编号的映射 struct KeyMapEntry { UINT nVK; // 虚拟键码 int nNote; // 音符编号, 0~87 }; extern KeyMapEntry g_keyMap[];初始化频率表时,用A4440Hz作为基准,从MIDI音符编号21(A0)开始一直算到108(C8),这样程序启动后所有频率都是O(1)查表。这套设计放在实验报告的数据结构设计一节,得分效果很好。键位映射我采用这样一组布局:键盘按键音符说明Z / S / X / D / C / V / G / B / H / N / J / MC3~B3中音区半音阶,白键黑键混排Q / 2 / W / 3 / E / R / 5 / T / 6 / Y / 7 / UC4~B4高音区半音阶A / W...切换八度用上下方向键整体移调这里用Z、S、X这种行,模仿真实钢琴键位黑白关系,2、3、5、6、7这些数字键当黑键,手指落位非常自然。上下方向键做八度整体移调,这样双手或单手都能跨三个八度演奏。这个布局方案在实验结果分析里可以写:用户测试平均5分钟即可熟练弹奏小星星。3.2 键盘消息与消息映射MFC里处理键盘输入,核心是消息映射。你要在对话框类里响应WM_KEYDOWN和WM_KEYUP,而不是用GetAsyncKeyState轮询。两者的区别在于:消息是按事件驱动的,按下和抬起是两个独立事件,天然适合按下发声、抬起停声的演奏逻辑;轮询是不断读状态,还得自己记录上一次的状态才能判断刚按下还是持续按住,容易出bug。在对话框头文件里声明两个处理函数:protected: afx_msg BOOL OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg BOOL OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);然后在实现文件里手动加消息映射。注意WM_KEYDOWN不是对话框默认处理的消息,你不能只靠类向导自动生成,要手动添加:BEGIN_MESSAGE_MAP(CKeyboardPianoDlg, CDialogEx) ... ON_WM_KEYDOWN() ON_WM_KEYUP() END_MESSAGE_MAP()处理函数里做三件事:通过m_keyMap查表把虚拟键码转成音符编号;维护一个std::mapUINT, bool记录哪些键正在按下,防止重复触发;调用m_musicEngine.NoteOn(note)或NoteOff(note)。还有一个特别坑的地方:对话框上如果放了按钮、编辑框等控件,焦点在控件上时,WM_KEYDOWN不会发给父对话框,而是发给有焦点的控件。解决的方案我在第六章专门讲。3.3 发声方案:Beep函数与waveOut发音有两种方案,我分别讲讲适用场景和代码思路。方案一是最简单的Beep(DWORD dwFreq, DWORD dwDuration)。它会同步地按指定频率发声指定毫秒。核心代码极短:void MusicEngineBeep::NoteOn(int midiNote) { double freq g_freqTable[midiNote - 21]; Beep((DWORD)freq, 200); // 固定时值 200ms }这个方案最大的问题在于,Beep从Windows 7开始是异步的?其实微软文档说的很模糊,实测在多数系统上它确实不阻塞。但在Windows XP/2000这类老系统里它是同步的,会卡死消息循环,按键扫描就全乱了。而且Beep音色单一、无法控制包络(音量从弱到强再到消失),只能发出一声滴滴,离电子琴的体验差很远。方案二是用waveOut系列API播放波形音频,这也是我更推荐的做法,虽然代码多一点,但体验提升巨大,答辩时还能多讲一句使用PCM波形生成模拟了乐器音色。核心步骤分三块:第一,启动时打开波形设备:waveOutOpen(m_hWaveOut, WAVE_MAPPER, m_waveFormat, 0, 0, CALLBACK_NULL);第二,生成一个音符的PCM数据。这段代码是我实际工程里的简化版,核心是填充正弦波采样并加一个简单的衰减包络:void MusicEngineWave::GenerateNote(int midiNote, double durationMs, vectorshort buffer) { double freq g_freqTable[midiNote - 21]; int sampleRate m_waveFormat.nSamplesPerSec; // 44100 int sampleCount (int)(sampleRate * durationMs / 1000.0); buffer.resize(sampleCount); for (int i 0; i sampleCount; i) { double t (double)i / sampleRate; double envelope 1.0 - (double)i / sampleCount; // 线形衰减,模拟琴键敲击后的自然渐弱 double value sin(2.0 * PI * freq * t) * envelope; buffer[i] (short)(value * 12000); // 幅度控制,不要爆音 } }这里的关键点是envelope。不加包络的正弦波开头会有一个啪的爆音,这个爆音就是频谱上突然出现的边缘毛刺。加了线性衰减包络之后,音头从0开始,音尾自然消失,听感就从电脑滴滴声变成了像那么回事的电子琴音。第三,用waveOutWrite把缓冲区送出去播放。注意要用双缓冲,一块正在播放、一块准备填充,不然连续按下多个键时会听到明显的卡顿。双缓冲的实现思路是准备两个波形头结构,交替提交给waveOutWrite,在MM_WOM_DONE回调里确认哪块缓冲用完了才能改它。4. 界面设计与交互增强MFC的界面部分,直接决定了课设答辩时老师的第一印象。一个界面干净、按键有反馈的电子琴,和一个白底对话框上放几个按钮的电子琴,分数差距可以拉到一档以上。这一节讲界面怎么组织,以及几个值得做的增强功能。4.1 主界面布局与自绘钢琴键盘主界面我用一个基于对话框的MFC应用,窗口标题改成电子琴演奏程序,客户区放三块东西:顶部是菜单栏和工具栏,中间是音符状态显示条,下半部分是一个自绘钢琴键盘。自绘键盘用的是一个自定义控件类PianoCtrl,继承自CWnd,注册窗口类后在对话框里动态创建。它要做的事很简单:在OnPaint里按键盘映射表的布局画白键和黑键,可以做成按下去的颜色变化。大致的绘制逻辑:void CPianoCtrl::OnPaint() { CPaintDC dc(this); int keyWidth 30, keyHeight 120; for (int i 0; i m_whiteKeyCount; i) { CRect rect(i * keyWidth, 0, (i 1) * keyWidth, keyHeight); // 如果这个键正在按下,用高亮色填充,否则白色 if (m_pressedKeys.find(i) ! m_pressedKeys.end()) dc.FillSolidRect(rect, RGB(180, 200, 255)); else dc.FillSolidRect(rect, RGB(255, 255, 255)); dc.DrawEdge(rect, EDGE_RAISED, BF_RECT); } // 黑键画在对应白键的分界处,高度约白键的2/3 }这个控件本身不处理按键,它只负责显示。真正按键逻辑在父对话框的消息处理里,按下一个键时,对话框调用m_pianoCtrl.SetKeyPressed(note, true),控件响应后Invalidate()重绘。显示和逻辑分离,这是我反复强调的一个点,写报告时模块化设计这一小节就靠它撑场面。4.2 菜单、工具栏与状态栏的设计菜单项我设计了四组:文件、演奏、设置、帮助。文件菜单:开始新演奏、保存演奏录音、退出。演奏菜单:播放示例曲谱、停止播放。设置菜单:切换音色(正弦波/方波/三角波)、切换音域(默认中音区/高音区)。帮助菜单:关于、操作说明。工具栏就放四个按钮:播放、停止、录音、音色切换,全部用MFC的CBitmapButton或CMFCToolBar实现。状态栏显示当前状态,比如正常演奏中 CtrlR 开始录音,以及当前按下音符的音名(C4、A3这种),这个在演示时效果特别好,老师一眼就能看到按键和音符的对应关系。4.3 扩展功能:曲谱自动演奏与录音回放这两个功能非常推荐做,因为它们是加分项里的性价比之王。代码量不大,但演示效果好,实验报告里还能多写一节系统扩展与创新点。曲谱自动演奏的原理是:把一首曲子表示成一个(音符编号, 时值)的数组,然后用一个定时器每隔一定时间取出一个音符播放。struct NoteEvent { int note; // MIDI音符编号, -1表示休止符 int durationMs; // 时值毫秒 }; static NoteEvent kLittleStar[] { { 60, 400 }, { 60, 400 }, { 67, 400 }, { 67, 400 }, { 69, 400 }, { 69, 400 }, { 67, 800 }, { 65, 400 }, { 65, 400 }, { 64, 400 }, { 64, 400 }, { 62, 400 }, { 62, 400 }, { 60, 800 }, };定时器用SetTimer(1, 100, NULL)开一个100毫秒的节拍器,在OnTimer里累加已播放时长,到了当前音符的时值就切到下一个音符。这个逻辑非常简单,但注意不能在定时器里阻塞播放,否则界面会卡。用上面讲到的waveOut异步播放,正好配合这种节拍器模型。录音功能更简单,在演奏时记录(按下音符, 时间戳)和(抬起音符, 时间戳),回放时先把这些事件按时间排序,再用一个定时器按时间戳依次触发。这样录出来的回放和原演奏几乎一模一样,报告里可以写实现了演奏数据的采集与回放功能。5. 实验报告撰写与答辩准备很多人代码写完以为就结束了,其实实验报告才是拉分项。我见过代码稀烂但报告写得清楚的同学拿了优秀,也见过代码能跑但报告一塌糊涂的被挂了。这个现象背后的逻辑很简单:课设评的是你有没有搞懂原理,而报告是你在答辩之前唯一能让老师看出你懂不懂的东西。5.1 实验报告的结构我建议实验报告按下面这个结构写,每个部分控制在两页以内,总篇幅十页左右:摘要:一段话,说清项目目标和核心实现方式。实验目的:从题目要求出发,列举3~4条,不要抄课本。系统设计:包含系统总体结构图、功能模块划分、开发环境说明(Windows 11 VS2022 C/MFC)。关键技术实现:分小节讲键盘消息处理、音符频率计算、音频播放原理,配合代码片段和流程图。界面设计:界面截图、操作方法说明。系统测试与结果分析:列出测试用例表,比如单键弹奏、多键和弦、八度切换、曲谱播放的测试结果。总结:写遇到的主要问题和解决方法,以及课程收获。其中系统测试那一节最容易被忽视。老师看报告时,最喜欢看的就是你有没有正经做过测试。你列一张表:测试编号、测试项、操作步骤、预期结果、实际结果、是否通过,六列写下来,专业课设的水准立刻就不一样了。5.2 与微机原理知识点的呼应这个部分决定了你的课设是MFC编程作业还是微机原理课程设计。我建议在关键技术实现中明确写出三个知识点的对应:第一,8253/8254定时器与音符频率。你可以这样写:在单片机实验板上,音符频率可以通过对8253定时器设置分频初值产生,初值N 时钟频率 / (2 × 音符频率)。本程序在PC平台上采用同样的分频思想,通过查表直接获取各音符频率值,本质上是把硬件定时器的工作逻辑软件化。第二,键盘扫描与并行接口。可以写:在硬件系统中,矩阵键盘扫描把键值通过8255并行接口读入CPU;本程序利用Windows消息机制捕获键盘事件,等效于完成按键扫描—编码—读入的流程。第三,中断机制与音频输出。可以写:硬件方案中音调的输出可由定时器中断驱动,本程序利用定时器消息与waveOut异步回调,模拟了中断驱动的并发模型。这些不是硬蹭,MFC程序里的定时器确实是对中断的抽象,waveOut的回调也确实类似中断服务程序。写出来,老师一看就知道你是认真把课程内容对应到项目里了。5.3 答辩常见提问与应对我把这几年被问过、以及周围同学被问到的高频问题整理成一张表,这些都是真正会出现在答辩现场的题:问题回答思路频率表怎么计算的?以A4440Hz为基准,按十二平均律f440×2^((n-69)/12)算出全部88键频率,提前存表为什么不直接用Beep?Beep音色单一、无法控制音量包络,在高负载下会阻塞;waveOut可以生成更自然音色并支持并发播放怎么支持同时按多个键?维护一个按键状态表,记录每个键当前是否按下;每个按键的音频用独立缓冲交给waveOut异步播放,互不阻塞键盘按键冲突怎么处理?PC键盘本身有键位冲突限制,程序内通过记录按键状态表避免重复触发,同时建议用户使用非冲突键位组合波形数据怎么生成的?用sin函数生成PCM采样,采样率44100Hz,16位量化,加衰减包络模拟钢琴音色如果调程序时声音卡顿怎么排查?首先检查是否在UI线程阻塞,其次检查waveOut缓冲是否被提前改写,再检查是否有其他进程占用音频设备答辩的核心心法是:老师问什么,你都要回到自己的代码和原理上回答问题。哪怕老师问到一个你没做过的功能,你也可以说这个我在设计时考虑过,最终没有做的原因是XXX,如果要扩展,我会用XXX方式,这种回答方式比硬着头皮编要安全得多,也真诚得多。6. 常见问题与排查技巧实录最后分享几个我在实际开发和帮别人调试时遇到最多的坑。这些坑基本不会出现在教材里,但每一个都能让程序在一秒钟内从能跑变成崩了。6.1 按键焦点被控件抢走这是MFC对话框应用里最经典的坑。你在对话框上放了一个按钮,程序运行时按钮自动获得焦点,然后你按键盘上的字母键,发现对话框收不到任何WM_KEYDOWN,因为消息全发给按钮了。解决办法有很多,我推荐最简单稳的一种:重写对话框的OnGetDlgCode,让对话框在所有情况下都要键盘消息:UINT CKeyboardPianoDlg::OnGetDlgCode() { return DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTCHARS; }这样对话框就不会把按键转给默认控件处理了。同时,在窗口初始化时把焦点设置到自绘键盘控件上,不要停留在按钮上。6.2 自绘控件不刷新导致按键无反馈很多同学做完界面后发现,按下键盘键,视频上能看到状态栏文字变了,但自绘的钢琴键盘没有反应。原因很简单:你改了m_pressedKeys之后没调用Invalidate(),控件不会自己重绘。还有一个更隐蔽的问题是,Invalidate()虽然请求重绘,但WM_PAINT可能没有立刻执行,导致视觉反馈有延迟。解决方法是:更新按键状态后,立刻调用Invalidate(FALSE)加UpdateWindow(),强制立即重绘。这样演奏时按键反馈才是实时的,不会一顿一顿。6.3 音频爆音和卡顿用waveOut播放时最常见的两个问题:一是爆音,二是连续快速按键时声音卡顿。爆音的根源几乎都是包络问题。正弦波从零开始会有冲击,但如果你在音头加了一个短促的增益爬升,爆音就消失了。正确做法是让包络在开头几毫秒从0线性升到目标幅度,然后在尾端衰减到0。这个淡入淡出处理,是音频程序的基本功。快速按键卡顿的根源通常是waveOutWrite提交缓冲的速度跟不上播放速度。解决办法有三个层次:第一,把waveOutSetPitch这类控制放到和音频无关的线程里执行,不要让界面事件阻塞音频线程;第二,使用多缓冲池,至少8个buffer轮转,避免偶尔的分配延迟卡住播放;第三,适当降低采样率(比如22050Hz),钢琴演示完全够用,但计算量减半。6.4 MFC的字符集与编译错误VS2019及以后版本默认使用Unicode字符集,MFC的CString在Unicode下是wchar_t数组。如果你在代码里直接写文本,然后赋给CString,编译不会报错,但运行时会得到乱码。正确的写法是_T(文本)。另外一个高频编译错误是无法解析的外部符号,这通常是MFC的链接配置问题。创建工程时选择在静态库中使用MFC可以减少DLL依赖,但要注意这个选项必须在整个解决方案里保持一致,混用会导致链接失败。我自己的习惯是:创建MFC工程时直接选在静态库中使用MFC,这样生成的exe在实验室其他机器上也能直接跑,不会被缺少mfc140u.dll这种问题卡住。这个细节在课程设计提交时特别重要,因为老师很可能不是在你有VS的那台机器上运行。7. 扩展玩法与最终建议做完基础功能,如果你还有时间,有几个方向可以让项目在课设里显得更出彩:一是加简单的五线谱或简谱显示,把当前演奏的音符实时映射到谱面上,这个功能用MFC的CDC绘制文字和横线就能实现,工作量不大,但视觉冲击力很强;二是做一个预置曲库,把小星星欢乐颂两只老虎这些曲子的数据放进数组,一键播放,演示时非常讨喜;三是把波形生成从正弦波扩展到方波、三角波、锯齿波,做成音色切换,这对应了电子琴琴键—音色的基本模型,也是报告里写得最华丽的数字波形合成小节。我在实际带人做这个题的时候,最深的体会是:这个项目技术门槛不算高,真正拉开差距的在于你有没有把整个链条想清楚。从按键为什么能发声,到频率怎么映射,再到软件里怎么模拟硬件定时器的工作,这一整套逻辑通了,代码怎么写都是顺理成章的;逻辑没通,网上抄一堆代码下来,改了几天还是跑不起来,最后答辩也是两眼一抹黑。还有个特别实用的小建议:代码写完后,专门花一个小时录一段完整的操作演示视频。把单键弹奏、和弦、八度切换、曲谱播放、录音回放这几个功能全部演示一遍,视频存好。这不仅是为了答辩时万一现场设备出问题能救场,更是逼着你把各个功能都走一遍,很多隐藏bug会在演示过程中自动暴露出来。希望对正在做这个课设的你有点帮助。东西不难,静下心来,按着输入—处理—输出—显示这条路走,你也能交出一份自己掌握得明明白白的作品。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价