久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5948|回復: 19
打印 上一主題 下一主題
收起左側

STC單片機音源制作進程(日記)

  [復制鏈接]
跳轉到指定樓層
樓主
     昨天(24-09-2021)已完成了一款用STC8G制作的音源,整個制作過程繁雜,回頭再看很多方法已經忘記了,為了能重復整個制作過程,我將分幾日將原理和程序逐步梳理,寫在論壇就不會再忘記了。

(1) 樂曲聲音的來源:現在的音源都是用真樂器的錄音來制作的,錄音的工作就叫取樣,原廠家會請一些器樂演奏好手來錄音,做成樣本,由于聲音文件很大,一般都只采用幾個音符的樣本,用程序運算產生所有音符(一般有88個音符),做成音源售賣。

用編曲軟件去演奏這些音源,就可以把所有音符錄起來,這是一個MIDI文件,可以產生從C2到C9的音符:




雖然一般樂器沒有用到這么寬的音域,但為了統一方便處理,照錄不誤。樂器維持發聲長短也不一,彈撥樂最短,吹管樂一個音也不會長多五六秒,就用8秒間隔來錄:這是音頻文件的截圖:



從波形可以看出,這其實只是用幾個樣本運算所得的全部音符,這個音頻文件還要經過處理才可以用來制作STC單片機音源。

。。待續

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:276663 發表于 2021-9-26 09:21 | 只看該作者
kdg,還沒看懂你要干啥
回復

使用道具 舉報

板凳
ID:283954 發表于 2021-9-26 17:08 | 只看該作者
用作音源的音頻文件需要降噪處理,把背景雜聲去除,用CE軟件就能完成,接下來就是把全部85個音符剪輯,一個音符一個文件,順序排列,這項工作可用人工完成,但工作量不小,尤其是文件的命名,如果錯誤就麻煩了,因此需要軟件來幫忙。

經過降噪的音頻,在靜音的部分會有一連串零(00H)的字符,這本來可以作為辨識字符把每個音符剪切出來,但不能保證一定正確,因此還是用人工方法在每個音符開始的部分塞進容易辨識的字串,字串要如何塞進原來的音頻文件呢?就必須用音頻處理軟件如CE或GOLDWAVE完成。

首先要制作一個音頻文件,內容包含辨識字符,我采用了“CUTHERE!"這個字,用簡單的BASIC語言就能完成:

CUT$="CUTHERE!"
OPEN "CUTHERE.WAV" FOR BINARY AS #1
PUT$ #1, CUT$
CLOSE #1

生成的“CUTHERE.WAV”文件并沒有WAV文件需要的前輟字符,用CE或GOLDWAVE打開后,軟件會詢問,選擇44.1K,16 BITS signed,Stereo的參數即可,然后保存,以后打開就不會再詢問了。

如何使用呢?用GOLDWAVE打開CUTHERE.WAV文件,選擇復制(COPY),


打開要處理的音頻文件,把光標放在每個音符開始的前面,按“粘帖PASTE”,就把包含“CUTHERE!"字符的波形貼上了,從波形看就有一個突出的尖峰,用播放器播放就能聽到POP聲。把全部85個音符標記完畢工作就完成了。




標記位置的準確直接影響后來音源的結果,必須力求放在音頻剛開始的位置,太靠前則延遲音符的出現,太靠后則音符演奏時會有POP聲。

這工作完成后就可以寫一個軟件把每個音符剪切出來變成85個文件了。

。。待續



回復

使用道具 舉報

地板
ID:283954 發表于 2021-9-27 16:39 | 只看該作者
      昨天用GOLDWAVE把85個音符都做了標記,總共花費25分鐘才做完,如果要把128種音色都做完的話,那就得花25分鐘X128除60=53小時才能做完,真的是三天三夜不眠不吃不喝還得精神飽滿才能做完,所以還得相出其他辦法,否則是無法做出全部音色的。

      經過標記的音色文件,就可以用程序來做切割成85個音符,要寫出一個能一次過切割文件的程序也不容易,因此就分幾步走,第一步是讀取文件后產生一個MAP的文件,注釋每個音符在文件里的位置:

   mapfile.bas


   CLS
   VL=8
   FL$="FLUTE.WAV"

   OPEN FL$ FOR BINARY AS #1 'FIND THE WORD "DATA"
   PRINT "PROCESSING FILE ";FL$;" LEN=";LOF(1)

   FOR I&=0 TO 1000 'LOF(1)
   GET$ #1,4, RING$
   IF RING$="data" THEN
      PRINT "FOUND THE WORD data AT LOCATION:";LOC(1); " SO, IT IS A WAV FILE"
      EXIT FOR
   END IF
   K=LOC(1)
   K=K-3
   SEEK #1, K
   NEXT I&
   CLOSE #1

   VER$="CUTHERE!"

   OPEN FL$ FOR BINARY AS #1 'FIND VER$ MARK AS 000000000(38BYTES)
   OPEN "MAP.TXT" FOR OUTPUT AS #2
   PRINT "ORIGINAL FILE ";FL$;" LEN=";LOF(1)


   B&=LOF(1)/VL 'LOOP HOW MANY TIME

   N=9 'START FILE NAME AT NUMBER 9

   FOR I&=0 TO LOF(1)
   LOCATE 7, 1
   PRINT I&
   IF EOF(1) THEN
      EXIT FOR
   END IF

   GET$ #1,VL, RING$

   IF RING$=VER$ THEN
      N=N+1
      OL&=LOC(1)-OL&
      PRINT #2, N;LOC(1);OL&

      LOCATE 5, 1
      PRINT "FOUND VER$ AT";LOC(1);"SIZE=";OL&;" NUMBER=";N;" LOOP=";I&
      OL&=LOC(1)
      GET$ #1,64, USELESS$ 'MOVE FORWARD TO AVIOD DOUBLE
   END IF
   K&=LOC(1)
   K&=K&-7
   SEEK #1, K&
   NEXT I&
   CLOSE #1
   CLOSE #2
   END

運行后得到MAP.TXT的文件,內容如下:

10  2252344  2252344
11  3667072  1414728
12  5079052  1411980
13  6489384  1410332
14  7901104  1411720
15  9309872  1408768
16  10721256  1411384
17  12131796  1410540
18  13545088  1413292
19  14957832  1412744
20  16368244  1410412
21  17777268  1409024
22  19189964  1412696
23  20600396  1410432
24  22012532  1412136
25  23424380  1411848
26  24834712  1410332
27  26244712  1410000
28  27657152  1412440
29  29069004  1411852
30  30479592  1410588
31  31890980  1411388
32  33302956  1411976
33  34713624  1410668
34  36124548  1410924
35  37535808  1411260
36  38947912  1412104
37  40358964  1411052
38  41769040  1410076
39  43180428  1411388
40  44591816  1411388
41  46003204  1411388
42  47414384  1411180
43  48826824  1412440
44  50237620  1410796
45  51648080  1410460
46  53059468  1411388
47  54470184  1410716
48  55881908  1411724
49  57293884  1411976
50  58704808  1410924
51  60116068  1411260
52  61527120  1411052
53  62938508  1411388
54  64350020  1411512
55  65761152  1411132
56  67172668  1411516
57  68583208  1410540
58  69994260  1411052
59  71406492  1412232
60  72817672  1411180
61  74228548  1410876
62  75640064  1411516
63  77051244  1411180
64  78462836  1411592
65  79873684  1410848
66  81285404  1411720
67  82696664  1411260
68  84108228  1411564
69  85518688  1410460
70  86930412  1411724
71  88340744  1410332
72  89751872  1411128
73  91163772  1411900
74  92574904  1411132
75  93985904  1411000
76  95397804  1411900
77  96808728  1410924
78  98220244  1411516
79  99630784  1410540
80  101041324  1410540
81  102453224  1411900
82  103864612  1411388
83  105276204  1411592
84  106686920  1410716
85  108098644  1411724
86  109509568  1410924
87  110921468  1411900
88  112332468  1411000
89  113743728  1411260
90  115154856  1411128
91  116565832  1410976
92  117977092  1411260


文件中第一列是音符序列碼,第二列是該音符在文件中開始的位置,第三列是每個標記之間的大小,大概是1.4M,這數字并不重要,主要是用來查看有沒有漏標或多標,除了第一行的數字,其他的都應該接近1.4M這個數字,如有錯誤必須打開音色文件糾正才能繼續。

。。待續



回復

使用道具 舉報

5#
ID:887734 發表于 2021-9-27 21:17 | 只看該作者
好東西,坐等更新。。。。。。
回復

使用道具 舉報

6#
ID:283954 發表于 2021-9-28 17:50 | 只看該作者
本帖最后由 dalaoshi 于 2021-9-29 01:22 編輯

    有了MAP.TXT 這個文件,就可以寫一個軟件把每個音符剪出來保存為一個音頻文件,在這之前得先知道每個音符真正長度所占的字節是多少,這可以用GOLDWAVE將音色文件中的一個音符復制,保存為ONENOTE.WAV, 然后查看電腦目錄,顯示為734K,由于每個音符都是由CAKEWALK軟件演奏的,長度一樣,因此在軟件中就填上1024次循環,每次讀取734字節,共734K字節,保存為文件:

   CUTFILE.BAS

   DR$="C:\SOUND\"
   FL$="FLUTE.WAV"
   CLS

   OPEN DR$+FL$ FOR BINARY AS #1 'FIND data
   PRINT "ORIGINAL FILE ";DR$;FL$;" LEN=";LOF(1)

   FOR I&=0 TO 1000 'LOF(1)
   GET$ #1,4, RING$
   IF RING$="data" THEN
      PRINT "FOUND data AT";LOC(1);"SO IT IS A WAV FILE"
      EXIT FOR
   END IF
   K&=LOC(1)
   K&=K&-3
   SEEK #1, K&
   NEXT I&
   CLOSE #1

   OPEN DR$+FL$ FOR BINARY AS #1 'FIND DATA
   OPEN DR$+"MAP.TXT" FOR INPUT AS #2
   PRINT "ORIGINAL FILE ";DR$;FL$;" LEN="LOF(1)

   FOR I=1 TO 84
   IF EOF(2) THEN EXIT FOR
   INPUT #2, MAKE$
   SN$=LTRIM$(STR$(VAL(MAKE$))," ")  'FILE
   PRINT SN$;",";
   MAKE$=MID$(MAKE$,5,18)
   START&=VAL(MAKE$)  'START
   PRINT "LOCATION:";START&;
   MAKE$=MID$(MAKE$,10,10)
   LG=VAL(MAKE$)
   PRINT "BYTES:";LG
   OPEN DR$+SN$+".WAV" FOR BINARY AS #3
   CLOSE #3
   KILL DR$+SN$+".WAV"

   OPEN DR$+SN$+".WAV" FOR BINARY AS #3  'GET 800K
   SEEK #1, START&
   FOR V= 1 TO 1024
   GET$ #1, 734, HG$
   PUT$ #3, HG$
   NEXT V
   CLOSE #3
   NEXT I
   END

   剪切好的音符文件必須用GOLDWAVE打開一個試聽,確保音符是完整的。



。。待續

回復

使用道具 舉報

