示例#1
0
bool LameAudioWriter::close_private()
{
	if (m_bufferSize < 7200) {
		if (m_buffer) {
			delete [] m_buffer;
		}
		m_bufferSize = 7200;
		m_buffer = new char[m_bufferSize];
	}
	
	bool success = true;
	int size = lame_encode_flush(m_lameInfo->flags,
					(unsigned char*)m_buffer,
					m_bufferSize);
	if (size < 0) {
		PERROR("lame_encode_buffer_flush failed.");
		success = false;
	}
	if (size > 0 && fwrite(m_buffer, 1, size, m_fid) != (nframes_t)size) {
		PERROR("writing mp3 data failed.");
		success = false;
	}
	else {
		lame_mp3_tags_fid(m_lameInfo->flags, m_fid);
	}
	
	lame_close(m_lameInfo->flags);
	m_lameInfo->flags = 0;
	
	fclose(m_fid);
	m_fid = 0;
	
	return success;
}
示例#2
0
static int MP3_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec,
				    struct amci_codec_t *codec)
{
    int final_samples;

    unsigned char  mp3buffer[7200];    
    DBG("MP3: close. \n");
    if(options == AMCI_WRONLY) {
      if (!h_codec || !((mp3_coder_state*)h_codec)->gfp) {
	ERROR("no valid codec handle!\n");
	return -1;
      }

      if ((final_samples = lame_encode_flush(((mp3_coder_state*)h_codec)->gfp,mp3buffer, 7200))) {
	    fwrite(mp3buffer, 1, final_samples, fp);
	    DBG("MP3: flushing %d bytes from MP3 encoder.\n", final_samples);
	}
	lame_mp3_tags_fid(((mp3_coder_state*)h_codec)->gfp,fp);
    }
    return 0;
}
示例#3
0
int encode_to_file(lame_global_flags *gfp, const FMT_DATA *hdr, const short *leftPcm, const short *rightPcm,
	const int iDataSize, const char *filename)
{
	int numSamples = iDataSize / hdr->wBlockAlign;

	int mp3BufferSize = numSamples * 5 / 4 + 7200; // worst case estimate
	unsigned char *mp3Buffer = new unsigned char[mp3BufferSize];

	// call to lame_encode_buffer
	int mp3size = lame_encode_buffer(gfp, (short*)leftPcm, (short*)rightPcm, numSamples, mp3Buffer, mp3BufferSize);
	if (!(mp3size > 0)) {
		delete[] mp3Buffer;
		cerr << "No data was encoded by lame_encode_buffer. Return code: " << mp3size << endl;
		return EXIT_FAILURE;
	}

	// write to file
	FILE *out = fopen(filename, "wb+");
	fwrite((void*)mp3Buffer, sizeof(unsigned char), mp3size, out);

	// call to lame_encode_flush
	int flushSize = lame_encode_flush(gfp, mp3Buffer, mp3BufferSize);

	// write flushed buffers to file
	fwrite((void*)mp3Buffer, sizeof(unsigned char), flushSize, out);

	// call to lame_mp3_tags_fid (might be omitted)
	lame_mp3_tags_fid(gfp, out);

	fclose(out);
	delete[] mp3Buffer;

#ifdef __VERBOSE_
	cout << "Wrote " << mp3size + flushSize << " bytes." << endl;
#endif
	return EXIT_SUCCESS;
}
示例#4
0
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 (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Appending to MP3 not supported.\n");
		}
		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;
		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);
		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);
		}
		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 {
			/* 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, "wb+"))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening %s\n", path);
				goto error;
			}
		}
	}

	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;

}
示例#5
0
static inline void free_context(shout_context_t *context)
{
	int ret;

	if (context) {
		switch_mutex_lock(context->audio_mutex);
		context->err++;
		switch_mutex_unlock(context->audio_mutex);

		if (context->stream_url) {
			int sanity = 0;

			while (context->thread_running) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for stream to terminate: %s\n", context->stream_url);
				switch_yield(500000);
				if (++sanity > 10) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for stream to terminate: %s\n", context->stream_url);
					break;
				}
			}
		}

		switch_thread_rwlock_wrlock(context->rwlock);

		if (context->mh) {
			mpg123_close(context->mh);
			mpg123_delete(context->mh);
		}

		if (context->fp) {
			unsigned char mp3buffer[8192];
			int len;
			int16_t blank[2048] = { 0 }, *r = NULL;


			if (context->channels == 2) {
				r = blank;
			}

			len = lame_encode_buffer(context->gfp, blank, r, sizeof(blank) / 2, mp3buffer, sizeof(mp3buffer));

			if (len) {
				ret = fwrite(mp3buffer, 1, len, context->fp);
			}

			while ((len = lame_encode_flush(context->gfp, mp3buffer, sizeof(mp3buffer))) > 0) {
				ret = fwrite(mp3buffer, 1, len, context->fp);
				if (ret < 0) {
					break;
				}
			}

			lame_mp3_tags_fid(context->gfp, context->fp);

			fclose(context->fp);
			context->fp = NULL;
		}

		if (context->shout) {
			shout_close(context->shout);
			context->shout = NULL;
		}

		if (context->gfp) {
			lame_close(context->gfp);
			context->gfp = NULL;
		}

		if (context->audio_buffer) {
			switch_buffer_destroy(&context->audio_buffer);
		}

		switch_mutex_destroy(context->audio_mutex);

		switch_thread_rwlock_unlock(context->rwlock);
		switch_thread_rwlock_destroy(context->rwlock);
	}
}
示例#6
0
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;
	}
}
示例#7
0
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);
	}
}
示例#8
0
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;
}
示例#9
0
文件: main.c 项目: Molteris/monitord
int
main(int argc, char **argv)
{
    int     ret;
    lame_global_flags *gf;
    char    outPath[PATH_MAX + 1];
    char    nogapdir[PATH_MAX + 1];
    char    inPath[PATH_MAX + 1];

    /* support for "nogap" encoding of up to 200 .wav files */
#define MAX_NOGAP 200
    int    nogapout = 0;
    int     max_nogap = MAX_NOGAP;
    char   *nogap_inPath[MAX_NOGAP];

    int     i;
    FILE   *outf;

#if macintosh
    argc = ccommand(&argv);
#endif

#if defined(_WIN32)
   /* set affinity back to all CPUs.  Fix for EAC/lame on SMP systems from
     "Todd Richmond" <*****@*****.**> */
    typedef BOOL (WINAPI *SPAMFunc)(HANDLE, DWORD);
    SPAMFunc func;
    SYSTEM_INFO si;

    if ((func = (SPAMFunc)GetProcAddress(GetModuleHandle("KERNEL32.DLL"),
        "SetProcessAffinityMask")) != NULL) {
        GetSystemInfo(&si);
        func(GetCurrentProcess(), si.dwActiveProcessorMask);
    }
#endif


#ifdef __EMX__
    /* This gives wildcard expansion on Non-POSIX shells with OS/2 */
    _wildcard(&argc, &argv);
#endif

    for (i = 0; i < max_nogap; ++i) {
        nogap_inPath[i] = malloc(PATH_MAX + 1);
    }

    memset(inPath, 0, sizeof(inPath));
    
    /* initialize libmp3lame */
    input_format = sf_unknown;
    if (NULL == (gf = lame_init())) {
        fprintf(stderr, "fatal error during initialization\n");
        return 1;
    }
    if (argc <= 1) {
        usage(stderr, argv[0]); /* no command-line args, print usage, exit  */
        return 1;
    }

    /* 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 the file API and lame.h for documentation about these parameters)
     */
    parse_args_from_string(gf, getenv("LAMEOPT"), inPath, outPath);
    ret = parse_args(gf, argc, argv, inPath, outPath, nogap_inPath, &max_nogap);
    if (ret < 0)
        return ret == -2 ? 0 : 1;

    if (update_interval < 0.)
        update_interval = 2.;

    if (outPath[0] != '\0' && max_nogap>0) {
        strncpy(nogapdir, outPath, PATH_MAX + 1);  
        nogapout = 1;
    }
    
    /* initialize input file.  This also sets samplerate and as much
       other data on the input file as available in the headers */
    if (max_nogap > 0) {
        /* for nogap encoding of multiple input files, it is not possible to
         * specify the output file name, only an optional output directory. */
        parse_nogap_filenames(nogapout,nogap_inPath[0],outPath,nogapdir);
        outf = init_files(gf, nogap_inPath[0], outPath);
    }
    else {
        outf = init_files(gf, inPath, outPath);
    }
    if (outf == NULL) {
        return -1;
    }

    /* Now that all the options are set, lame needs to analyze them and
     * set some more internal options and check for problems
     */
    i = lame_init_params(gf);
    if (i < 0) {
        if (i == -1) {
            display_bitrates(stderr);
        }
        fprintf(stderr, "fatal error during initialization\n");
        return i;
    }

    if (silent > 0 
#ifndef RH_HIST   
    || lame_get_VBR(gf) == vbr_off
#endif
    ) {
        brhist = 0;     /* turn off VBR histogram */
    }


    if (lame_get_decode_only(gf)) {
        /* decode an mp3 file to a .wav */
        if (mp3_delay_set)
            lame_decoder(gf, outf, mp3_delay, inPath, outPath);
        else
            lame_decoder(gf, outf, 0, inPath, outPath);

    }
    else {
        if (max_nogap > 0) {
            /*
             * encode multiple input files using nogap option
             */
            for (i = 0; i < max_nogap; ++i) {
                int     use_flush_nogap = (i != (max_nogap - 1));
                if (i > 0) {
                    parse_nogap_filenames(nogapout,nogap_inPath[i],outPath,nogapdir);
                    /* note: if init_files changes anything, like
                       samplerate, num_channels, etc, we are screwed */
                    outf = init_files(gf, nogap_inPath[i], outPath);
                }
                brhist_init_package(gf);
                lame_set_nogap_total(gf, max_nogap);
                lame_set_nogap_currentindex(gf, i);
                ret =
                    lame_encoder(gf, outf, use_flush_nogap, nogap_inPath[i],
                                 outPath);	
                
                if (silent<=0) print_lame_tag_leading_info(gf);
                lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */
		
                if (silent<=0) print_trailing_info(gf);
                
                fclose(outf); /* close the output file */
                close_infile(); /* close the input file */

                /* reinitialize bitstream for next encoding.  this is normally done
                 * by lame_init_params(), but we cannot call that routine twice */
                if (use_flush_nogap) 
                    lame_init_bitstream(gf);
            }
            lame_close(gf);

        }
        else {
            /*
             * encode a single input file
             */
            brhist_init_package(gf);
            ret = lame_encoder(gf, outf, 0, inPath, outPath);
            
            if (silent<=0) print_lame_tag_leading_info(gf);
            lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */
	    
            if (silent<=0) print_trailing_info(gf);
            
            fclose(outf); /* close the output file */
            close_infile(); /* close the input file */
            lame_close(gf);
        }
    }
    return ret;
}