26 May '13 - 07:08 *
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: Encode the stream to OGG and get data in buffer  (Read 4315 times)
VideoLord
Posts: 14


« on: 19 Sep '03 - 13:11 »
Reply with quoteQuote

Hello, Ian!

I need to send sound, recorded from microphone, over the ethernet. I tried to use BASSEnc library to compress recorded sound and then send encoded data to network. But how could I understand, BASSEnc can't get encoded data from the encoder...

Is there _any_ way to encode wave stream to ogg stream ?
Logged
VideoLord
Posts: 14


« Reply #1 on: 22 Sep '03 - 15:58 »
Reply with quoteQuote

Hello again!

I see that here is no replies in this thread.

May be there is a point in adding the ability to connect DLL encoders (bassenc.dll, lame_enc.dll and so on) to BASSEnc.
So it will be possible to send some data to encoder and then get encoded data from it.

With respect to all!
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #2 on: 22 Sep '03 - 18:24 »
Reply with quoteQuote

May be there is a point in adding the ability to connect DLL encoders (bassenc.dll, lame_enc.dll and so on) to BASSEnc.
So it will be possible to send some data to encoder and then get encoded data from it.

If you have a specific format you want to encode to, and there's a DLL available that can already do that, then there's no real need to go via BASSEnc... you can just call the DLL directly? Smiley

Anyway, it should be possible to add an option to receive the encoded data back from BASSEnc (instead of writing it to disk), but I'm not sure what the performance will be like. I'll look into it for the next release.
Logged
VideoLord
Posts: 14


« Reply #3 on: 22 Sep '03 - 20:06 »
Reply with quoteQuote

Okay, I understood that :-)

I really don't need to use some specific format, just OGG. But I need to get encoded OGG data to BASSEnc back, not into file on disk.

Ok, i'll wait for next release of BASSEnc ;-)

And now, I tried to communicate to vorbisenc.dll directly. I can encode data, and I can send it over the network.
On the other side, I receive it and how can I play it back in BASS?

>>>
var FIFO: string;

procedure SocketRead(..)
begin
 FIFO:=FIFO+socket.ReceiveText;
end;

procedure StartPlay;
 strm:=BASS_StreamCreate(SampleRate, BASS_STREAM_FILEPROC, @CallBack_Play, 0);
 BASS_StreamPlay(strm, TRUE, 0);
end;

function StreamFileProc(action, param1, param2, user: DWORD): DWORD; stdcall;
begin
 Result:=0;
 case action of
  BASS_FILE_QUERY: result:=param1;
  BASS_FILE_READ:
  begin
   move(PChar(copy(FIFO, 1, param1))^, pointer(param2)^, param1);
   delete(FIFO, 1, param1);
   result:=param1;
  end;
  BASS_FILE_LEN: result:=0;
  BASS_FILE_CLOSE: result:=0;
 end;
end;

After executing StartPlay procedure, there are only 5 hits in callback procedure StreamFileProc (1st with action = BASS_FILE_LEN and next 4 with BASS_FILE_READ).
There is absolutely no sound at all and after this 5 hits stream is stopped and don't play more...
Logged
VideoLord
Posts: 14


« Reply #4 on: 22 Sep '03 - 20:22 »
Reply with quoteQuote

It reads in StreamFileProc:
action = BASS_FILE_LEN (here I return 0 - read by blocks)

action = BASS_FILE_READ: (here I give wanted number of bytes to BASS)
 param1 = 10;
 param1 = 2;
 param1 = 3998;
 param1 = 12000;

action = BASS_FILE_CLOSE; (and that's all... no more reads)
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #5 on: 22 Sep '03 - 21:47 »
Reply with quoteQuote

That looks like it's not recognised the stream format.

Are you sure you have enough data buffered to fulfill those read requests? You should be checking how much data there is available in the buffer - the same applies with the BASS_FILE_QUERY Smiley

I suggest you have at least 16KB pre-buffered before calling BASS_StreamCreate.

Btw, I've quickly looked into the BASSEnc receiving the encoded data option, and it seems to work quite nicely. So it'll be in the next release Smiley
Logged
VideoLord
Posts: 14


« Reply #6 on: 24 Sep '03 - 14:44 »
Reply with quoteQuote

Okay, there was some error with 0-terminated strings when send data over network.

Now i corrected that code, but have "Division by Zero" exception inside the StreamFileProc, when action=BASS_FILE_READ and param1=12000.

If I save data received from network in OGG-file (using TFileStream) and then open it with BASS_StreamCreateFile, all works OK.

But when I try to load the contents of the same file with
BASS_CreateStream (...BASS_STREAM_FILEPROC...), I get that exception and channel is stopping.

The same error happens when I try to stream data from FIFO buffer in StreamFileProc.
Of course I have more than 16 kb in file and FIFO buffer (nearly 300 kb).

callback procedures:
-----
When streaming from FIFO string:

function StreamFileProc(action, param1: dword; param2:pointer; user: DWORD): DWORD; stdcall;
begin
 Result:=0;
 case action of
  BASS_FILE_QUERY:
  begin
   while length(FIFO)<param1 do Application.ProcessMessages;
   result:=param1;
  end;
  BASS_FILE_READ:
  begin
   move(PChar(Copy(FIFO, 1, param1))^, param2^, param1);
   delete(FIFO, 1, param1);
   result:=param1;
  end;
  BASS_FILE_LEN: result:=0;
  BASS_FILE_CLOSE: result:=0;
 end;
end;


When streaming from saved OGG file:

var         tfs: TFileStream;
function StreamFileProc(action, param1: dword; param2:pointer; user: DWORD): DWORD; stdcall;
begin
 Result:=0;
 case action of
  BASS_FILE_QUERY: result:=param1;
  BASS_FILE_READ:
  begin
   tfs.ReadBuffer(param2^, param1);  
   result:=param1;
  end;
  BASS_FILE_LEN: result:=0;
  BASS_FILE_CLOSE: result:=0;
 end;
end;
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #7 on: 25 Sep '03 - 19:30 »
Reply with quoteQuote

I'm a little unsure here... are you saying that both the above "StreamFileProc" crash, or just the one with the "FIFO string" buffer?

Anyway, here's a few comments Smiley

BASS_FILE_QUERY: There's no need to call ProcessMessages as the function is running in it's own BASS-created thread. You also don't need to wait for the full requested amount - you can return immediately with less (except 0, which means end of file).

BASS_FILE_READ: You should not simply return the requested amount ("param1") without checking that you've actually successfully read that amount.
Logged
VideoLord
Posts: 14


« Reply #8 on: 26 Sep '03 - 17:35 »
Reply with quoteQuote

---
But when I try to load the contents of the same file with
BASS_CreateStream (...BASS_STREAM_FILEPROC...), I get that exception and channel is stopping.

The same error happens when I try to stream data from FIFO buffer in StreamFileProc.
Of course I have more than 16 kb in file and FIFO buffer (nearly 300 kb).
---

Yes, both StreamFileProcs crash when I load that OGG.
but StreamCreateFile - works OK.

How can it be ?
Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #9 on: 28 Sep '03 - 14:29 »
Reply with quoteQuote

Did you correct the BASS_FILE_READ problem? You should return the number of bytes that have been successfully read (not simply the number requested).

If that doesn't sort it, where exactly is it crashing? Please give some details - location/registers/call-stack.
Logged
Irrational86
Posts: 960


« Reply #10 on: 28 Sep '03 - 15:40 »
Reply with quoteQuote

Ian, since the 2.0 version is having a lot of stuff added and modified, i have a little request, why not make the STREAMPROC request X amount of bytes, but if you return 200 bytes less than X for it to still work. What i mean is, if you could make it work like the STREAMPROCFILE one, that even if you return less than it request it still keeps going, and only stop when you return 0 bytes...can that be possible??

[Edit]I think this will reduce a bit of headache when using Winamp plugins and such... Roll Eyes[/Edit]
« Last Edit: 28 Sep '03 - 15:41 by XMinioNX » Logged
Ian @ un4seen
Administrator
Posts: 15276


« Reply #11 on: 29 Sep '03 - 12:52 »
Reply with quoteQuote

The difference between the STREAMPROC and STREAMFILEPROC systems is that STREAMFILEPROC writes data to an intermediate buffer, from where BASS decodes it into the playback buffer as required, while STREAMPROC writes sample data directly to the playback buffer.

As BASS has access to the upcoming data in the STREAMFILEPROC case, it knows how much data is immediately available and can stall/resume accordingly. In the STREAMPROC case, BASS can't know how much data is coming. So the problem is that if you continuously returned less than requested (if BASS allowed it), you could end up with a buffer underrun, and old data in the playback buffer would be repeated.

On the otherhand, automatically stalling/resuming custom streams may be a possibility... I'll look into it Smiley

Meanwhile... what type of Winamp plugins do you have in mind? If DSP, you just need to keep feeding it sample data until it gives back the required amount (buffering any excess). With input plugins, you need to make sure that you pre-buffer enough, and if you see the buffer level getting too low, stall/pause the stream until it's ready to go again.
« Last Edit: 29 Sep '03 - 13:29 by Ian @ un4seen » Logged
Irrational86
Posts: 960


« Reply #12 on: 29 Sep '03 - 20:52 »
Reply with quoteQuote

On the otherhand, automatically stalling/resuming custom streams may be a possibility... I'll look into it Smiley
Awesome Smiley

Meanwhile... what type of Winamp plugins do you have in mind? If DSP, you just need to keep feeding it sample data until it gives back the required amount (buffering any excess). With input plugins, you need to make sure that you pre-buffer enough, and if you see the buffer level getting too low, stall/pause the stream until it's ready to go again.
I was talking about input plugins, i have already managed to use them, but i was just requesting it for a bit of less coding in slow languages Grin
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines