22 May '13 - 04:05 *
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: Support for LIBMP3LAME  (Read 960 times)
AnthonyM
Posts: 47


« on: 18 Jan '12 - 05:16 »
Reply with quoteQuote

The iPad doesn't support MP3 Encoding in any of the inbuilt frameworks (Apple says this is due to MP3 encoding using a lot of CPU and therefore draining the battery faster).
You can however compile LAME for the iPad as LIBMP3LAME.a .

Is there any chance that support for this could be added to BASS for iOS?


Thanks Smiley
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #1 on: 18 Jan '12 - 14:09 »
Reply with quoteQuote

There are no plans to incorporate LAME into BASS (or BASSenc), but you could incorporate it into your app, and then pass the sample data from BASS to it. Depending on how your app works, you could get the sample data from BASS_ChannelGetData or a DSP function. For example, using a DSP function, it could look like this...

// initialize encoder here
BASS_ChannelSetDSP(handle, EncodingDSP, NULL, -1000); // set a DSP function on a BASS channel to feed the encoder

...

void CALLBACK EncodingDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
// feed "length" bytes of data in "buffer" to the encoder here
}

You could make use of the "user" parameter to pass encoder instance stuff to the DSP function.
Logged
AnthonyM
Posts: 47


« Reply #2 on: 18 Jan '12 - 22:55 »
Reply with quoteQuote

Thanks Ian.

Say I have a mixer and want to pass the data from it to a function to do the MP3 encoding and then pass that to CastInit.
How would I 'roughly' go about implementing that?
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #3 on: 19 Jan '12 - 16:31 »
Reply with quoteQuote

Oh right, you want to send the encoded data to a Shoutcast/Icecast server? I'm afraid that isn't currently possible (using BASSenc), as you can't send your data directly to the casting stuff (it has to go through an encoder), but I'll see if something can be arranged.
Logged
AnthonyM
Posts: 47


« Reply #4 on: 19 Jan '12 - 21:24 »
Reply with quoteQuote

Thanks Ian. Smiley
Logged
Ian @ un4seen
Administrator
Posts: 15259


« Reply #5 on: 20 Jan '12 - 16:35 »
Reply with quoteQuote

OK. I have put an updated BASSenc version in the iOS package (in the iOS thread), which allows casting when using the PCM/WAVE writing option (BASS_ENCODE_PCM flag) and also accepts a NULL filename to skip the file writing. PCM/WAVE writing doesn't modify the data (so long as the BASS_ENCODE_FP/BIGEND flags aren't used), so it allows data to be sent straight to the casting, something like this...

encoder=BASS_Encode_Start(handle, NULL, BASS_ENCODE_PCM|BASS_ENCODE_NOHEAD|BASS_ENCODE_PAUSE, NULL, NULL); // set PCM writer with automatic feeding disabled/paused
BASS_Encode_CastInit(encoder, ...); // setup casting on it

...

BASS_Encode_Write(encoder, data, datalen); // send data to the encoder/caster

"handle" could be any BASS channel handle, eg. your mixer. Combining this with the code in my earlier reply, the BASS_Encode_Write call might be placed at the end of the EncodingDSP function with the data that you get back from the encoder.
Logged
AnthonyM
Posts: 47


« Reply #6 on: 21 Jan '12 - 10:28 »
Reply with quoteQuote

Thanks Ian.

I must be doing things wrong as I get choppy sound from BASS when I do this:
void CALLBACK EncodingDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
   
    int write;
   
    unsigned char mp3_buffer[length];
    if (length == 0)
        write = lame_encode_flush(lame, mp3_buffer, length);
    else
        write = lame_encode_buffer_interleaved(lame, buffer, length, mp3_buffer, length);

    BASS_Encode_Write((HENCODE)user, mp3_buffer, write); // send data to the encoder/caster
}

Do you think this is due to CPU load or have I done something wrong?


Thanks Smiley
Logged
AnthonyM
Posts: 47


« Reply #7 on: 23 Jan '12 - 05:15 »
Reply with quoteQuote

Ok, here is my latest code:

lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_mode(lame, JOINT_STEREO);
lame_set_quality(lame, 7);
lame_set_findReplayGain(lame, 0);
lame_set_brate(lame, 128);
lame_set_VBR_min_bitrate_kbps(lame, lame_get_brate(lame));
lame_set_out_samplerate(lame, 44100);
lame_init_params(lame);

BASS_ChannelSetDSP(m_MixerHandle, EncodingDSP, self, -1000);       
encHandle=BASS_Encode_Start(m_MixerHandle, NULL, BASS_ENCODE_PCM|BASS_ENCODE_NOHEAD|BASS_ENCODE_PAUSE, NULL, NULL);

BASS_Encode_CastInit(encHandle, "192.168.0.48:8000",
                                        "ais22b",
                                        BASS_ENCODE_TYPE_MP3,
                                        "TribeFM",
                                        NULL,
                                        "Various",
                                        NULL, 0, 128, NO);

BASS_ChannelPlay(m_MixerHandle, true);

void CALLBACK EncodingDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
    int write;
    HENCODE encHandle = [(Broadcaster*)user encHandle];
    unsigned char mp3_buffer[8000];
    write = lame_encode_buffer_interleaved(lame, buffer, length/2, mp3_buffer, 8000);
    BASS_Encode_Write(encHandle, mp3_buffer, write);
}

This has the output from BASS back to smooth sounding audio.
However the sound from SHOUTcast is broken up and has crunching noises in it.

I'm assuming it's because of my hacked "No idea what i'm doing" attempt of a callback function.

Please help  Huh

Lame Functions Explained: http://openinnowhere.sourceforge.net/lameonj/javadoc/lame/std/Lame.html
Logged
AnthonyM
Posts: 47


« Reply #8 on: 23 Jan '12 - 05:33 »
Reply with quoteQuote

Got it working  Grin

I moved the buffer declaration to outside of the function:
unsigned char mp3_buffer[800000];

Then divide length by 4 as lame needs number of samples
void CALLBACK EncodingDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
    int write;
    HENCODE encHandle = [(Broadcaster*)user encHandle];
    write = lame_encode_buffer_interleaved(lame, buffer, length/4, mp3_buffer, 800000);
    BASS_Encode_Write(encHandle, mp3_buffer, write);
}

Adding support for this has made me a very happy man Smiley
Much thanks Ian.
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines