In that case, you could try using the Windows-provided GSM 6.10 codec. You will first need an appropriate format info block, which you can use BASS_Encode_GetACMFormat to generate. You can then use that in a BASS_Encode_StartACM call to setup the encoder on your recording channel. The encoded data will be received via an ENCODEPROC callback function, which you can have send the data to the central server, eg. via a TCP socket. If you would like to give it a go, here are some code snippets...
record=BASS_RecordStart(freq, 1, BASS_RECORD_PAUSE, RecordProc, NULL); // create a mono recording channel (paused)
// generate a GSM 6.10 format info block...
DWORD formlen=BASS_Encode_GetACMFormat(0, NULL, 0, NULL, 0); // get suggested format buffer size
void *gsmform=malloc(formlen); // allocate the format buffer
formlen=BASS_Encode_GetACMFormat(record, gsmform, formlen, NULL,
MAKELONG(BASS_ACM_SUGGEST|BASS_ACM_RATE|BASS_ACM_CHANS,WAVE_FORMAT_GSM610)) // get the GSM 6.10 format info
BASS_Encode_StartACM(record, gsmform, 0, EncodeProc, NULL); // set a GSM 6.10 encoder on the recording
// setup connection with central server here, and send "gsmform" and "formlen" to initialize the decoder
BASS_ChannelPlay(record, 0); // resume the recording
...
BOOL CALLBACK RecordProc(HRECORD handle, const void *buffer, DWORD length, void *user)
{
return BASS_Encode_IsActive(handle); // continue recording if encoder is alive
}
void CALLBACK EncodeProc(HENCODE handle, DWORD channel, void *buffer, DWORD length, void *user)
{
// send "length" bytes of data in "buffer" to the central server
}
On the central server side, you would prepend the received data with a WAVE header (including the format info that the encoder used) and use BASS_StreamCreateFileUser to create a stream to decode/play it. It might look something like this...
// when the client/server connection is established
// generate a WAVE header (in a FIFO buffer) to tell the decoder what the data format is...
BYTE header1[20]={'R','I','F','F',0xff,0xff,0xff,0xff,'W','A','V','E','f','m','t',' ',formlen,0,0,0}; // WAVE file header
fifobuf->Write(header1, 20); // write it to the buffer
fifobuf->Write(gsmform, formlen); // add the format info block (sent by the client) to the buffer
BYTE header2[8]={'d','a','t','a',0xff,0xff,0xff,0xff}; // "data" chunk header
fifobuf->Write(header2, 8); // add it to the buffer
// create a stream to decode/play the data...
BASS_FILEPROCS fileprocs={FileCloseProc, FileLenProc, FileReadProc}; // callback table
stream=BASS_StreamCreateFileUser(STREAMFILE_BUFFERPUSH, 0, &fileprocs, 0); // create a "buffered push" stream to play the data
if (!stream) ... // failed, cancel it (close conection/etc)
...
void CALLBACK FileCloseProc(void *user)
{
// close the connection
}
QWORD CALLBACK FileLenProc(void *user)
{
return 0; // indeterminate length
}
DWORD CALLBACK FileReadProc(void *buffer, DWORD length, void *user)
{
return fifobuf->Read(buffer, length); // read up to "length" bytes of data
}
...
// when data is received from the client
BASS_StreamPutFileData(stream, data, datalen); // send the data to the stream
Please see the documentation for details on all of the aforementioned functions. To support multiple clients, you can use the "user" parameter to pass instance info to the callback functions. Once you have this stuff working, you can then go on to use the BASSmix add-on to mix/merge multiple streams into one, set an encoder on that, and send the result back to the clients.