|
VideoLord
Posts: 14
|
 |
« on: 19 Sep '03 - 13:11 » |
Quote
|
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 » |
Quote
|
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 » |
Quote
|
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?  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 » |
Quote
|
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 » |
Quote
|
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 » |
Quote
|
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  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 
|
|
|
|
|
Logged
|
|
|
|
|
VideoLord
Posts: 14
|
 |
« Reply #6 on: 24 Sep '03 - 14:44 » |
Quote
|
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 » |
Quote
|
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 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 » |
Quote
|
--- 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 » |
Quote
|
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 » |
Quote
|
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...  [/Edit]
|
|
|
|
« Last Edit: 28 Sep '03 - 15:41 by XMinioNX »
|
Logged
|
|
|
|
|
Ian @ un4seen
Administrator
Posts: 15276
|
 |
« Reply #11 on: 29 Sep '03 - 12:52 » |
Quote
|
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  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 » |
Quote
|
On the otherhand, automatically stalling/resuming custom streams may be a possibility... I'll look into it  Awesome  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 
|
|
|
|
|
Logged
|
|
|
|
|