Exemple #1
0
//The recording stuff runs in its own thread
//this prevents dropouts in the recording, in case the
//bandwidth is smaller than the selected streaming bitrate
void* snd_rec_thread(void *data)
{
    int rb_read_bytes;
    int ogg_header_written;
    int enc_bytes_read;
    char *enc_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(rec_rb.size * sizeof(short));

    ogg_header_written = 0;

    while(record)
    {
        pthread_cond_wait(&rec_cond, &rec_mut);

		rb_read_bytes = rb_read(&rec_rb, audio_buf);
		if(rb_read_bytes == 0)
			continue;

#if HAVE_LIBLAME
        if(!strcmp(cfg.rec.codec, "mp3"))
        {

            enc_bytes_read = lame_enc_encode(&lame_rec, (short int*)audio_buf, enc_buf,
                                rb_read_bytes/(2*cfg.rec.channel), rec_rb.size*10);
            bytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd);
        }
#endif
#if HAVE_LIBVORBIS
        if (!strcmp(cfg.rec.codec, "ogg"))
        {
            if(!ogg_header_written)
            {
                vorbis_enc_write_header(&vorbis_rec);
                ogg_header_written = 1;
            }

            enc_bytes_read = vorbis_enc_encode(&vorbis_rec, (short int*)audio_buf, 
                    enc_buf, rb_read_bytes/(2*cfg.rec.channel));
            bytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd);
        }