7#
ID:283954 發表于 2021-9-29 17:26 | 只看該作者
    接下來就是要把所有單音符的文件重新組合成一個文件, 并產生參數讓單片機編程使用:

   JOINFILE.BAS

   CLS
   DR$="C:\SOUND\"

   OPEN DR$+"ALL.WAV" FOR BINARY AS #2
   CLOSE #2
   KILL DR$+"ALL.WAV"
   OPEN DR$+"ALL.WAV" FOR BINARY AS #2
   OPEN DR$+"LIST.TXT" FOR OUTPUT AS #3

   FOR F=10 TO 93
   FILE$=STR$(F)
   FILE$=DR$+MID$(FILE$, 2,2)+".WAV"
   PRINT FILE$
   GOSUB MAKEFILE
   NEXT F
   CLOSE #2

   OPEN DR$+"ALL.WAV" AS #2
   TOTAL$=STR$(LOF(2)/1024)+" KB"
   PRINT "TOTAL IN NEW FILE=";TOTAL$
   PRINT #3, "TOTAL IN NEW FILE=";TOTAL$
   PRINT "TOTAL SECTOR=";LOF(2)/512
   PRINT #3, "TOTAL SECTOR=";LOF(2)/512
   CLOSE #3
   CLOSE #2
   END


   MAKEFILE:
   OPEN FILE$ FOR BINARY AS #1
   IF LOF(1)=0 THEN
      CLOSE #1
      PRINT
      PRINT FILE$;" CONTAIN ZERO BYTES, PRESS ANY KEY TO CONTINUES: ";
      W$=INPUT$(1)
      PRINT
      GOTO MAKEFILEEXIT
   END IF
   PRINT "ORIGINAL FILE LEN=";LOF(1)
   Z=1000
   M=LOF(1)
   IF DISPLAY=0 THEN             'SHOW DETAIL AT FIRST FILE
      PRINT "VALID DATA M=";M
      H=M mod 512
      PRINT "EXTRA DATA H=";H
      K=512-H
      PRINT "NEED FEED DATA K=";K
      PRINT "TOTAL DATA WILL BE";M+K
      PRINT "EACH NOTE NEED:";(M+K)/512;" SECTORS "
      PRINT #3,"EACH NOTE NEED:";(M+K)/512;" SECTORS "
      PRINT
      PRINT "PRESS ANY KEY TO CONTINUE";
      W$=INPUT$(1) 'WAIT
      DISPLAY=1
    END IF
   P=LOF(1)/Z
   FOR I=0 TO P 'LOF(1)
   GET$ #1,Z,G$
   PUT$ #2, G$
   NEXT I
   FOR I=1 TO K
   PUT$ #2, CHR$(0)
   NEXT I
   CLOSE #1
   MAKEFILEEXIT:
   RETURN

      生成的 ALL.WAV 就是一個有結構的文件,每個音符所占用的扇區一樣,將音符好碼乘上扇區數就能直接到該扇區把音符的字節取出,用單片機的PWM或外接DAC就能播放出來。



參數:
EACH NOTE NEED: 1469  SECTORS
TOTAL IN NEW FILE= 60963.5 KB
TOTAL SECTOR= 121927


回復

使用道具 舉報

8#
ID:147710 發表于 2021-9-30 12:00 | 只看該作者
很多年前用電腦玩過MIDI,音色不錯,文件又小,看到大佬的帖子,手癢癢,準備弄片SAM2695玩玩,看那封裝,真有點猶豫,大佬的音源是放在SD卡里么
回復

使用道具 舉報

9#
ID:283954 發表于 2021-9-30 16:32 | 只看該作者
MIDI文件很小,只是記錄音符和音符的時長,但要播放出好聲音,要有好的音源,現在都用軟音源,聲音還不錯,sam2695原本是打算給玩具用的,意外成功,但音色不佳,不能用來當演奏用,玩玩可以。這晶片太小,手工焊接很難成功,我做了10片只有7片有聲音,打算驗證線路正確后,讓廠家小批量生產。

我把經過格式化的音源文件存入SD卡后,用單片機載入大容量RAM再播放出來。
回復

使用道具 舉報

10#
ID:887734 發表于 2021-10-1 10:45 | 只看該作者
2012年用stc11f02單片機做過midi 的播放程序,midi文件存儲在EEROM 25P40里面,參考的是一本日文雜志上的文章,由于單片機資源有限只做了一個鋼琴音色,2個通道,聲音效果一般,不過midi音樂文件要簡化到2個通道才能用。
附件的文件是效果音,以前的東西好多資料都沒有了,看樓主都東西比我的要好太多了。

回復

使用道具 舉報

11#
ID:283954 發表于 2021-10-2 03:46 | 只看該作者
syjldz 發表于 2021-10-1 10:45
2012年用stc11f02單片機做過midi 的播放程序,midi文件存儲在EEROM 25P40里面,參考的是一本日文雜志上的文 ...

市售的音源必須至少有16個聲道,必須能同時發24個音以上,還要有128種樂器的聲音。這不是一般的單片機能做到,而且必須能對幾十種控制訊號做反應,對CPU的運算能力要求很高。所以你用STC單片機做的只能2聲道,1種樂器。
市面通行的音源芯片只有三顆:SAM2695, VS1053B, CS9326,我都有做過,但聲音都不滿意,很多樂器的聲音都不像,不能作為表演用,因此我必須從最底層做起,連音色文件都要自己制作才行。
回復

使用道具 舉報

12#
ID:887734 發表于 2021-10-2 06:29 | 只看該作者
附件里是2通道一種音色的聲音效果,見笑了,stc11f02的性能確實有限。

01.rar

3.46 MB, 下載次數: 10, 下載積分: 黑幣 -5

2通道示例音頻

回復

使用道具 舉報

13#
ID:283954 發表于 2021-10-2 16:54 | 只看該作者
syjldz 發表于 2021-10-2 06:29
附件里是2通道一種音色的聲音效果,見笑了,stc11f02的性能確實有限。

聽起來還很不錯,而且是兩個聲部,同時發兩個音,那就是有multitasking的能力,估計再多幾個聲部MCU就來不及了,不過現在MCU速度快多了,可以再嘗試,有四個聲部就有實用價值了,因為一個和弦必須用四個音組成。

音源開發還有另一條路線圖,就是采用網上易得的SOUNDFONT格式,文件后輟是.sf2,原理是長音符都采用重復播放部分的方式,所以文件很小,128種樂器就30M,而聲音也不錯了。你若能寫個能解讀.SF2的代碼,就能造出完整的音源,而不必用我這個笨方法了。

這是用.SF2演奏的: hsymp3.zip (4.94 MB, 下載次數: 17)
回復

使用道具 舉報

14#
ID:887734 發表于 2021-10-2 22:31 | 只看該作者
用單片機玩解碼midi音樂播放的人不多,要有音樂和單片機的多方位能力,樓主的東西很扎實,很好,學習了。
要是能年輕10歲我一定好好研究一下這個東西。我是60后,玩不動了,呵呵。。。

回復

使用道具 舉報

15#
ID:992668 發表于 2021-12-15 12:15 | 只看該作者
玩單片機也玩midi的人很少,方便加個
回復

使用道具 舉報

16#
ID:283954 發表于 2021-12-18 15:32 | 只看該作者
你好!我玩單片機是為了解決電子樂器無法用來組織交響樂隊的難題,市面賣的電子琴功能很多,音質差,但容易銷售,我稱之為“市場導向型”,我要的電子琴是聲音要好,演奏者能自然控制音量,彎音等,表達情感,我稱為“藝術導向型”,這樣的琴商家是不會生產的,因為賣不多,無法營運,所以只能自己做,這是我用市售的37鍵電子琴改裝的琴,整個控制器拆掉,換成用STC15+STC12做的控制器:



有了這個琴,就能讓四個鍵盤手組成弦樂四重奏。

目前要解決的是音源,音源IC最便宜的是sam2695,¥15,做了7個,聲音很差,玩玩可以,用來舞臺演奏就對不起觀眾了,所以又得用STC8自己做了。

回復

使用道具 舉報

