音樂隨機播放算法


常見的音樂隨機播放算法主要有兩種:一是Shuffle算法;二是Random算法。

一 Shuffle算法

Shuffle算法和排序算法正好相反,是從有序到亂序的一個過程,俗稱洗牌算法。它將播放列表中的歌曲順序打亂,變成一個和原來歌曲順序沒有任何關系的亂序的播放列表,之后進行歌曲的播放,並支持當用戶點擊“上一首”時,能夠回到剛剛播放的那一首歌曲。

二 Random算法

Random算法是在選取即將播放的歌曲時,進行一個隨機數的運算,得到即將播放的歌曲在播放列表中的索引,播放列表本身並沒有被打亂,只是利用隨機函數從播放列表中選取一首歌曲進行播放而已。

現在比較普遍的隨機數生成算法是基於線性同余算法實現的,例如C語言標准庫函數rand()就是利用它產生隨機數的。線性同余算法能夠產生均勻分布的隨機數,但是它依賴於給定的隨機數的上限,如果上限越小,產生的隨機數重復的概率就越大。

Random算法另一個缺陷是當點擊“上一首”時,跟“下一首”功能完全一樣,都是重新生成隨機數,並利用它從播放列表中選取歌曲進行播放,而不會回到剛剛播放的那一首歌。當然,這個缺陷可以通過提供歷史記錄來彌補,只是需要花費額外的空間。

三 隨機函數

上面兩種算法的關鍵都是隨機函數,下面介紹Java和C兩種語言中隨機函數的使用。

3.1)Java中的隨機函數

Java是采用線性同余算法產生隨機數的,優點是隨機性好,周期長,速度快,易於計算機軟件實現,缺點是產生的隨機數受數學規律的制約,具有周期性和相關性,只能產生偽隨機序列。JDK提供的隨機數生成方式有兩種:

3.1.1)Math.random()函數

該函數返回0到1區間中的某個double值,源碼實現如下:

可見,該函數底層是調用Random類實現的,首次調用random函數時,靜態成員變量randomNumberGenerator為空,因此將調用Random類的構造函數進行初始化,隨后每次調用random函數randomNumberGenerator不再為空,將不會再實例化Random類,因此,每次調用Math.random()函數用到的都是同一個種子,也就是首次調用的系統時間產生的種子。

3.1.2)Random類

位於Java.util包中,該類有兩個構造函數,實現如下:

可見,構造函數默認使用當前的系統時間產生種子,用於初始化Random對象。之后就可以調用各種next*函數來獲取各種類型的隨機數,如nextBytes,nextInt,nextDouble,nextGaussian等等。

3.2)C/C++中的隨機函數

C/C++中最常用的生成偽隨機數的方法是C標准庫提供的rand()函數,它定義在stdlib.h文件中,能夠返回0~RAND_MAX之間均勻分布的偽隨機數(RAND_MAX至少為32767,一般默認為32767)。

直接調用rand(),每次生成的偽隨機序列是相同的,因為rand()在生成隨機數時會使用一個種子(默認值是1),作為計算隨機數的初始值,如果種子相同,那么生成的偽隨機序列也將是一樣的。解決的辦法很簡單,就是每次使用不同的種子來調用rand()函數,srand()函數就是用來設置rand()函數產生隨機數時使用的種子的。

srand()函數原型如下:

srand()和rand()配合使用的示例如下:

需要注意的一點是,上面代碼在生成多個隨機數時,要將srand()放到for循環的外面,否則上面輸出的10個隨機數都將是一樣的,因為計算機運行速度太快,導致time()函數執行的結果沒來得及改變。詳見下圖。




四 音樂隨機播放算法的Shuffle實現

4.1)C/C++版本


4.2)Java版本

 現成的Shuffle庫算法

其實無論在C++還是Java中,都已經實現了Shuffle算法,在實際項目開發中,如果不是有特殊要求的話,完全沒有必要自己去實現Shuffle算法,下面就來看看已有的Shuffle算法。

5.1)C++中的Shuffle算法

C++ STL中的函數random_shuffle()就是用來對一個元素序列進行隨機重新排序的算法,函數原型如下:

具體用法可參見:http://blog.csdn.net/ACE1985/article/details/5868682 。


5.2)Java中的Shuffle算法

Collections類中實現了Shuffle算法,這個類位於java.util包中,有兩個重載函數,下面直接看源碼:

參考文獻:

1)http://www.ifanr.com/29498 從隨機播放算法看iPod的細節之美

2)http://blog.csdn.net/cstn_kdlx/article/details/7326516 隨機數生成問題小結

3)http://blog.csdn.net/hcy0727/article/details/7581671 洗牌算法

4)http://blog.csdn.net/chosen0ne/article/details/6129315 隨機播放CD

5)http://blog.csdn.net/ACE1985/article/details/5868682 random_shuffle()和transform算法



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM