23 May '13 - 18:24 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: BASSWMA Music Stream  (Read 347 times)
Oli_Mo
Posts: 2


« on: 30 Jun '12 - 22:05 »
Reply with quoteQuote

Hey guys,

I have a question about the topic mentioned in the title.

My Problem: I'm trying to stream music files with BASSWMA like an internet radio application does.
So I coded an application in which you can choose a file to stream.
Everything works fine ... except of the fact that if I open this stream in VLC Player I can't hear anyhing!
But the strange thing is that VLC Player can connect and doesn't fire any errorcode!

Here is my code for you understanding my problem better and hopefully tell me the solution I'm searching for Cheesy.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    ComboBox1: TComboBox;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    ComboBox2: TComboBox;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  outdev: DWORD;        // Output Device
  chan: HSTREAM;        // Output Channel
  ehandle: HWMENCODE;   // encoder handle

const
  SAMPLERATE = 44100;
  CHANNELS = 2;

implementation

{$R *.dfm}

function StreamingCallback(chan: HSTREAM; buffer: Pointer; length: DWORD; user: DWORD): BOOL; stdcall;
begin
  // encode the sample data
  Result := BASS_WMA_EncodeWrite(ehandle, buffer, length);
end;

procedure ClientConnect(handle: HWMENCODE; connect: BOOL; ip: PChar; user: DWORD); stdcall;
begin
  if (connect) then
  begin
    showMessage(PChar(ip));
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  ADeviceInfo: BASS_DEVICEINFO;
begin
// check the correct BASS was loaded
if (HIWORD(BASS_GetVersion) <> BASSVERSION) then
begin
MessageBox(0,'An incorrect version of BASS.DLL was loaded',nil,MB_ICONERROR);
Halt;
end;

  i := 1;
  while BASS_GetDeviceInfo(I, ADeviceInfo) do
  begin
    ComboBox1.Items.Add(ADeviceInfo.name);
    i := i + 1;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    BASS_StreamFree(chan);
    BASS_SetDevice(outdev);
    Chan := BASS_StreamCreateFile(False, PChar(OpenDialog1.FileName), 0, 0, BASS_SAMPLE_LOOP {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
    if (chan = 0) then
    begin
      MessageBox(0, 'Can''t play the file', nil, MB_ICONERROR);
      Exit;
    end;
    BASS_ChannelPlay(chan, False);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  bitrates: PDWORD;
begin
  outdev := ComboBox1.ItemIndex+1;

  if (not BASS_Init(outdev, 44100, 0, Handle, nil)) then
  begin
    MessageBox(0, PChar('Cant''t initialize device 1' + #13#10 + 'Error #' + IntToStr(BASS_ErrorGetCode)), nil, MB_ICONERROR);
    Halt;
  end else
  begin
    ShowMessage('Device Init successful');
    // get the available bitrates
    bitrates := BASS_WMA_EncodeGetRates(SAMPLERATE, CHANNELS, 0);
    if (bitrates = nil) then
    begin
      MessageBox(0, 'Can''t find codec', 'Error', 0);
      Halt;
    end
    else
    begin
      while (bitrates^ <> 0) do
      begin
        ComboBox2.Items.Add(IntToStr(bitrates^));
        Inc(bitrates);
      end;
    end;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  if (BASS_ChannelIsActive(chan) = 0) then
    showMessage('Not Active')
  else
    showMessage('Active');
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  // initialize encoder - port 8485, max 5 clients
  // or port 0 to let system choose port
  ehandle := BASS_WMA_EncodeOpenNetwork(SAMPLERATE, CHANNELS, BASS_WMA_ENCODE_SCRIPT, strtoint(combobox2.Text), 8485, 5);

  if (ehandle = 0) then
    MessageBox(0, 'Can''t initialize encoding', 'Error', 0)
  else
  begin
    ShowMessage('Encoder Init successful');
    // songtitle can be changed to the actual name
    BASS_WMA_EncodeSetTag(ehandle, 'Title', 'songtitle', BASS_WMA_TAG_ANSI); // set WMA title tag
    BASS_WMA_EncodeSetNotify(ehandle, @ClientConnect, 0); // setup client notification
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  BASS_SetDevice(outdev);
  BASS_Free;
  BASS_WMA_EncodeClose(ehandle); // incase it was encoding on exit
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    BASS_StreamFree(chan);
    BASS_SetDevice(outdev);
    // LOOK AT THE FOLLOWING LINE, IS THIS CORRECT?
    chan := BASS_StreamCreate(SAMPLERATE, CHANNELS, 0, @StreamingCallback, 0);
    //BASS_StreamCreateFile(False, PChar(OpenDialog1.FileName), 0, 0, BASS_SAMPLE_LOOP {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
    //BASS_StreamCreate(SAMPLERATE, CHANNELS, 0, @StreamingCallback, 0);
    BASS_ChannelPlay(chan, false);
    if (chan = 0) then
    begin
      MessageBox(0, 'Can''t start streaming', 'Error', 0);
      BASS_WMA_EncodeClose(ehandle);
    end else
    begin
      ShowMessage('Streaming Start successful');
    end;
  end;
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  BASS_ChannelStop(chan);
end;

procedure TForm1.Button7Click(Sender: TObject);
var
  pos: integer;
begin
    pos := BASS_ChannelGetPosition(ehandle, BASS_POS_BYTE);
    ShowMessage(IntToStr(pos));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Application.Terminate;
end;

end.

I think the mistake is somewhere in the following code:
function StreamingCallback(chan: HSTREAM; buffer: Pointer; length: DWORD; user: DWORD): BOOL; stdcall;
begin
  // encode the sample data
  Result := BASS_WMA_EncodeWrite(ehandle, buffer, length);
end;

// ...

procedure TForm1.Button5Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    BASS_StreamFree(chan);
    BASS_SetDevice(outdev);
    // LOOK AT THE FOLLOWING LINE, IS THIS CORRECT?
    chan := BASS_StreamCreate(SAMPLERATE, CHANNELS, 0, @StreamingCallback, 0);
    //BASS_StreamCreateFile(False, PChar(OpenDialog1.FileName), 0, 0, BASS_SAMPLE_LOOP {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
    //BASS_StreamCreate(SAMPLERATE, CHANNELS, 0, @StreamingCallback, 0);
    BASS_ChannelPlay(chan, false);
    if (chan = 0) then
    begin
      MessageBox(0, 'Can''t start streaming', 'Error', 0);
      BASS_WMA_EncodeClose(ehandle);
    end else
    begin
      ShowMessage('Streaming Start successful');
    end;
  end;
end;

Best regards, Oli_Mo
Logged
Ian @ un4seen
Administrator
Posts: 15270


« Reply #1 on: 2 Jul '12 - 15:02 »
Reply with quoteQuote

Yep, the problem is indeed in how you are feeding the WMA encoder. That can be done via a DSP function set on the stream that was created by the BASS_StreamCreateFile call (no need for the BASS_StreamCreate stream), something like this...

BASS_ChannelSetDSP(Chan, @StreamingDSP, 0, -1); // set a DSP function to feed the WMA encoder

...

procedure StreamingDSP(handle: HDSP; channel: DWORD; buffer: Pointer; length: DWORD; user: Pointer); stdcall;
begin
  // encode the sample data
  BASS_WMA_EncodeWrite(ehandle, buffer, length);
end;

When you want to move the encoder to another stream, you can call BASS_ChannelRemoveDSP to remove the DSP function from the old stream and call BASS_ChannelSetDSP on the new stream. Note the streams should have the same sample format as the WMA encoder, as specified in the BASS_WMA_EncodeOpenNetwork call. If they don't, you could use the BASSmix add-on to have them converted to the correct format... create a mixer with the wanted format (via BASS_Mixer_StreamCreate) and plug the streams into the mixer to play them (via BASS_Mixer_StreamAddChannel). Note you would need to add the BASS_STREAM_DECODE flag to the BASS_StreamCreateFile calls to make the streams "decoding channels".

Please see the documentation for details on all of the aforementioned stuff.
Logged
Oli_Mo
Posts: 2


« Reply #2 on: 6 Jul '12 - 15:59 »
Reply with quoteQuote

okay thanks!

Oli_Mo
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines