static void *SWITCH_THREAD_FUNC write_stream_thread(switch_thread_t *thread, void *obj) { shout_context_t *context = (shout_context_t *) obj; switch_thread_rwlock_rdlock(context->rwlock); if (context->thread_running) { context->thread_running++; } else { switch_thread_rwlock_unlock(context->rwlock); return NULL; } if (!context->lame_ready) { lame_init_params(context->gfp); lame_print_config(context->gfp); context->lame_ready = 1; } while (!context->err && context->thread_running) { unsigned char mp3buf[8192] = ""; int16_t audio[9600] = { 0 }; switch_size_t audio_read = 0; int rlen = 0; long ret = 0; switch_mutex_lock(context->audio_mutex); if (context->audio_buffer) { audio_read = switch_buffer_read(context->audio_buffer, audio, sizeof(audio)); } else { context->err++; } switch_mutex_unlock(context->audio_mutex); error_check(); if (!audio_read) { audio_read = sizeof(audio); memset(audio, 255, sizeof(audio)); } if (context->channels == 2) { int16_t l[4800] = { 0 }; int16_t r[4800] = { 0 }; int j = 0; switch_size_t i; for (i = 0; i < audio_read / 4; i++) { l[i] = audio[j++]; r[i] = audio[j++]; } if ((rlen = lame_encode_buffer(context->gfp, l, r, audio_read / 4, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto error; } } else if (context->channels == 1) { if ((rlen = lame_encode_buffer(context->gfp, (void *) audio, NULL, audio_read / sizeof(int16_t), mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto error; } } if (rlen) { ret = shout_send(context->shout, mp3buf, rlen); if (ret != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Send error: %s\n", shout_get_error(context->shout)); goto error; } } else { memset(mp3buf, 0, 128); ret = shout_send(context->shout, mp3buf, 128); } shout_sync(context->shout); switch_yield(100000); } error: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Thread Done\n"); switch_thread_rwlock_unlock(context->rwlock); context->thread_running = 0; return NULL; }
static switch_status_t shout_file_write(switch_file_handle_t *handle, void *data, size_t *len) { shout_context_t *context; int rlen = 0; int16_t *audio = data; size_t nsamples = *len; if (!handle) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no handle\n"); return SWITCH_STATUS_FALSE; } if (!(context = handle->private_info)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no context\n"); return SWITCH_STATUS_FALSE; } if (context->err) { return SWITCH_STATUS_FALSE; } if (context->shout && !context->shout_init) { if (!context->gfp) { return SWITCH_STATUS_FALSE; } context->shout_init++; if (shout_open(context->shout) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening stream: %s\n", shout_get_error(context->shout)); context->err++; return SWITCH_STATUS_FALSE; } launch_write_stream_thread(context); } if (handle->handler && context->audio_mutex) { switch_mutex_lock(context->audio_mutex); if (context->audio_buffer) { if (!switch_buffer_write(context->audio_buffer, data, (nsamples * sizeof(int16_t) * handle->channels))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Buffer error\n"); context->err++; } } else { context->err++; } switch_mutex_unlock(context->audio_mutex); if (context->err) { return SWITCH_STATUS_FALSE; } handle->sample_count += *len; return SWITCH_STATUS_SUCCESS; } if (!context->lame_ready) { lame_init_params(context->gfp); lame_print_config(context->gfp); context->lame_ready = 1; } if (context->mp3buflen < nsamples * 4) { context->mp3buflen = nsamples * 4; context->mp3buf = switch_core_alloc(context->memory_pool, context->mp3buflen); } if (handle->channels == 2) { switch_size_t i, j = 0; if (context->llen < nsamples) { context->l = switch_core_alloc(context->memory_pool, nsamples * 2); context->r = switch_core_alloc(context->memory_pool, nsamples * 2); context->llen = context->rlen = nsamples; } for (i = 0; i < nsamples; i++) { context->l[i] = audio[j++]; context->r[i] = audio[j++]; } if ((rlen = lame_encode_buffer(context->gfp, context->l, context->r, nsamples, context->mp3buf, context->mp3buflen)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); return SWITCH_STATUS_FALSE; } } else if (handle->channels == 1) { if ((rlen = lame_encode_buffer(context->gfp, audio, NULL, nsamples, context->mp3buf, context->mp3buflen)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); return SWITCH_STATUS_FALSE; } } else { rlen = 0; } if (rlen) { int ret = fwrite(context->mp3buf, 1, rlen, context->fp); if (ret < 0) { return SWITCH_STATUS_FALSE; } } handle->sample_count += *len; return SWITCH_STATUS_SUCCESS; }
void do_telecast(switch_stream_handle_t *stream) { char *path_info = switch_event_get_header(stream->param_event, "http-path-info"); char *uuid = strdup(path_info + 4); switch_core_session_t *tsession; char *fname = "stream.mp3"; if ((fname = strchr(uuid, '/'))) { *fname++ = '\0'; } if (!(tsession = switch_core_session_locate(uuid))) { char *ref = switch_event_get_header(stream->param_event, "http-referer"); stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>Not Found!</h2>\n" "<META http-equiv=\"refresh\" content=\"1;URL=%s\">", ref); } else { switch_media_bug_t *bug = NULL; switch_buffer_t *buffer = NULL; switch_mutex_t *mutex; switch_channel_t *channel = switch_core_session_get_channel(tsession); lame_global_flags *gfp = NULL; switch_codec_implementation_t read_impl = { 0 }; switch_core_session_get_read_impl(tsession, &read_impl); if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stepping into media path so this will work!\n"); switch_ivr_media(uuid, SMF_REBRIDGE); } if (!(gfp = lame_init())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n"); goto end; } lame_set_num_channels(gfp, read_impl.number_of_channels); lame_set_in_samplerate(gfp, read_impl.actual_samples_per_second); lame_set_brate(gfp, 16 * (read_impl.actual_samples_per_second / 8000) * read_impl.number_of_channels); lame_set_mode(gfp, 3); lame_set_quality(gfp, 2); lame_set_errorf(gfp, log_error); lame_set_debugf(gfp, log_debug); lame_set_msgf(gfp, log_msg); lame_set_bWriteVbrTag(gfp, 0); lame_mp3_tags_fid(gfp, NULL); lame_init_params(gfp); lame_print_config(gfp); switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); switch_buffer_create_dynamic(&buffer, 1024, 2048, 0); switch_buffer_add_mutex(buffer, mutex); if (switch_core_media_bug_add(tsession, "telecast", NULL, telecast_callback, buffer, 0, SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING, &bug) != SWITCH_STATUS_SUCCESS) { goto end; } stream->write_function(stream, "Content-type: audio/mpeg\r\n" "Content-Disposition: inline; filename=\"%s\"\r\n\r\n", fname); while (switch_channel_ready(channel)) { unsigned char mp3buf[TC_BUFFER_SIZE] = ""; int rlen; uint8_t buf[1024]; switch_size_t bytes = 0; if (switch_buffer_inuse(buffer) >= 1024) { switch_buffer_lock(buffer); bytes = switch_buffer_read(buffer, buf, sizeof(buf)); switch_buffer_unlock(buffer); } else { if (!bytes) { switch_cond_next(); continue; } memset(buf, 0, bytes); } if ((rlen = lame_encode_buffer(gfp, (void *) buf, NULL, bytes / 2, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto end; } if (rlen) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } } end: switch_safe_free(uuid); if (gfp) { lame_close(gfp); gfp = NULL; } if (bug) { switch_core_media_bug_remove(tsession, &bug); } if (buffer) { switch_buffer_destroy(&buffer); } switch_core_session_rwunlock(tsession); } }
void do_broadcast(switch_stream_handle_t *stream) { char *path_info = switch_event_get_header(stream->param_event, "http-path-info"); char *file; lame_global_flags *gfp = NULL; switch_file_handle_t fh = { 0 }; unsigned char mp3buf[TC_BUFFER_SIZE] = ""; uint8_t buf[1024]; int rlen; int is_local = 0; uint32_t interval = 20000; if (strstr(path_info + 7, "://")) { file = strdup(path_info + 7); is_local++; } else { file = switch_mprintf("%s/streamfiles/%s", SWITCH_GLOBAL_dirs.base_dir, path_info + 7); } assert(file); if (switch_core_file_open(&fh, file, 0, 0, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { memset(&fh, 0, sizeof(fh)); stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>File not found</h2>\n"); goto end; } if (switch_test_flag((&fh), SWITCH_FILE_NATIVE)) { stream->write_function(stream, "Content-type: text/html\r\n\r\n<h2>File format not supported</h2>\n"); goto end; } if (!(gfp = lame_init())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n"); goto end; } lame_set_num_channels(gfp, fh.channels); lame_set_in_samplerate(gfp, fh.samplerate); lame_set_brate(gfp, 16 * (fh.samplerate / 8000) * fh.channels); lame_set_mode(gfp, 3); lame_set_quality(gfp, 2); lame_set_errorf(gfp, log_error); lame_set_debugf(gfp, log_debug); lame_set_msgf(gfp, log_msg); lame_set_bWriteVbrTag(gfp, 0); lame_mp3_tags_fid(gfp, NULL); lame_init_params(gfp); lame_print_config(gfp); stream->write_function(stream, "Content-type: audio/mpeg\r\n" "Content-Disposition: inline; filename=\"%s.mp3\"\r\n\r\n", path_info + 7); if (fh.interval) { interval = fh.interval * 1000; } for (;;) { switch_size_t samples = sizeof(buf) / 2; switch_core_file_read(&fh, buf, &samples); if (is_local) { switch_yield(interval); } if (!samples) { break; } if ((rlen = lame_encode_buffer(gfp, (void *) buf, NULL, samples, mp3buf, sizeof(mp3buf))) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MP3 encode error %d!\n", rlen); goto end; } if (rlen) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } } while ((rlen = lame_encode_flush(gfp, mp3buf, sizeof(mp3buf))) > 0) { if (stream->raw_write_function(stream, mp3buf, rlen)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Disconnected\n"); goto end; } } end: if (fh.channels) { switch_core_file_close(&fh); } switch_safe_free(file); if (gfp) { lame_close(gfp); gfp = NULL; } }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool LameLibEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } lameGlobalFlags = lame_init(); // ugly lame returns -1 in a pointer on allocation errors if ( !lameGlobalFlags || ((int)lameGlobalFlags) == -1 ) { throw Exception( __FILE__, __LINE__, "lame lib init error", (int) lameGlobalFlags); } if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting channels error", getInChannel() ); } if ( 0 > lame_set_mode( lameGlobalFlags, getOutChannel() == 1 ? MONO : JOINT_STEREO) ) { throw Exception( __FILE__, __LINE__, "lame lib setting mode error", JOINT_STEREO ); } reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags)); reportEvent( 5, "set lame channels", lame_get_num_channels( lameGlobalFlags)); if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting input sample rate error", getInSampleRate() ); } reportEvent( 5, "set lame in sample rate", lame_get_in_samplerate( lameGlobalFlags)); if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output sample rate error", getOutSampleRate() ); } reportEvent( 5, "set lame out sample rate", lame_get_out_samplerate( lameGlobalFlags)); switch ( getOutBitrateMode() ) { case cbr: { if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output bit rate error", getOutBitrate() ); } reportEvent( 5, "set lame bit rate", lame_get_brate( lameGlobalFlags)); double d = (1.0 - getOutQuality()) * 10.0; int q = int (d + 0.499999); if ( 0 > lame_set_quality( lameGlobalFlags, q) ) { throw Exception( __FILE__, __LINE__, "lame lib setting quality error", q); } reportEvent( 5, "set lame quality", lame_get_quality( lameGlobalFlags)); } break; case abr: if ( 0 > lame_set_VBR( lameGlobalFlags,vbr_abr)) { throw Exception( __FILE__, __LINE__, "lame lib setting abr error", vbr_abr); } reportEvent( 5, "set lame abr bitrate", lame_get_VBR( lameGlobalFlags)); if ( 0 > lame_set_VBR_mean_bitrate_kbps( lameGlobalFlags, getOutBitrate())) { throw Exception( __FILE__, __LINE__, "lame lib setting abr mean bitrate error", getOutBitrate()); } reportEvent( 5, "set lame abr mean bitrate", lame_get_VBR_mean_bitrate_kbps( lameGlobalFlags)); break; case vbr: { if ( 0 > lame_set_VBR( lameGlobalFlags, vbr_mtrh)) { throw Exception( __FILE__, __LINE__, "lame lib setting vbr error", vbr_mtrh ); } reportEvent( 5, "set lame vbr bitrate", lame_get_VBR( lameGlobalFlags)); double d = (1.0 - getOutQuality()) * 10.0; int q = int (d + 0.499999); if ( 0 > lame_set_VBR_q( lameGlobalFlags, q) ) { throw Exception( __FILE__, __LINE__, "lame lib setting vbr quality error", q); } reportEvent( 5, "set lame vbr quality", lame_get_VBR_q( lameGlobalFlags)); } break; } if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting lowpass frequency error", lowpass ); } reportEvent( 5, "set lame lowpass frequency", lame_get_lowpassfreq( lameGlobalFlags)); if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting highpass frequency error", lowpass ); } reportEvent( 5, "set lame highpass frequency", lame_get_highpassfreq( lameGlobalFlags)); // not configurable lame settings if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting psycho acoustic model error"); } reportEvent( 5, "set lame psycho acoustic model", lame_get_exp_nspsytune( lameGlobalFlags)); if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting error protection error", 1 ); } reportEvent( 5, "set lame error protection", lame_get_error_protection( lameGlobalFlags)); // let lame init its own params based on our settings if ( 0 > lame_init_params( lameGlobalFlags) ) { throw Exception( __FILE__, __LINE__, "lame lib initializing params error" ); } lame_print_config( lameGlobalFlags); // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "lame lib opening underlying sink error"); } return true; }
int lame_main(lame_t gf, int argc, char **argv) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; char inPath[PATH_MAX + 1]; char outPath[PATH_MAX + 1]; int Buffer[2][1152]; int maxx = 0, tmpx = 0; int ret; int wavsamples; int mp3bytes; FILE *outf; char ip[16]; unsigned int port = 5004; unsigned int ttl = 2; char dummy; if (argc <= 2) { console_printf("Encode (via LAME) to mp3 with RTP streaming of the output\n" "\n" " mp3rtp ip[:port[:ttl]] [lame encoding options] infile outfile\n" "\n" " examples:\n" " arecord -b 16 -s 22050 -w | ./mp3rtp 224.17.23.42:5004:2 -b 56 - /dev/null\n" " arecord -b 16 -s 44100 -w | ./mp3rtp 10.1.1.42 -V2 -b128 -B256 - my_mp3file.mp3\n" "\n"); return 1; } switch (sscanf(argv[1], "%11[.0-9]:%u:%u%c", ip, &port, &ttl, &dummy)) { case 1: case 2: case 3: break; default: error_printf("Illegal destination selector '%s', must be ip[:port[:ttl]]\n", argv[1]); return -1; } rtp_initialization(); if (rtp_socket(ip, port, ttl)) { rtp_deinitialization(); error_printf("fatal error during initialization\n"); return 1; } lame_set_errorf(gf, &frontend_errorf); lame_set_debugf(gf, &frontend_debugf); lame_set_msgf(gf, &frontend_msgf); /* Remove the argumets that are rtp related, and then * parse the command line arguments, setting various flags in the * struct pointed to by 'gf'. If you want to parse your own arguments, * or call libmp3lame from a program which uses a GUI to set arguments, * skip this call and set the values of interest in the gf struct. * (see lame.h for documentation about these parameters) */ { int i; int argc_mod = argc-1; /* leaving out exactly one argument */ char** argv_mod = calloc(argc_mod, sizeof(char*)); argv_mod[0] = argv[0]; for (i = 2; i < argc; ++i) { /* leaving out argument number 1, parsed above */ argv_mod[i-1] = argv[i]; } parse_args(gf, argc_mod, argv_mod, inPath, outPath, NULL, NULL); free(argv_mod); } /* open the output file. Filename parsed into gf.inPath */ if (0 == strcmp(outPath, "-")) { lame_set_stream_binary_mode(outf = stdout); } else { if ((outf = lame_fopen(outPath, "wb+")) == NULL) { rtp_deinitialization(); error_printf("Could not create \"%s\".\n", outPath); return 1; } } /* open the wav/aiff/raw pcm or mp3 input file. This call will * open the file with name gf.inFile, try to parse the headers and * set gf.samplerate, gf.num_channels, gf.num_samples. * if you want to do your own file input, skip this call and set * these values yourself. */ if (init_infile(gf, inPath) < 0) { rtp_deinitialization(); fclose(outf); error_printf("Can't init infile '%s'\n", inPath); return 1; } /* Now that all the options are set, lame needs to analyze them and * set some more options */ ret = lame_init_params(gf); if (ret < 0) { if (ret == -1) display_bitrates(stderr); rtp_deinitialization(); fclose(outf); close_infile(); error_printf("fatal error during initialization\n"); return -1; } lame_print_config(gf); /* print useful information about options being used */ if (global_ui_config.update_interval < 0.) global_ui_config.update_interval = 2.; /* encode until we hit EOF */ while ((wavsamples = get_audio(gf, Buffer)) > 0) { /* read in 'wavsamples' samples */ levelmessage(maxvalue(Buffer), &maxx, &tmpx); mp3bytes = lame_encode_buffer_int(gf, /* encode the frame */ Buffer[0], Buffer[1], wavsamples, mp3buffer, sizeof(mp3buffer)); rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */ fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */ } mp3bytes = lame_encode_flush(gf, /* may return one or more mp3 frame */ mp3buffer, sizeof(mp3buffer)); rtp_output(mp3buffer, mp3bytes); /* write MP3 output to RTP port */ fwrite(mp3buffer, 1, mp3bytes, outf); /* write the MP3 output to file */ lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */ rtp_deinitialization(); fclose(outf); close_infile(); /* close the sound input file */ return 0; }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool LameLibEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } lameGlobalFlags = lame_init(); // ugly lame returns -1 in a pointer on allocation errors if ( !lameGlobalFlags || ((int)lameGlobalFlags) == -1 ) { throw Exception( __FILE__, __LINE__, "lame lib init error", (int) lameGlobalFlags); } if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting channels error", getInChannel() ); } if ( 0 > lame_set_mode( lameGlobalFlags, getInChannel() == 1 ? MONO : JOINT_STEREO) ) { throw Exception( __FILE__, __LINE__, "lame lib setting mode error", JOINT_STEREO ); } reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags)); reportEvent( 5, "set lame channels", lame_get_num_channels( lameGlobalFlags)); if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting input sample rate error", getInSampleRate() ); } reportEvent( 5, "set lame in sample rate", lame_get_in_samplerate( lameGlobalFlags)); if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output sample rate error", getOutSampleRate() ); } reportEvent( 5, "set lame out sample rate", lame_get_out_samplerate( lameGlobalFlags)); if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output bit rate error", getOutBitrate() ); } reportEvent( 5, "set lame bit rate", lame_get_brate( lameGlobalFlags)); if ( lowpass ) { if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting lowpass frequency error", lowpass ); } reportEvent( 5, "set lame lowpass frequency", lame_get_lowpassfreq( lameGlobalFlags)); } if ( highpass ) { if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting highpass frequency error", lowpass ); } reportEvent( 5, "set lame highpass frequency", lame_get_highpassfreq( lameGlobalFlags)); } // not configurable lame settings if ( 0 > lame_set_quality( lameGlobalFlags, 2) ) { throw Exception( __FILE__, __LINE__, "lame lib setting quality error", 2 ); } reportEvent( 5, "set lame quality", lame_get_quality( lameGlobalFlags)); if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting psycho acoustic model error"); } reportEvent( 5, "set lame psycho acoustic model", lame_get_exp_nspsytune( lameGlobalFlags)); if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting error protection error", 1 ); } reportEvent( 5, "set lame error protection", lame_get_error_protection( lameGlobalFlags)); // let lame init its own params based on our settings if ( 0 > lame_init_params( lameGlobalFlags) ) { throw Exception( __FILE__, __LINE__, "lame lib initializing params error" ); } lame_print_config( lameGlobalFlags); // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "lame lib opening underlying sink error"); } return true; }
int lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath) { unsigned char mp3buffer[LAME_MAXMP3BUFFER]; int Buffer[2][1152]; int iread, imp3; static const char *mode_names[2][4] = { {"stereo", "j-stereo", "dual-ch", "single-ch"}, {"stereo", "force-ms", "dual-ch", "single-ch"} }; int frames; if (silent < 10) { lame_print_config(gf); /* print useful information about options being used */ fprintf(stderr, "Encoding %s%s to %s\n", strcmp(inPath, "-") ? inPath : "<stdin>", strlen(inPath) + strlen(outPath) < 66 ? "" : "\n ", strcmp(outPath, "-") ? outPath : "<stdout>"); fprintf(stderr, "Encoding as %g kHz ", 1.e-3 * lame_get_out_samplerate(gf)); { const char *appendix = ""; switch (lame_get_VBR(gf)) { case vbr_mt: case vbr_rh: case vbr_mtrh: appendix = "ca. "; fprintf(stderr, "VBR(q=%i)", lame_get_VBR_q(gf)); break; case vbr_abr: fprintf(stderr, "average %d kbps", lame_get_VBR_mean_bitrate_kbps(gf)); break; default: fprintf(stderr, "%3d kbps", lame_get_brate(gf)); break; } fprintf(stderr, " %s MPEG-%u%s Layer III (%s%gx) qval=%i\n", mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)], 2 - lame_get_version(gf), lame_get_out_samplerate(gf) < 16000 ? ".5" : "", appendix, 0.1 * (int) (10. * lame_get_compression_ratio(gf) + 0.5), lame_get_quality(gf)); } if (silent <= -10) lame_print_internals(gf); fflush(stderr); } /* encode until we hit eof */ do { /* read in 'iread' samples */ iread = get_audio(gf, Buffer); frames = lame_get_frameNum(gf); /********************** status display *****************************/ if (silent <= 0) { if (update_interval > 0) { timestatus_klemm(gf); } else { if (0 == frames % 50) { #ifdef BRHIST brhist_jump_back(); #endif timestatus(lame_get_out_samplerate(gf), frames, lame_get_totalframes(gf), lame_get_framesize(gf)); #ifdef BRHIST if (brhist) brhist_disp(gf); #endif } } } /* encode */ imp3 = lame_encode_buffer_int(gf, Buffer[0], Buffer[1], iread, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) fprintf(stderr, "mp3 buffer is not big enough... \n"); else fprintf(stderr, "mp3 internal error: error code=%i\n", imp3); return 1; } if (fwrite(mp3buffer, 1, imp3, outf) != imp3) { fprintf(stderr, "Error writing mp3 output \n"); return 1; } } while (iread); if (nogap) imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ else imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */ if (imp3 < 0) { if (imp3 == -1) fprintf(stderr, "mp3 buffer is not big enough... \n"); else fprintf(stderr, "mp3 internal error: error code=%i\n", imp3); return 1; } if (silent <= 0) { #ifdef BRHIST brhist_jump_back(); #endif frames = lame_get_frameNum(gf); timestatus(lame_get_out_samplerate(gf), frames, lame_get_totalframes(gf), lame_get_framesize(gf)); #ifdef BRHIST if (brhist) { brhist_disp(gf); } brhist_disp_total(gf); #endif timestatus_finish(); } fwrite(mp3buffer, 1, imp3, outf); return 0; }
bool AUDMEncoder_Lame::initialize (void) { int ret; MPEG_mode_e mmode; uint32_t frequence; lameFlags = lame_init (); if (lameFlags == NULL) return false; if (_incoming->getInfo ()->channels > 2) { printf ("[Lame]Too many channels\n"); return false; } // recompute output length ret = lame_set_in_samplerate (MYFLAGS, wavheader.frequency); ret = lame_set_num_channels (MYFLAGS, wavheader.channels); frequence = wavheader.frequency; printf ("[Lame] output frequency : %"PRIu32"\n", frequence); ret = lame_set_out_samplerate (MYFLAGS, frequence); ret = lame_set_quality (MYFLAGS, 2); if (wavheader.channels == 2) { mmode = STEREO; } else { mmode = MONO; printf ("[Lame] mono audio mp3"); } ret = lame_set_brate (MYFLAGS, _config.bitrate); ret = lame_set_mode (MYFLAGS, mmode); // 0 stereo 1 jstero ret = lame_set_quality (MYFLAGS, _config.quality); // 0 stereo 1 jstero ret = lame_set_disable_reservoir (MYFLAGS, _config.disableBitReservoir); printf ("[Lame]Using quality of %d\n", lame_get_quality (MYFLAGS)); // update bitrate in header wavheader.byterate = (_config.bitrate >> 3) * 1000; #define BLOCK_SIZE 1152 // configure CBR/ABR/... switch (_config.preset) { default: case ADM_LAME_PRESET_CBR: ADM_info("Lame : CBR Mode\n"); break; case ADM_LAME_PRESET_ABR: ADM_info("Lame : ABR Mode\n"); lame_set_preset (MYFLAGS, _config.bitrate); wavheader.blockalign = BLOCK_SIZE; break; case ADM_LAME_PRESET_EXTREME: ADM_info("Lame : Extreme Mode\n"); wavheader.blockalign = BLOCK_SIZE; lame_set_preset (MYFLAGS, EXTREME); break; } ret = lame_init_params (MYFLAGS); if (ret == -1) { printf("[Lame] Init params failes %d\n",ret); return false; } lame_print_config (MYFLAGS); lame_print_internals (MYFLAGS); _chunk = BLOCK_SIZE * wavheader.channels; return true; }
//________________________________________________ // Init lame encoder // frequence : Impose frequency , 0 means reuse the incoming fq // mode : ADM_STEREO etc... // bitrate : Bitrate in kbps (96,192...) // return 0 : init failed // 1 : init succeeded //_______________________________________________ uint8_t AVDMProcessAudio_Lame::initLame(uint32_t frequence, uint32_t mode, uint32_t bitrate, ADM_LAME_PRESET preset) { int ret, ratio; MPEG_mode_e mmode; double dratio; myflags = lame_init(); if (myflags == NULL) return 0; // recompute output length // since we compress recompute the length in bytes double comp; comp=_instream->getLength(); comp/=2; // 16 bits sample comp/=_wavheader->channels; // We got sample comp/=_wavheader->frequency; // and no we got seconds comp*=bitrate*1000; comp/=8; // now we got bytes _length=(uint32_t) floor(comp+1); printf("Incoming : %lu bytes, fq : %lu, channel : %lu bitrate: %lu outgoing : %lu\n", _instream->getLength(),_wavheader->frequency,_wavheader->channels,bitrate,_length); //initLame(frequence,mode,bitrate); ret = lame_set_in_samplerate(myflags, _instream->getInfo()->frequency); ret = lame_set_num_channels(myflags, _instream->getInfo()->channels); if (frequence == 0) // keep same as instream frequence = _instream->getInfo()->frequency; printf("\n output frequency : %lu\n", frequence); ret = lame_set_out_samplerate(myflags, frequence); ret = lame_set_quality(myflags, 2); //max quality); if (_instream->getInfo()->channels == 2) { switch (mode) { case ADM_STEREO: mmode = STEREO; break; case ADM_JSTEREO: mmode = JOINT_STEREO; break; default: printf("\n **** unknown mode ***\n"); mmode = STEREO; break; } } else { mmode = MONO; printf("\n mono audio mp3"); } _mode=mmode; ret = lame_set_brate(myflags, bitrate); ret = lame_set_mode(myflags, mmode); // 0 stereo 1 jstero ret = lame_init_params(myflags); if (ret == -1) return 0; // update bitrate in header _wavheader->byterate = (bitrate >> 3) * 1000; // configure CBR/ABR/... _preset=preset; switch(preset) { default: case ADM_LAME_PRESET_CBR: break; case ADM_LAME_PRESET_ABR: lame_set_preset( myflags, bitrate); _wavheader->blockalign=1152; break; case ADM_LAME_PRESET_EXTREME: _wavheader->blockalign=1152; lame_set_preset( myflags, EXTREME); break; } lame_print_config(myflags); lame_print_internals(myflags); return 1; }
void encoder_progress_begin( lame_global_flags const* gf , char const* inPath , char const* outPath ) { brhist_init_package(gf); global_encoder_progress.time_status_init = 0; global_encoder_progress.last_time = 0; global_encoder_progress.last_frame_num = 0; if (global_ui_config.silent < 9) { char* i_file = 0; char* o_file = 0; #if defined( _WIN32 ) && !defined(__MINGW32__) inPath = i_file = utf8ToLocal8Bit(inPath); outPath = o_file = utf8ToConsole8Bit(outPath); #endif lame_print_config(gf); /* print useful information about options being used */ console_printf("Encoding %s%s to %s\n", strcmp(inPath, "-") ? inPath : "<stdin>", strlen(inPath) + strlen(outPath) < 66 ? "" : "\n ", strcmp(outPath, "-") ? outPath : "<stdout>"); free(i_file); free(o_file); console_printf("Encoding as %g kHz ", 1.e-3 * lame_get_out_samplerate(gf)); { static const char *mode_names[2][4] = { {"stereo", "j-stereo", "dual-ch", "single-ch"}, {"stereo", "force-ms", "dual-ch", "single-ch"} }; switch (lame_get_VBR(gf)) { case vbr_rh: console_printf("%s MPEG-%u%s Layer III VBR(q=%g) qval=%i\n", mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)], 2 - lame_get_version(gf), lame_get_out_samplerate(gf) < 16000 ? ".5" : "", lame_get_VBR_quality(gf), lame_get_quality(gf)); break; case vbr_mt: case vbr_mtrh: console_printf("%s MPEG-%u%s Layer III VBR(q=%g)\n", mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)], 2 - lame_get_version(gf), lame_get_out_samplerate(gf) < 16000 ? ".5" : "", lame_get_VBR_quality(gf)); break; case vbr_abr: console_printf("%s MPEG-%u%s Layer III (%gx) average %d kbps qval=%i\n", mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)], 2 - lame_get_version(gf), lame_get_out_samplerate(gf) < 16000 ? ".5" : "", 0.1 * (int) (10. * lame_get_compression_ratio(gf) + 0.5), lame_get_VBR_mean_bitrate_kbps(gf), lame_get_quality(gf)); break; default: console_printf("%s MPEG-%u%s Layer III (%gx) %3d kbps qval=%i\n", mode_names[lame_get_force_ms(gf)][lame_get_mode(gf)], 2 - lame_get_version(gf), lame_get_out_samplerate(gf) < 16000 ? ".5" : "", 0.1 * (int) (10. * lame_get_compression_ratio(gf) + 0.5), lame_get_brate(gf), lame_get_quality(gf)); break; } } if (global_ui_config.silent <= -10) { lame_print_internals(gf); } } }
static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path) { shout_context_t *context; char *host, *file; char *username, *password, *port; char *err = NULL; const char *mpg123err = NULL; int portno = 0; if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) { return SWITCH_STATUS_MEMERR; } if (!handle->samplerate) { handle->samplerate = 8000; } context->memory_pool = handle->memory_pool; context->samplerate = handle->samplerate; context->handle = handle; switch_thread_rwlock_create(&(context->rwlock), context->memory_pool); switch_thread_rwlock_rdlock(context->rwlock); switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->memory_pool); if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { if (switch_buffer_create_dynamic(&context->audio_buffer, TC_BUFFER_SIZE, TC_BUFFER_SIZE * 2, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); goto error; } context->mh = our_mpg123_new(NULL, NULL); if (mpg123_format_all(context->mh) != MPG123_OK) { MPGERROR(); } if (mpg123_param(context->mh, MPG123_FORCE_RATE, context->samplerate, 0) != MPG123_OK) { MPGERROR(); } if (handle->handler) { if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_SEEKBUFFER | MPG123_MONO_MIX, 0) != MPG123_OK) { MPGERROR(); } if (mpg123_open_feed(context->mh) != MPG123_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening mpg feed\n"); mpg123err = mpg123_strerror(context->mh); goto error; } context->stream_url = switch_core_sprintf(context->memory_pool, "http://%s", path); context->prebuf = handle->prebuf; launch_read_stream_thread(context); } else { handle->seekable = 1; if (mpg123_param(context->mh, MPG123_FLAGS, MPG123_MONO_MIX, 0) != MPG123_OK) { MPGERROR(); } if (mpg123_open(context->mh, path) != MPG123_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path); mpg123err = mpg123_strerror(context->mh); goto error; } } } else if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { if (!(context->gfp = lame_init())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate lame\n"); goto error; } if (!handle->handler) { id3tag_init(context->gfp); id3tag_v2_only(context->gfp); id3tag_pad_v2(context->gfp); } context->channels = handle->channels; if (globals.brate) { lame_set_brate(context->gfp, globals.brate); } else { lame_set_brate(context->gfp, 16 * (handle->samplerate / 8000) * handle->channels); } lame_set_num_channels(context->gfp, handle->channels); lame_set_in_samplerate(context->gfp, handle->samplerate); if (globals.resample) { lame_set_out_samplerate(context->gfp, globals.resample); } else { lame_set_out_samplerate(context->gfp, handle->samplerate); } if (handle->channels == 2) { lame_set_mode(context->gfp, STEREO); } else { lame_set_mode(context->gfp, MONO); } if (globals.quality) { lame_set_quality(context->gfp, globals.quality); } else { lame_set_quality(context->gfp, 2); /* 2=high 5 = medium 7=low */ } lame_set_errorf(context->gfp, log_error); lame_set_debugf(context->gfp, log_debug); lame_set_msgf(context->gfp, log_msg); if (handle->handler) { if (switch_buffer_create_dynamic(&context->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); goto error; } lame_set_bWriteVbrTag(context->gfp, 0); lame_mp3_tags_fid(context->gfp, NULL); username = switch_core_strdup(handle->memory_pool, path); if (!(password = strchr(username, ':'))) { err = "invalid url"; goto error; } *password++ = '\0'; if (!(host = strchr(password, '@'))) { err = "invalid url"; goto error; } *host++ = '\0'; if ((file = strchr(host, '/'))) { *file++ = '\0'; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL: %s\n", path); goto error; } if ((port = strchr(host, ':'))) { *port++ = '\0'; if (port) { portno = atoi(port); } } if (!portno) { portno = 8000; } if (!(context->shout = shout_new())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not allocate shout_t\n"); goto error; } if (shout_set_host(context->shout, host) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting hostname: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_protocol(context->shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting protocol: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_port(context->shout, portno) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting port: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_password(context->shout, password) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting password: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_mount(context->shout, file) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting mount: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_user(context->shout, username) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting user: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_url(context->shout, "http://www.freeswitch.org") != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting name: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_description(context->shout, "FreeSWITCH mod_shout Broadcasting Module") != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting description: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_audio_info(context->shout, "bitrate", "24000") != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting bitrate: %s\n", shout_get_error(context->shout)); goto error; } if (shout_set_format(context->shout, SHOUT_FORMAT_MP3) != SHOUTERR_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting format: %s\n", shout_get_error(context->shout)); goto error; } } else { const char *mask = "wb+"; if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) { mask = "ab+"; } /* lame being lame and all has FILE * coded into it's API for some functions so we gotta use it */ if (!(context->fp = fopen(path, mask))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path); goto error; } if (!context->lame_ready) { lame_init_params(context->gfp); lame_print_config(context->gfp); context->lame_ready = 1; } } } handle->samples = 0; handle->format = 0; handle->sections = 0; handle->speed = 0; handle->private_info = context; switch_thread_rwlock_unlock(context->rwlock); return SWITCH_STATUS_SUCCESS; error: switch_thread_rwlock_unlock(context->rwlock); if (err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: %s\n", err); } if (mpg123err) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error from mpg123: %s\n", mpg123err); } free_context(context); return SWITCH_STATUS_GENERR; }
//________________________________________________ // Init lame encoder // frequence : Impose frequency , 0 means reuse the incoming fq // mode : ADM_STEREO etc... // bitrate : Bitrate in kbps (96,192...) // return 0 : init failed // 1 : init succeeded //_______________________________________________ uint8_t AUDMEncoder_Lame::init(ADM_audioEncoderDescriptor *config) { int ret; MPEG_mode_e mmode; uint32_t frequence; LAME_encoderParam *lameConf=(LAME_encoderParam *)config->param; ADM_assert(config->paramSize==sizeof(LAME_encoderParam)); lameFlags = lame_init(); if (lameFlags == NULL) return 0; if(_incoming->getInfo()->channels>2) { printf("Too many channels\n"); return 0; } // recompute output length ret = lame_set_in_samplerate(MYFLAGS, _wavheader->frequency); ret = lame_set_num_channels(MYFLAGS, _wavheader->channels); frequence = _wavheader->frequency; printf("\n output frequency : %lu\n", frequence); ret = lame_set_out_samplerate(MYFLAGS, frequence); ret = lame_set_quality(MYFLAGS, 2); if (_wavheader->channels == 2) { switch (lameConf->mode) { case ADM_STEREO: mmode = STEREO; break; case ADM_JSTEREO: mmode = JOINT_STEREO; break; default: printf("\n **** unknown mode ***\n"); mmode = STEREO; break; } } else { mmode = MONO; printf("\n mono audio mp3"); } ret = lame_set_brate(MYFLAGS, config->bitrate); ret = lame_set_mode(MYFLAGS, mmode); // 0 stereo 1 jstero ret = lame_set_quality(MYFLAGS, lameConf->quality); // 0 stereo 1 jstero ret = lame_set_disable_reservoir(MYFLAGS,lameConf->disableReservoir); printf("[Lame]Using quality of %d\n",lame_get_quality(MYFLAGS)); ret = lame_init_params(MYFLAGS); if (ret == -1) return 0; // update bitrate in header _wavheader->byterate = (config->bitrate >> 3) * 1000; #define BLOCK_SIZE 1152 // configure CBR/ABR/... _preset=lameConf->preset; switch(_preset) { default: case ADM_LAME_PRESET_CBR: break; case ADM_LAME_PRESET_ABR: lame_set_preset( MYFLAGS, config->bitrate); _wavheader->blockalign=BLOCK_SIZE; break; case ADM_LAME_PRESET_EXTREME: _wavheader->blockalign=BLOCK_SIZE; lame_set_preset( MYFLAGS, EXTREME); break; } lame_print_config(MYFLAGS); lame_print_internals(MYFLAGS); _chunk=BLOCK_SIZE*_wavheader->channels; return 1; }
int main(int argc, char **argv) { char mp3buffer[LAME_MAXMP3BUFFER]; short int Buffer[2][1152]; int iread,imp3; lame_global_flags gf; FILE *outf; #ifdef __riscos__ int i; #endif lame_init(&gf); /* initialize libmp3lame */ if(argc==1) lame_usage(&gf,argv[0]); /* no command-line args, print usage, exit */ /* parse the command line arguments, setting various flags in the * struct 'gf'. If you want to parse your own arguments, * or call libmp3lame from a program which uses a GUI to set arguments, * skip this call and set the values of interest in the gf struct. * (see lame.h for documentation about these parameters) */ lame_parse_args(&gf,argc, argv); if (!gf.gtkflag) { /* open the MP3 output file */ if (!strcmp(gf.outPath, "-")) { #ifdef __EMX__ _fsetmode(stdout,"b"); #elif (defined __BORLANDC__) setmode(_fileno(stdout), O_BINARY); #elif (defined __CYGWIN__) setmode(fileno(stdout), _O_BINARY); #elif (defined _WIN32) _setmode(_fileno(stdout), _O_BINARY); #endif outf = stdout; } else { if ((outf = fopen(gf.outPath, "wb")) == NULL) { fprintf(stderr,"Could not create \"%s\".\n", gf.outPath); exit(1); } } #ifdef __riscos__ /* Assign correct file type */ for (i = 0; gf.outPath[i]; i++) if (gf.outPath[i] == '.') gf.outPath[i] = '/'; SetFiletype(gf.outPath, 0x1ad); #endif } /* open the wav/aiff/raw pcm or mp3 input file. This call will * open the file with name gf.inFile, try to parse the headers and * set gf.samplerate, gf.num_channels, gf.num_samples. * if you want to do your own file input, skip this call and set * these values yourself. */ lame_init_infile(&gf); /* Now that all the options are set, lame needs to analyze them and * set some more options */ lame_init_params(&gf); lame_print_config(&gf); /* print usefull information about options being used */ #ifdef HAVEGTK if (gf.gtkflag) gtk_init (&argc, &argv); if (gf.gtkflag) gtkcontrol(&gf); else #endif { /* encode until we hit eof */ do { /* read in 'iread' samples */ iread=lame_readframe(&gf,Buffer); /* encode */ imp3=lame_encode_buffer(&gf,Buffer[0],Buffer[1],iread, mp3buffer,(int)sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3==-1) { fprintf(stderr,"mp3 buffer is not big enough... \n"); exit(1); } if (fwrite(mp3buffer,1,imp3,outf) != imp3) { fprintf(stderr,"Error writing mp3 output"); exit(1); } } while (iread); } imp3=lame_encode_finish(&gf,mp3buffer,(int)sizeof(mp3buffer)); /* may return one more mp3 frame */ fwrite(mp3buffer,1,imp3,outf); fclose(outf); lame_close_infile(&gf); /* close the input file */ lame_mp3_tags(&gf); /* add id3 or VBR tags to mp3 file */ return 0; }
bool AudioEncoderMP3::initialize() { if(lame_flags) { STREAMER_ERROR("error: cannot initialize AudioEncoder because lame_flags has been setup already.\n"); return false; } if(settings.bitsize == AV_AUDIO_BITSIZE_UNKNOWN) { STREAMER_ERROR("error: cannot initialize AudioEncoder because the set bitsize is invalid.\n"); return false; } if(settings.in_bitsize == AV_AUDIO_BITSIZE_UNKNOWN) { settings.in_bitsize = settings.bitsize; } if(settings.mode == AV_AUDIO_MODE_UNKNOWN) { STREAMER_ERROR("error: cannot initialize AudioEncoder because the mode (mono/stereo) is invalid.\n"); return false; } if(settings.samplerate == AV_AUDIO_SAMPLERATE_UNKNOWN) { STREAMER_ERROR("error: cannot intialize the AudioEncoder because the samplerate is invalid.\n"); return false; } if(!settings.bitrate) { STREAMER_ERROR("error: cannot initialize the AudioEncoder because the bitrate was not set.\n"); return false; } if(settings.samplerate == AV_AUDIO_SAMPLERATE_44100) { samplerate = 44100; } else if(settings.samplerate == AV_AUDIO_SAMPLERATE_22050) { samplerate = 22050; } else { STREAMER_ERROR("error: invalid samplerate given for the AudioEncoder.\n"); return false; } if(settings.mode == AV_AUDIO_MODE_STEREO) { mode = STEREO; nchannels = 2; } else if(settings.mode == AV_AUDIO_MODE_MONO) { mode = MONO; nchannels = 1; STREAMER_ERROR("error: for now we only implement stereo audio.\n"); return false; } else { STREAMER_ERROR("error: invalid mode given for the AudioEncoder.\n"); return false; } if(settings.quality > 9) { STREAMER_ERROR("error: invalid quality given for the AudioEncoder, use a value between 0 (best) and 9 (worst).\n"); return false; } lame_flags = lame_init(); if(!lame_flags) { STREAMER_ERROR("error: cannot initalize lame.\n"); return false; } lame_set_num_channels(lame_flags, (mode == STEREO) ? 2 : 1); lame_set_in_samplerate(lame_flags, samplerate); lame_set_brate(lame_flags, settings.bitrate); lame_set_VBR(lame_flags, vbr_off); lame_set_mode(lame_flags, mode); lame_set_quality(lame_flags, settings.quality); if(lame_init_params(lame_flags) < 0) { STREAMER_ERROR("error: cannot initialize the lame parameters.\n"); return false; } #if !defined(NDEBUG) lame_print_config(lame_flags); lame_print_internals(lame_flags); STREAMER_VERBOSE("lame: bitrate: %d\n", lame_get_brate(lame_flags)); #endif bitrate_time_started = uv_hrtime(); bitrate_timeout = bitrate_time_started + bitrate_delay; return true; }