#endif
        if (!strcmp(cfg.rec.codec, "wav"))
        {
            //this permanently updates the filesize value in the WAV header
            //so we still have a valid WAV file in case of a crash
            wav_write_header(cfg.rec.fd, cfg.audio.channel,
                    cfg.audio.samplerate, /*bps*/ 16);
            
            bytes_written += fwrite(audio_buf, sizeof(char), rb_read_bytes, cfg.rec.fd); 
        }
    }

    fclose(cfg.rec.fd);
    free(enc_buf);
    free(audio_buf);
    return NULL;
}
Exemple #2
0
void *snd_stream_thread(void *data)
{
    int sent;
    int rb_read_bytes;
	int encode_bytes_read;

    char *enc_buf = (char*)malloc(stream_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(stream_rb.size * sizeof(short));

    int (*xc_send)(char *buf, int buf_len) = NULL;

    encode_bytes_read = 0;

    if(cfg.srv[cfg.selected_srv]->type == SHOUTCAST)
            xc_send = &sc_send;
    if(cfg.srv[cfg.selected_srv]->type == ICECAST)
        xc_send = &ic_send;

    while(connected)
    {
        pthread_cond_wait(&stream_cond, &stream_mut);
        if(!connected)
            break;

		rb_read_bytes = rb_read(&stream_rb, audio_buf);
		if(rb_read_bytes == 0)
			continue;

#if HAVE_LIBLAME
        if(!strcmp(cfg.audio.codec, "mp3"))
            encode_bytes_read = lame_enc_encode(&lame_stream, (short int*)audio_buf, enc_buf,
                                rb_read_bytes/(2*cfg.audio.channel), stream_rb.size*10);
#endif
#if HAVE_LIBVORBIS
        if(!strcmp(cfg.audio.codec, "ogg"))
            encode_bytes_read = vorbis_enc_encode(&vorbis_stream, (short int*)audio_buf, 
                    enc_buf, rb_read_bytes/(2*cfg.audio.channel));
#endif
        if((sent = xc_send(enc_buf, encode_bytes_read)) == -1)
            connected = 0; 
        else
            bytes_sent += encode_bytes_read;
    }

    free(enc_buf);
    free(audio_buf);

    return NULL;
}
Exemple #3
0
//The recording stuff runs in its own thread
//this prevents dropouts in the recording in case the
//bandwidth is smaller than the selected streaming bitrate
void* snd_rec_thread(void *data)
{
    int rb_bytes_read;
    int bytes_to_read;
    int ogg_header_written;
    int opus_header_written;
    int enc_bytes_read;
    
    char *enc_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(rec_rb.size * sizeof(char)*10);

    ogg_header_written = 0;
    opus_header_written = 0;

    while(record)
    {
        pthread_cond_wait(&rec_cond, &rec_mut);

        if(next_file == 1)
        {
            if(!strcmp(cfg.rec.codec, "flac")) // The flac encoder closes the file
                flac_enc_close(&flac_rec);
            else
                fclose(cfg.rec.fd);

            cfg.rec.fd = next_fd;
            next_file = 0;
            if(!strcmp(cfg.rec.codec, "ogg"))
            {
                vorbis_enc_reinit(&vorbis_rec);
                ogg_header_written = 0;
            }
            if(!strcmp(cfg.rec.codec, "opus"))
            {
                opus_enc_reinit(&opus_rec);
                opus_header_written = 0;
            }
            if(!strcmp(cfg.rec.codec, "flac"))
            {
                flac_enc_reinit(&flac_rec);
                flac_enc_init_FILE(&flac_rec, cfg.rec.fd);
            }
        }

        // Opus needs a special treatment
        // The encoder needs a predefined count of frames
        // Therefore we don't feed the encoder with all data we have in the
        // ringbuffer at once 
        if(!strcmp(cfg.rec.codec, "opus"))
        {
            bytes_to_read = 960 * sizeof(short)*cfg.audio.channel;
            while ((rb_filled(&rec_rb)) >= bytes_to_read)
            {
                rb_read_len(&rec_rb, audio_buf, bytes_to_read);

                if(!opus_header_written)
                {
                    opus_enc_write_header(&opus_rec);
                    opus_header_written = 1;
                }

                enc_bytes_read = opus_enc_encode(&opus_rec, (short*)audio_buf, 
                        enc_buf, bytes_to_read/(2*cfg.audio.channel));
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }
        }
        else
        {

            if(rb_filled(&rec_rb) < framepacket_size*sizeof(short))
                continue;

            rb_bytes_read = rb_read(&rec_rb, audio_buf);
            if(rb_bytes_read == 0)
                continue;


            if(!strcmp(cfg.rec.codec, "mp3"))
            {

                enc_bytes_read = lame_enc_encode(&lame_rec, (short*)audio_buf, enc_buf,
                        rb_bytes_read/(2*cfg.audio.channel), rec_rb.size*10);
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "ogg"))
            {
                if(!ogg_header_written)
                {
                    vorbis_enc_write_header(&vorbis_rec);
                    ogg_header_written = 1;
                }

                enc_bytes_read = vorbis_enc_encode(&vorbis_rec, (short*)audio_buf, 
                        enc_buf, rb_bytes_read/(2*cfg.audio.channel));
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "flac"))
            {
                flac_enc_encode(&flac_rec, (short*)audio_buf, rb_bytes_read/sizeof(short)/cfg.audio.channel, cfg.audio.channel);
                kbytes_written = flac_enc_get_bytes_written()/1024.0;
            }


            if(!strcmp(cfg.rec.codec, "wav"))
            {
                //this permanently updates the filesize value in the WAV header
                //so we still have a valid WAV file in case of a crash
                wav_write_header(cfg.rec.fd, cfg.audio.channel, cfg.audio.samplerate, 16);
                kbytes_written += fwrite(audio_buf, sizeof(char), rb_bytes_read, cfg.rec.fd)/1024.0;
            }

            if(!strcmp(cfg.rec.codec, "aac")) {
                enc_bytes_read = aac_enc_encode(&aac_rec, (short*) audio_buf, enc_buf, rb_bytes_read / (2*cfg.audio.channel), cfg.audio.channel);
                kbytes_written += fwrite(enc_buf, 1, enc_bytes_read, cfg.rec.fd) / 1024.0;
            }
        }
    }

    if(!strcmp(cfg.rec.codec, "flac")) // The flac encoder closes the file
        flac_enc_close(&flac_rec);
    else
        fclose(cfg.rec.fd);
    
    free(enc_buf);
    free(audio_buf);
    
    return NULL;
}
Exemple #4
0
void *snd_stream_thread(void *data)
{
    int sent;
    int rb_bytes_read;
	int encode_bytes_read = 0;
    int bytes_to_read;

    char *enc_buf = (char*)malloc(stream_rb.size * sizeof(char)*10);
    char *audio_buf = (char*)malloc(stream_rb.size * sizeof(char)*10);

    int (*xc_send)(char *buf, int buf_len) = NULL;


    if(cfg.srv[cfg.selected_srv]->type == SHOUTCAST)
        xc_send = &sc_send;
    else //Icecast
        xc_send = &ic_send;
    
    while(connected)
    {

        pthread_cond_wait(&stream_cond, &stream_mut);
        if(!connected)
            break;

        if(!strcmp(cfg.audio.codec, "opus"))
        {
            
            // Read always chunks of 960 frames from the audio ringbuffer to be
            // compatible with OPUS
            bytes_to_read = 960 * sizeof(short)*cfg.audio.channel;

            while ((rb_filled(&stream_rb)) >= bytes_to_read)
            {
                // Read always chunks of 960 frames from the audio ringbuffer to be
                bytes_to_read = 960 * sizeof(short)*cfg.audio.channel;
                rb_read_len(&stream_rb, audio_buf, bytes_to_read);

                encode_bytes_read = opus_enc_encode(&opus_stream, (short*)audio_buf,
                        enc_buf, bytes_to_read/(2*cfg.audio.channel));

                if((sent = xc_send(enc_buf, encode_bytes_read)) == -1)
                {
                    connected = 0;
                }
                else
                    kbytes_sent += bytes_to_read/1024.0;

            }
        }
        else // ogg and mp3 need more data than opus in order to compress the audio data
        {
            if(rb_filled(&stream_rb) < framepacket_size*sizeof(short))
                continue;

            rb_bytes_read = rb_read(&stream_rb, audio_buf);
            if(rb_bytes_read == 0)
                continue;

            if(!strcmp(cfg.audio.codec, "mp3"))
                encode_bytes_read = lame_enc_encode(&lame_stream, (short*)audio_buf, enc_buf,
                        rb_bytes_read/(2*cfg.audio.channel), stream_rb.size*10);
            
            if(!strcmp(cfg.audio.codec, "ogg"))
                encode_bytes_read = vorbis_enc_encode(&vorbis_stream, (short*)audio_buf, 
                        enc_buf, rb_bytes_read/(2*cfg.audio.channel));
            
            if(!strcmp(cfg.audio.codec, "aac")) {
                encode_bytes_read = aac_enc_encode(&aac_stream, (short*) audio_buf,
                        enc_buf, rb_bytes_read/2/cfg.audio.channel, stream_rb.size*10);
            }

            if(encode_bytes_read != 0) {
                if((sent = xc_send(enc_buf, encode_bytes_read)) == -1)
                    connected = 0;
                else
                    kbytes_sent += encode_bytes_read/1024.0;
            }

        }
    }

    free(enc_buf);
    free(audio_buf);

    return NULL;
}