150 likes | 237 Views
DJ Player. DCL Project Group 16. 作品介紹. 用鍵盤演奏樂器,有爵士鼓,電子琴兩種 mode 可以將錄下剛剛創作的歌,播放欣賞. 樂器選擇. 由 key 切換: 在錄音模式下 : Key2 -> 鋼琴聲 Key3 -> 鼓聲. 實作方式. Interrupt handler{ 依照對應的 keycode 改變要播放的聲音編號 } While(1){ Scan keyboard( 按按鍵,產生 interrupt) 由 SD card 讀檔播放該聲音編號 }. 實作方式 - 續.
E N D
DJ Player DCL Project Group 16
作品介紹 • 用鍵盤演奏樂器,有爵士鼓,電子琴兩種mode • 可以將錄下剛剛創作的歌,播放欣賞
樂器選擇 • 由key切換: • 在錄音模式下: • Key2 -> 鋼琴聲 • Key3 -> 鼓聲
實作方式 • Interrupt handler{ • 依照對應的keycode改變要播放的聲音編號 • } While(1){ Scan keyboard(按按鍵,產生interrupt) 由SD card讀檔播放該聲音編號 }
實作方式-續 • 每個聲音對應到一首儲存在SD card中的歌,我們先將每首歌按照樂器的順序放好,每個聲音對應到各自的song_number,song_number = -1 時沒聲音(迴圈)。按鍵按下時會更改song_number,!=-1時會跳出迴圈,開始播放(&紀錄)對應的音。
由SD卡讀wav檔 • 讀wav的標頭檔,依照裡面的資訊讀檔: • 先用file_list()這個函式取得所有需要的資訊,包括SD card中的歌曲數目、每首歌的長度。 • 歌的長度是以cluster為單位計算,一個cluster是512 byte,歌曲的長度是以cluster的數目來儲存。
錄音 • 用一個二維陣列紀錄 • record0[ ][0] • 用switch2 來控制錄音與否,當switch2 on時為錄音模式,此時用switch0,switch1來選擇要錄在哪一軌。
所遇到的困難 • 同時播放聲音: • Attempt1: 用thread同時播,但需要在DE2上灌OS ,太複雜而放棄 • Attempt2: 原本播一種聲音,是一次讀16bit,在迴圈內播放,因此想嘗試,交錯讀兩種聲音播放。 但是播出來的聲音很明顯是失敗的。
遇到的困難2 • 即時播放按下鍵的聲音 • Sol1:在鍵盤的部分用interrupt的方式來寫,可以立即傳入主要的迴圈中,比較快ㄏㄏ。 • Sol2: 儘量減少迴圈內的判斷式,尤其是usleep()的數目
遇到的困難3 • 因為播放聲音中,整個process會被block住,這時候按下另一個鍵就無法播放下一個聲音,不夠realtime • Sol1:同樣以interrupt的方式處理,設計另外一個flag叫newsong,每次按鍵按下時都會被設為1,同時把song_number設為下一首歌。跳出原本在播放的迴圈,開始播新的歌。
遇到的困難4 • 如何錄音? • Attempt1: 開一個特大的陣列BYTE把播了哪些東西全部存下來,然後記憶體就炸了… • Attempt2:每一軌用一個二維的陣列來存,record[1000][2]。 record[n][0]存song_number,record[n][1]存播了幾個cluster ( 紀錄長度 )
遇到的困難4-2 • 前頁Attempt2的方法,因為在song_number = -1時沒有播放音樂,所以無法像播其他聲音時能正確記下長度。本來還嘗試了播放空白的音樂檔案等方法,但空白的音樂檔案也會神秘的發出聲音。 • 最後用usleep模擬無聲,正確記下空白時間長度。
成果 • 做出鍵盤樂器 ˇ • 多軌錄音 ˇ • 混音播放 :’(