Mezclar dos señales de audio.
Mezclar dos señales de audio.
Preparando los cores arcades para el futuro addon jamma de antonio, necesitaba mezclar los dos canales de sonido del galaxian., ya que utiliza un dac para los sonkdos generados y otro para los samples, y los saca independientes cada uno por un canal del stereo del zxuno... El caso es que jamma solo tiene mono y x ma vueltas que le doy no lo consigo.
Lo he intentado con un and en las dos salidas del los dacs... Y me mezcla mucho ruido en la salida, y tambien lo he intentado mezclando los datos que van a la entrada del dac (dos señales de 8 bits) antes de meterlos al dac, pero nada... Consigo reducir los ruidos, pero no doy con la formula correcta.
Alguien me podria echar una mano y decirme ¿como mezclar las dos señales de sonido?. Me valdría si es antes o después de pasar x el dac, eso me da igual.... La señal como he dicho es un vector de 8 bits (antes de que pase x el dac y la convierta a señal de salida).
Muchas gracias, a ver si alguien me ayuda, no pensaba que esto de mezclar sonido era tan difícil, después de haber visto a kiko rivera [emoji2]
Añado los datos del fuente relevantes:
signal W_DAC_A : std_logic := '0';
signal W_DAC_B : std_logic := '0';
signal W_SDAT_A : std_logic_vector( 7 downto 0) := (others => '0');
signal W_SDAT_B : std_logic_vector( 7 downto 0) := (others => '0');
mc_sound_a : entity work.MC_SOUND_A
port map(
I_CLK_12M => W_CLK_12M,
I_CLK_6M => W_CLK_6M,
I_H_CNT1 => W_H_CNT(1),
I_BD => W_BDI,
I_PITCHn => W_PITCHn,
I_VOL1 => W_VOL1,
I_VOL2 => W_VOL2,
O_SDAT => W_SDAT_A,
O_DO => open
);
mc_sound_b : entity work.MC_SOUND_B
port map(
I_CLK1 => W_CLK_6M,
I_RSTn => rst_count(3),
I_SW => new_sw,
I_DAC => W_DAC,
I_FS => W_FS,
O_SDAT => W_SDAT_B
);
wav_dac_a : entity work.dac
port map(
clk_i => W_CLK_18M,
res_n_i => W_RESETn,
dac_i => W_SDAT_A,
dac_o => W_DAC_A
);
wav_dac_b : entity work.dac
port map(
clk_i => W_CLK_18M,
res_n_i => W_RESETn,
dac_i => W_SDAT_B,
dac_o => W_DAC_B
);
(dac.vhd)
-------------------------------------------------------------------------------
--
-- Delta-Sigma DAC
--
-- $Id: dac.vhd,v 1.1 2006/05/10 20:57:06 arnim Exp $
--
-- Refer to Xilinx Application Note XAPP154.
--
-- This DAC requires an external RC low-pass filter:
--
-- dac_o 0---XXXXX---+---0 analog audio
-- 3k3 |
-- === 4n7
-- |
-- GND
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DAC is
generic (
msbi_g : integer := 7
);
port (
clk_i : in std_logic;
res_n_i : in std_logic;
dac_i : in std_logic_vector(msbi_g downto 0);
dac_o : out std_logic
);
end;
architecture RTL of dac is
signal sig_in : unsigned(msbi_g+2 downto 0) := (others => '0');
begin
seq: process (clk_i, res_n_i)
begin
if res_n_i = '0' then
sig_in <= to_unsigned(2**(msbi_g+1), sig_in'length);
dac_o <= '0';
elsif rising_edge(clk_i) then
sig_in <= sig_in + unsigned(sig_in(msbi_g+2) & sig_in(msbi_g+2) & dac_i);
dac_o <= sig_in(msbi_g+2);
end if;
end process seq;
end RTL;
Enviado desde mi ONE A2003 mediante Tapatalk
Lo he intentado con un and en las dos salidas del los dacs... Y me mezcla mucho ruido en la salida, y tambien lo he intentado mezclando los datos que van a la entrada del dac (dos señales de 8 bits) antes de meterlos al dac, pero nada... Consigo reducir los ruidos, pero no doy con la formula correcta.
Alguien me podria echar una mano y decirme ¿como mezclar las dos señales de sonido?. Me valdría si es antes o después de pasar x el dac, eso me da igual.... La señal como he dicho es un vector de 8 bits (antes de que pase x el dac y la convierta a señal de salida).
Muchas gracias, a ver si alguien me ayuda, no pensaba que esto de mezclar sonido era tan difícil, después de haber visto a kiko rivera [emoji2]
Añado los datos del fuente relevantes:
signal W_DAC_A : std_logic := '0';
signal W_DAC_B : std_logic := '0';
signal W_SDAT_A : std_logic_vector( 7 downto 0) := (others => '0');
signal W_SDAT_B : std_logic_vector( 7 downto 0) := (others => '0');
mc_sound_a : entity work.MC_SOUND_A
port map(
I_CLK_12M => W_CLK_12M,
I_CLK_6M => W_CLK_6M,
I_H_CNT1 => W_H_CNT(1),
I_BD => W_BDI,
I_PITCHn => W_PITCHn,
I_VOL1 => W_VOL1,
I_VOL2 => W_VOL2,
O_SDAT => W_SDAT_A,
O_DO => open
);
mc_sound_b : entity work.MC_SOUND_B
port map(
I_CLK1 => W_CLK_6M,
I_RSTn => rst_count(3),
I_SW => new_sw,
I_DAC => W_DAC,
I_FS => W_FS,
O_SDAT => W_SDAT_B
);
wav_dac_a : entity work.dac
port map(
clk_i => W_CLK_18M,
res_n_i => W_RESETn,
dac_i => W_SDAT_A,
dac_o => W_DAC_A
);
wav_dac_b : entity work.dac
port map(
clk_i => W_CLK_18M,
res_n_i => W_RESETn,
dac_i => W_SDAT_B,
dac_o => W_DAC_B
);
(dac.vhd)
-------------------------------------------------------------------------------
--
-- Delta-Sigma DAC
--
-- $Id: dac.vhd,v 1.1 2006/05/10 20:57:06 arnim Exp $
--
-- Refer to Xilinx Application Note XAPP154.
--
-- This DAC requires an external RC low-pass filter:
--
-- dac_o 0---XXXXX---+---0 analog audio
-- 3k3 |
-- === 4n7
-- |
-- GND
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DAC is
generic (
msbi_g : integer := 7
);
port (
clk_i : in std_logic;
res_n_i : in std_logic;
dac_i : in std_logic_vector(msbi_g downto 0);
dac_o : out std_logic
);
end;
architecture RTL of dac is
signal sig_in : unsigned(msbi_g+2 downto 0) := (others => '0');
begin
seq: process (clk_i, res_n_i)
begin
if res_n_i = '0' then
sig_in <= to_unsigned(2**(msbi_g+1), sig_in'length);
dac_o <= '0';
elsif rising_edge(clk_i) then
sig_in <= sig_in + unsigned(sig_in(msbi_g+2) & sig_in(msbi_g+2) & dac_i);
dac_o <= sig_in(msbi_g+2);
end if;
end process seq;
end RTL;
Enviado desde mi ONE A2003 mediante Tapatalk
Re: Mezclar dos señales de audio.
Puedes hacerlo de dos formas:
- Sumando los dos vectores en un tercero un bit más grande para no perder precisión y pasando la suma al DAC.
- Multiplexando las señales. Un contador de 1 bit que cambie con el clock y cuando es cero le pasas al DAC una señal y cuando es 1 la otra.
Tanto el ZX-Uno como mi core usan el método de multiplexar señales.
- Sumando los dos vectores en un tercero un bit más grande para no perder precisión y pasando la suma al DAC.
- Multiplexando las señales. Un contador de 1 bit que cambie con el clock y cuando es cero le pasas al DAC una señal y cuando es 1 la otra.
Tanto el ZX-Uno como mi core usan el método de multiplexar señales.
Re: Mezclar dos señales de audio.
Lo del multiplexado lo probe con la señal de la salida y no me funciono, pero claro, no se me ocurrio hacerlo en la de entrada. Voy a probarlo y mañana te cuento. Muchas gracias.
Enviado desde mi ONE A2003 mediante Tapatalk
Enviado desde mi ONE A2003 mediante Tapatalk
Re: Mezclar dos señales de audio.
El DAC tiene que ser el último paso. Los datos le tienen que llegar ya 'apañaos'
- mcleod_ideafix
- Mensajes: 831
- Registrado: 27 Sep 2015, 00:14
- Ubicación: Jerez de la Frontera
- Contactar:
Re: Mezclar dos señales de audio.
Suponiendo que las señales de entrada (las que van originalmente a cada DAC por separado) son de 8 bits sin signo, una forma de mezclarlas es usando este módulo:
O sea: sumas las dos señales de audio original, y del resultado, de 9 bits, coges los 8 bits más significativos, pero cuidando de invertir el bit más significativo de esos 8 (lo cual es equivalente a sumar 256 a suma).
El método de multiplexar en el tiempo las dos señales de audio quedaría una cosa así:
Aquí se van enviando alternativamente muestras de audio1 y audio2, pero no en cada ciclo de reloj, sino cada 256 ciclos de reloj, para que al DAC le dé tiempo de construir un sample analógico, que le lleva precisamente 256 ciclos de reloj. Este método asume que las señales audio1 y audio2 cambian con mucha menor velocidad que el reloj clk. De hecho, clk debería tener una frecuencia igual o superior a 256 (2^8, o sea, 2 elevado a 8) veces la frecuencia de muestreo que se pretende conseguir en el conversor digital-analógico.
Así, si se sabe que las señales de audio no van a una frecuencia mayor de 10kHz, se muestrean en 8 bits, y hay 2 señales para multiplexar, la frecuencia mínima que se necesita en el DAC (y en este módulo) es de 10000 * 2^8 * 2 = 5.12 MHz.
Código: Seleccionar todo
module mixer (
input wire [7:0] audio1,
input wire [7:0] audio2,
output wire [7:0] mezcla
);
wire [8:0] suma;
assign suma = audio1 + audio2;
assign mezcla = {~suma[8], suma[7:1]};
endmodule
El método de multiplexar en el tiempo las dos señales de audio quedaría una cosa así:
Código: Seleccionar todo
module mixer (
input wire clk, // el mismo reloj que se use en el DAC
input wire [7:0] audio1,
input wire [7:0] audio2,
output reg [7:0] mezcla
);
reg [8:0] cnt = 9'd0;
always @(posedge clk) begin
cnt <= cnt + 9'd1;
if (cnt[8] == 1'b0)
mezcla <= audio1;
else
mezcla <= audio2;
end
endmodule
Así, si se sabe que las señales de audio no van a una frecuencia mayor de 10kHz, se muestrean en 8 bits, y hay 2 señales para multiplexar, la frecuencia mínima que se necesita en el DAC (y en este módulo) es de 10000 * 2^8 * 2 = 5.12 MHz.
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA
Re: RE: Re: Mezclar dos señales de audio.
Perfecto, funciona genial.mcleod_ideafix escribió:Suponiendo que las señales de entrada (las que van originalmente a cada DAC por separado) son de 8 bits sin signo, una forma de mezclarlas es usando este módulo:
O sea: sumas las dos señales de audio original, y del resultado, de 9 bits, coges los 8 bits más significativos, pero cuidando de invertir el bit más significativo de esos 8 (lo cual es equivalente a sumar 256 a suma).Código: Seleccionar todo
module mixer ( input wire [7:0] audio1, input wire [7:0] audio2, output wire [7:0] mezcla ); wire [8:0] suma; assign suma = audio1 + audio2; assign mezcla = {~suma[8], suma[7:1]}; endmodule
El método de multiplexar en el tiempo las dos señales de audio quedaría una cosa así:
Aquí se van enviando alternativamente muestras de audio1 y audio2, pero no en cada ciclo de reloj, sino cada 256 ciclos de reloj, para que al DAC le dé tiempo de construir un sample analógico, que le lleva precisamente 256 ciclos de reloj. Este método asume que las señales audio1 y audio2 cambian con mucha menor velocidad que el reloj clk. De hecho, clk debería tener una frecuencia igual o superior a 256 (2^8, o sea, 2 elevado a 8) veces la frecuencia de muestreo que se pretende conseguir en el conversor digital-analógico.Código: Seleccionar todo
module mixer ( input wire clk, // el mismo reloj que se use en el DAC input wire [7:0] audio1, input wire [7:0] audio2, output reg [7:0] mezcla ); reg [8:0] cnt = 9'd0; always @(posedge clk) begin cnt <= cnt + 9'd1; if (cnt[8] == 1'b0) mezcla <= audio1; else mezcla <= audio2; end endmodule
Así, si se sabe que las señales de audio no van a una frecuencia mayor de 10kHz, se muestrean en 8 bits, y hay 2 señales para multiplexar, la frecuencia mínima que se necesita en el DAC (y en este módulo) es de 10000 * 2^8 * 2 = 5.12 MHz.
Lo he puesto en el modullo top de verilog para multiplexar a la salida (asi no tg que modificar todos los arcades que usan la placa del galaxian) y va de coña.
Muchisimas gracias, sois la releche. [img]https://uploads.tapatalk-cdn.com/201708 ... 6b03e3.jpg[/img]
Enviado desde mi ONE A2003 mediante Tapatalk
Re: Mezclar dos señales de audio.
Interesante apreciación. A ver si esto resuelve un problema que me he encontrado implementando el SpecDrum en mi core.mcleod_ideafix escribió: Aquí se van enviando alternativamente muestras de audio1 y audio2, pero no en cada ciclo de reloj, sino cada 256 ciclos de reloj, para que al DAC le dé tiempo de construir un sample analógico, que le lleva precisamente 256 ciclos de reloj.
Lo mismo digo. Aunque esto es algo más o menos "evidente" (nótense las comillas ) siempre bien bien saber la teoría.mcleod_ideafix escribió: Este método asume que las señales audio1 y audio2 cambian con mucha menor velocidad que el reloj clk. De hecho, clk debería tener una frecuencia igual o superior a 256 (2^8, o sea, 2 elevado a 8) veces la frecuencia de muestreo que se pretende conseguir en el conversor digital-analógico.
Así, si se sabe que las señales de audio no van a una frecuencia mayor de 10kHz, se muestrean en 8 bits, y hay 2 señales para multiplexar, la frecuencia mínima que se necesita en el DAC (y en este módulo) es de 10000 * 2^8 * 2 = 5.12 MHz.