FPGA+PC1500,现代加古董组合实现VGM音乐电路设计和Verilog/VHDL编程。
全手搓数码音乐和数码语音识别技术加上自创midi编曲,还有Verilog硬件编程的vgm音乐低成本播放器-竟然因为采用了FPGA四代和DSP处理器而达到了PC1500破烂古董数码应用的天花板。所谓低成本:FPGA主板/25元+FPGA芯片EP4CE10F17/60元+音源芯片SAA1099/3元+YM2163/7元+YM2608B/12元+PC1500主机/68元,不到200元。还有焊接调试软件开发等不划算。
除了PC1500使用BASIC和汇编二种语言编程,最厉害的编程方案当属Verilog/VHDL硬件编程语言,而vgm格式音乐是典型的游戏音乐边编解码格式,要实现低成本播放器,采用了FPGA四代和DSP处理器而达到了PC1500古董电脑。所谓低成本:FPGA主板/25元+FPGA芯片EP4CE6E22C8/60元+音源芯片SAA1099/3元+YM2163/7元+YM2608B/12元+PC1500主机/68元,不到200元。还有焊接调试软件开发等,似乎不划算?
幸好功能强大的FPGA不止可以做音乐解码器和音乐包络线编程器鼓点和弦等随便我编程控制,还实现了比玩音源芯片更高级别的语音和图像识别技术!有了万能芯片FPGA,可能就没有学不会做不到的。这才是我的展示低成本超高价值所在。
PC1500+FPGA四代芯片EP4CE6E22C8+万能插座的可多型号音源芯片,展示飞利浦SAA1099P和雅马哈YM2163音源芯片的,采用Verilog硬件语言编程进行.vgm格式的音乐解码程序示例一,以及采用第二种VHDL硬件语言编程的DAC数模转换和FM调制解调程序示例二。
示例一:
```verilog
module VGM_Decoder (
input [7:0] vgm_data,
input vgm_clk,
input vgm_rst,
output [15:0] audio_data,
output audio_valid
);
// 寄存器状态
reg [15:0] sample_counter;
reg [7:0] command;
reg [15:0] data;
reg [7:0] wait;
reg [7:0] index;
reg [7:0] dac_value;
reg audio_data_valid;
// 解码器状态
reg [2:0] state;
parameter IDLE = 0;
parameter WAIT_COMMAND = 1;
parameter WAIT_DATA = 2;
always @(posedge vgm_clk) begin
if (vgm_rst) begin
state 0) begin
wait = audio_data) begin
dac_output = 255) begin
sample_count = 180) begin
audio_data = audio_data) begin
audio_out = 255) begin
audio_count '0');
analog_out '0');
fm_audio '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase '0');
audio_out '0');
analog_out '0');
fm_audio '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase '0');
audio_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
audio <= audio_in;
audio_out <= '1';
else
audio_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
```
以下是使用HDL编程,FPGA的DAC、FM解调器和音频输出模块:
```vhdl
-- DAC模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DAC is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16 -- 采样位数
);
port(
clk : in std_logic;
reset : in std_logic;
data_in : in signed(BITS_PER_SAMPLE-1 downto 0);
analog_out : out std_logic
);
end entity DAC;
architecture behavioral of DAC is
signal counter : integer range 0 to SAMPLE_RATE-1;
signal sample : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
counter <= 0;
sample <= (others => '0');
analog_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
sample <= data_in;
analog_out <= '1';
else
analog_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
-- FM解调器模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FM_Demodulator is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16, -- 采样位数
CARRIER_FREQ : integer := 1000 -- 载波频率
);
port(
clk : in std_logic;
reset : in std_logic;
if_signal : in std_logic;
fm_audio_out : out signed(BITS_PER_SAMPLE-1 downto 0)
);
end entity FM_Demodulator;
architecture behavioral of FM_Demodulator is
signal phase : unsigned(31 downto 0);
signal fm_audio : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
phase <= (others => '0');
fm_audio <= (others => '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase <= phase + unsigned(to_unsigned(CARRIER_FREQ, 32) * 2 * 3.14159 /
to_unsigned(SAMPLE_RATE, 32));
end if;
fm_audio <= to_signed(to_integer(fm_audio) +
(to_integer(if_signal) * integer(to_signed(round(8191 * sin(real(phase)))))), BITS_PER_SAMPLE);
end if;
end process;
fm_audio_out <= fm_audio;
end architecture behavioral;
-- 音频输出模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Audio_Output is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16 -- 采样位数
);
port(
clk : in std_logic;
reset : in std_logic;
audio_in : in signed(BITS_PER_SAMPLE-1 downto 0);
audio_out : out std_logic
);
end entity Audio_Output;
architecture behavioral of Audio_Output is
signal counter : integer range 0 to SAMPLE_RATE-1;
signal audio : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
counter <= 0;
audio <= (others => '0');
audio_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
audio <= audio_in;
audio_out <= '1';
else
audio_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
```
下次发个原创的采用树莓派4B,用Python语言编程,在Windows电脑以及手机(手机用的Python是扇贝编程app)实现的控制SAA1099和YM2608B音源芯片编程乐曲的程序。
FPGA+PC1500,现代加古董组合实现VGM音乐电路设计和Verilog/VHDL编程。
全手搓数码音乐和数码语音识别技术加上自创midi编曲,还有Verilog硬件编程的vgm音乐低成本播放器-竟然因为采用了FPGA四代和DSP处理器而达到了PC1500破烂古董数码应用的天花板。所谓低成本:FPGA主板/25元+FPGA芯片EP4CE10F17/60元+音源芯片SAA1099/3元+YM2163/7元+YM2608B/12元+PC1500主机/68元,不到200元。还有焊接调试软件开发等不划算。
除了PC1500使用BASIC和汇编二种语言编程,最厉害的编程方案当属Verilog/VHDL硬件编程语言,而vgm格式音乐是典型的游戏音乐边编解码格式,要实现低成本播放器,采用了FPGA四代和DSP处理器而达到了PC1500古董电脑。所谓低成本:FPGA主板/25元+FPGA芯片EP4CE6E22C8/60元+音源芯片SAA1099/3元+YM2163/7元+YM2608B/12元+PC1500主机/68元,不到200元。还有焊接调试软件开发等,似乎不划算?
幸好功能强大的FPGA不止可以做音乐解码器和音乐包络线编程器鼓点和弦等随便我编程控制,还实现了比玩音源芯片更高级别的语音和图像识别技术!有了万能芯片FPGA,可能就没有学不会做不到的。这才是我的展示低成本超高价值所在。
PC1500+FPGA四代芯片EP4CE6E22C8+万能插座的可多型号音源芯片,展示飞利浦SAA1099P和雅马哈YM2163音源芯片的,采用Verilog硬件语言编程进行.vgm格式的音乐解码程序示例一,以及采用第二种VHDL硬件语言编程的DAC数模转换和FM调制解调程序示例二。
示例一:
```verilog
module VGM_Decoder (
input [7:0] vgm_data,
input vgm_clk,
input vgm_rst,
output [15:0] audio_data,
output audio_valid
);
// 寄存器状态
reg [15:0] sample_counter;
reg [7:0] command;
reg [15:0] data;
reg [7:0] wait;
reg [7:0] index;
reg [7:0] dac_value;
reg audio_data_valid;
// 解码器状态
reg [2:0] state;
parameter IDLE = 0;
parameter WAIT_COMMAND = 1;
parameter WAIT_DATA = 2;
always @(posedge vgm_clk) begin
if (vgm_rst) begin
state 0) begin
wait = audio_data) begin
dac_output = 255) begin
sample_count = 180) begin
audio_data = audio_data) begin
audio_out = 255) begin
audio_count '0');
analog_out '0');
fm_audio '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase '0');
audio_out '0');
analog_out '0');
fm_audio '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase '0');
audio_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
audio <= audio_in;
audio_out <= '1';
else
audio_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
```
以下是使用HDL编程,FPGA的DAC、FM解调器和音频输出模块:
```vhdl
-- DAC模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DAC is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16 -- 采样位数
);
port(
clk : in std_logic;
reset : in std_logic;
data_in : in signed(BITS_PER_SAMPLE-1 downto 0);
analog_out : out std_logic
);
end entity DAC;
architecture behavioral of DAC is
signal counter : integer range 0 to SAMPLE_RATE-1;
signal sample : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
counter <= 0;
sample <= (others => '0');
analog_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
sample <= data_in;
analog_out <= '1';
else
analog_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
-- FM解调器模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FM_Demodulator is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16, -- 采样位数
CARRIER_FREQ : integer := 1000 -- 载波频率
);
port(
clk : in std_logic;
reset : in std_logic;
if_signal : in std_logic;
fm_audio_out : out signed(BITS_PER_SAMPLE-1 downto 0)
);
end entity FM_Demodulator;
architecture behavioral of FM_Demodulator is
signal phase : unsigned(31 downto 0);
signal fm_audio : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
phase <= (others => '0');
fm_audio <= (others => '0');
elsif rising_edge(clk) then
if if_signal = '1' then
phase <= phase + unsigned(to_unsigned(CARRIER_FREQ, 32) * 2 * 3.14159 /
to_unsigned(SAMPLE_RATE, 32));
end if;
fm_audio <= to_signed(to_integer(fm_audio) +
(to_integer(if_signal) * integer(to_signed(round(8191 * sin(real(phase)))))), BITS_PER_SAMPLE);
end if;
end process;
fm_audio_out <= fm_audio;
end architecture behavioral;
-- 音频输出模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Audio_Output is
generic(
SAMPLE_RATE : integer := 48000; -- 采样率
BITS_PER_SAMPLE : integer := 16 -- 采样位数
);
port(
clk : in std_logic;
reset : in std_logic;
audio_in : in signed(BITS_PER_SAMPLE-1 downto 0);
audio_out : out std_logic
);
end entity Audio_Output;
architecture behavioral of Audio_Output is
signal counter : integer range 0 to SAMPLE_RATE-1;
signal audio : signed(BITS_PER_SAMPLE-1 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
counter <= 0;
audio <= (others => '0');
audio_out <= '0';
elsif rising_edge(clk) then
if counter = 0 then
audio <= audio_in;
audio_out <= '1';
else
audio_out <= '0';
end if;
counter <= (counter + 1) mod SAMPLE_RATE;
end if;
end process;
end architecture behavioral;
```
下次发个原创的采用树莓派4B,用Python语言编程,在Windows电脑以及手机(手机用的Python是扇贝编程app)实现的控制SAA1099和YM2608B音源芯片编程乐曲的程序。