17#
ID:283954 發表于 2021-12-25 18:20 | 只看該作者
單片機音源已經DIY了30片,夠用了,但音符轉換時會出現POP聲,為了解決這個問題,必須對音頻的波形進行處理,這就必須作16BITS帶符號的運算,網上找資料來學,始終搞不通,干脆主動出擊,寫個軟件生成WAV文件,再用GOLDWAVE打開來看,這下就完全清楚了,制了個圖放在網上,就不會忘記了。



回復

使用道具 舉報

18#
ID:283954 發表于 2021-12-29 17:50 | 只看該作者
      制作單片機音源原本以為不必涉及負數運算,只需把VELOCITY的數字0-127輸出到音量控制IC就可控制的音量大小,免去復雜的運算,但結果控制不那么順滑,所以就想嘗試把波形直接減幅,每組數據都要16位X8位的一次除數運算和一次乘數運算,每秒要進行44K次,不知道這單片機是否來得及,先用PB軟件模擬一下運算過程,正數還容易理解,負數就頭大了,原本以為,負數越大,幅度就越大,模擬的結果卻完全相反,無所謂啦,用單片機只要加多幾步也能實現,這是模擬程序和產生的波形圖。


CLS

OPEN "LEARN2.WAV" FOR BINARY AS #1
CLOSE #1
KILL "LEARN2.WAV

OPEN "LEARN2.WAV" FOR BINARY AS #1
SS%=32767       '01111111 11111111 POSITIVE MAX
SS%=SS%/127     'EACH VELOCITY PART

FOR K%=0 TO 127
S%=SS%*K%
FOR I=1 TO 1
PUT$ #1, CHR$(S% MOD 256)+CHR$(S%\256)
NEXT I
NEXT K%

SS%=-32768      '11111111 11111111 NEGATIVE MAX
SS%=SS%+32767+1  
SS%=(SS%+32767)/127 'EACH VELOCITY PART

FOR K%=0 TO 127
J%=127-K%
S%=SS%*J%
FOR I=1 TO 1
PUT$ #1, CHR$(S% MOD 256)+CHR$(S%\256+128)
NEXT I
NEXT K%
CLOSE #1

PRINT "END"



回復

使用道具 舉報

19#
ID:495990 發表于 2022-1-4 09:46 | 只看該作者
樓主很牛,這要有相當的音樂專業知識才能看得懂哦!
回復

使用道具 舉報

20#
ID:106060 發表于 2022-1-16 16:20 | 只看該作者
如果真的想做,51單片機可能真的無法滿足你們的要求,有個DSP或者FPGA了解一下。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 瑟瑟视频在线看 | 国产精品久久久久久久久久免费看 | 成人在线看片 | 91视频进入 | 一区二区三区在线观看免费视频 | 亚洲精品视频在线播放 | 国产在线观看 | 91精品国产91久久久久久吃药 | 国产美女网站 | 碰碰视频 | 粉嫩国产精品一区二区在线观看 | 国产黄色小视频在线观看 | 欧美日韩久久精品 | 午夜视频网站 | 亚洲精品在线观看视频 | 一级片片 | 欧美日韩高清 | 精品国产乱码一区二区三区 | 国产日韩欧美精品一区二区三区 | 成人国产精品免费观看 | 一区二区三区免费 | 黄色在线免费观看视频 | 91精品麻豆日日躁夜夜躁 | 国产精品区二区三区日本 | 99视频在线免费观看 | 四虎影视一区二区 | 狠狠插狠狠操 | 欧美国产日韩精品 | 97av视频在线观看 | 国产在线视频在线观看 | 国产视频一区二区 | 日日操操操 | 久久久久久久久久久福利观看 | 亚洲激情在线观看 | 日韩精品无码一区二区三区 | 国产精品久久精品 | 欧美手机在线 | 精品久久精品 | 欧美成人h版在线观看 | 久久久久久av | 色综合天天天天做夜夜夜夜做 |