Author Topic: CHANNEL MIXING  (Read 5664 times)

hedgehog

  • Posts: 34
CHANNEL MIXING
« on: 2 Jun '03 - 18:08 »
hi to all,
there's someone who knows how to mix some channels togheter and play (or write on a file) the result?
thanx Hh

Ingolf

  • Posts: 81
Re: CHANNEL MIXING
« Reply #1 on: 5 Jun '03 - 11:47 »
Get the data of all the channels using BASS_ChannelGetData into seperate buffers, and then add everything up to a master buffer. I have done this myself, but it is to complicated to post it here, as my functions use lots of other functions, that call other functions, etc.

If you want to play the data, do as above, but instead write it to a custom stream.
« Last Edit: 5 Jun '03 - 11:48 by Ingolf »

bigjim

  • Posts: 232
Re: CHANNEL MIXING
« Reply #2 on: 5 Jun '03 - 17:47 »
Heres some code which was discussed in an earlier thread- translated from c++ if I remeber right.

Its a delphi unit consisting of a form(form1) and a button (button1)

Code: [Select]

unit mix2;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Bass,
 StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 type
 fakear = array[0..1] of smallint; //fake array to assign to callback buffer

var
 Form1: TForm1;
handles : array[0..20] of dword; // array to hold the channel handles
// mixbuf : array of dword; // a dynamic array for the mixing buffer
no_of_channels : integer; // the number of streams
mixgain : float;
// buffa : ^fakear; // a pointer to the real buffer- but an array type


implementation

{$R *.DFM}

function Mixit(handle: HSTREAM; buffer: Pointer; length: DWORD; user: DWORD): DWORD; stdcall;
var
buf: ^fakear;
mixbuf: array of float;
a,b,c: integer;
begin
// allocate mixing buffer
setlength(mixbuf,length div 2);
ZeroMemory(mixbuf,(length div 2)*4);

// mix the decoding channels
buf:=buffer;
for a:=0 to no_of_channels-1 do begin
  // may as well use "buffer" for temp storage :)
  b:=BASS_ChannelGetData(handles[a],buffer,length);
  for c:=0 to (b div 2)-1 do mixbuf[c]:= mixbuf[c]+buf[c];
end;

// put the final mix into "buffer"
for a:=0 to (length div 2)-1 do begin
  b:= trunc(mixbuf[a] * mixgain);
  if b>32767 then b:=32767;
  if b<-32768 then b:=-32768;
  buf[a]:=b;
end;

mixbuf:=nil;
Mixit:=length;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Bass_streamPlay(handles[2], FALSE, 0); // Play the custom stream
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Bass_Init(-1,44100,0, form1.handle); //init bass on default device
Bass_start; //start bass
handles[0] := Bass_StreamCreateFile(FALSE, pChar('one.mp3'), 0, 0, BASS_STREAM_DECODE); //load file 1
handles[1] := Bass_StreamCreateFile(FALSE, pChar('two.mp3'), 0, 0, BASS_STREAM_DECODE); //load file 2
no_of_channels := 2; // set the number of files loaded to 2
Bass_streamPlay(handles[0], FALSE, 0); // start the first file
Bass_streamPlay(handles[1], FALSE, 0); // start the second file
handles[2] := BASS_StreamCreate(44100, 0, @Mixit, 0); // Create a custom stream
mixgain := 1.0;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Bass_Free;
end;

end.

Ingolf

  • Posts: 81
Re: CHANNEL MIXING
« Reply #3 on: 5 Jun '03 - 17:53 »
That's it!

hedgehog

  • Posts: 34
Re: CHANNEL MIXING
« Reply #4 on: 5 Jun '03 - 18:52 »
thanx a lot guys!!! i'll try as soon as possible this code!I want to try some effects on every channel too, kinda volume, bass & trebble, pan. Do you think this add-on will destroy my CPU? (all must be at real time, like real mixers!!!)
thanx Hh

CatHerder454

  • Posts: 12
Re: CHANNEL MIXING
« Reply #5 on: 5 Jun '03 - 23:46 »
could someone tell me how to do this in VB?  ;D

thanks

hedgehog

  • Posts: 34
Re: CHANNEL MIXING
« Reply #6 on: 7 Jun '03 - 11:43 »
this is a simple variation on your great decode function:
Code: [Select]

function Mixit(handle: HSTREAM; buffer: Pointer; length: DWORD; user: DWORD): DWORD; stdcall;
var
buf: ^fakear;
mixbuf: array of float;
a,b,c: integer;
x:float;
begin
// allocate mixing buffer
setlength(mixbuf,length div 2);
ZeroMemory(mixbuf,(length div 2)*4);

// mix the decoding channels
buf:=buffer;
for a:=0 to no_of_channels-1 do begin
 // may as well use "buffer" for temp storage :)
 b:=BASS_ChannelGetData(handles[a],buffer,length);

 for c:=0 to (b div 2)-1 do
 begin
 x:=buf[c];//new
 x:=x*mixgain[a];//new
 mixbuf[c]:= mixbuf[c]+x;
 end;
end;

by adding a mixgain to every channel (
Code: [Select]
mixgain :array[0..20] of float;) you can set volume of every channel is mixed, now should be interest put an EQ to every single channel.. sholub be easy???  ???

VB translation is simple, take a look to VB examples given with bass...

Ingolf

  • Posts: 81
Re: CHANNEL MIXING
« Reply #7 on: 11 Jun '03 - 15:05 »
I have made an equalizer by using the FFT algoritm, but it is not as easy as you think.

To make it easier for us, Microsoft has built-in an parametric equalizer into DirectX, which you can use in BASS (look in the help file, or this forum, for BASS_ChannelSetFX etc.)

Then by creating multiple param eq's, you have a multi-band equalizer, or whatever.