mirror of https://github.com/sipwise/sems.git
git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@32 8eb893ce-cfd4-0310-b710-fb5ebe64c474sayer/1.4-spce2.6
parent
3aacc375a6
commit
3d34a388e1
@ -0,0 +1,20 @@
|
||||
plug_in_name = mp3
|
||||
|
||||
COREPATH ?=../../core
|
||||
LAME_DIR = ./lame-3.96.1
|
||||
|
||||
#module_ldflags = -L$(LAME_DIR)/libmp3lame/.libs
|
||||
module_extra_objs = $(LAME_DIR)/libmp3lame/.libs/libmp3lame.a
|
||||
|
||||
module_cflags = -I$(LAME_DIR)/include
|
||||
|
||||
extra_clean =
|
||||
|
||||
include $(COREPATH)/plug-in/Makefile.audio_module
|
||||
|
||||
#.PHONY: clean_libmp3lame
|
||||
#clean_libmp3lame:
|
||||
# cd $(LAME_DIR); $(MAKE) clean
|
||||
|
||||
$(LAME_DIR)/libmp3lame/.libs/libmp3lame.a:
|
||||
cd $(LAME_DIR); ./configure ; $(MAKE)
|
||||
@ -0,0 +1,32 @@
|
||||
Lame MP3 file writing plug-in for SEMS Readme
|
||||
|
||||
Description
|
||||
-----------
|
||||
This mp3 plug-in enables MP3 file writing for SEMS. In order to use
|
||||
it, you must get the lame library sources first. Files recorded with
|
||||
the extension "MP3" or "mp3" are recorded as mp3 if possible.
|
||||
|
||||
Quickstart
|
||||
----------
|
||||
cd plug-in/mp3 ; wget http://switch.dl.sourceforge.net/sourceforge/lame/lame-3.96.1.tar.gz ;
|
||||
tar xzvf lame-3.96.tar.gz ; make
|
||||
|
||||
Installation
|
||||
------------
|
||||
1) Get lame from lame.sourceforge.net (
|
||||
http://sourceforge.net/project/showfiles.php?group_id=290)
|
||||
2) Unpack the archive
|
||||
3) edit LAME_DIR in mp3 plug-in Makefile to point to the location of
|
||||
the unpacked lame source archive
|
||||
4) make in plug-in/mp3 directory
|
||||
|
||||
Important Note:
|
||||
--------------
|
||||
Using the LAME encoding engine (or other mp3 encoding technology) in
|
||||
your software may require a patent license in some countries.
|
||||
See http://www.mp3licensing.com/ or
|
||||
http://lame.sourceforge.net/links.html#patents for further information.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* $Id: mp3.c,v 1.2 2004/06/16 12:30:46 rco Exp $
|
||||
*
|
||||
* Copyright (C) 2002-2003 Fhg Fokus
|
||||
*
|
||||
* This file is part of sems, a free SIP media server.
|
||||
*
|
||||
* sems is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version
|
||||
*
|
||||
* For a license to use the ser software under conditions
|
||||
* other than those described here, or to purchase support for this
|
||||
* software, please contact iptel.org by e-mail at the following addresses:
|
||||
* info@iptel.org
|
||||
*
|
||||
* sems is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "amci.h"
|
||||
#include "codecs.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lame.h"
|
||||
|
||||
/**
|
||||
* @file plug-in/mp3/mp3.c
|
||||
* lame-MP3 support
|
||||
* This plug-in writes MP3 files using lame encoder.
|
||||
*
|
||||
* Set LAME_DIR in Makefile first!
|
||||
*
|
||||
* See http://lame.sourceforge.net/ .
|
||||
*
|
||||
*/
|
||||
|
||||
#define MP3_phone 1
|
||||
|
||||
static int MP3_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
static int Pcm16_2_MP3( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
static long MP3_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
static void MP3_destroy(long h_inst);
|
||||
static int MP3_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec);
|
||||
static int MP3_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec);
|
||||
|
||||
BEGIN_EXPORTS( "mp3" )
|
||||
BEGIN_CODECS
|
||||
CODEC( CODEC_MP3, 1, Pcm16_2_MP3, MP3_2_Pcm16, (amci_plc_t)0, (amci_codec_init_t)MP3_create, (amci_codec_destroy_t)MP3_destroy )
|
||||
END_CODECS
|
||||
|
||||
BEGIN_PAYLOADS
|
||||
END_PAYLOADS
|
||||
|
||||
BEGIN_FILE_FORMATS
|
||||
BEGIN_FILE_FORMAT( "MP3", "mp3", "audio/x-mp3", MP3_open, MP3_close)
|
||||
BEGIN_SUBTYPES
|
||||
SUBTYPE( MP3_phone, "MP3", 8000, 1, CODEC_MP3 )
|
||||
END_SUBTYPES
|
||||
END_FILE_FORMAT
|
||||
END_FILE_FORMATS
|
||||
|
||||
END_EXPORTS
|
||||
|
||||
|
||||
void no_output(const char *format, va_list ap)
|
||||
{
|
||||
return;
|
||||
// (void) vfprintf(stdout, format, ap);
|
||||
}
|
||||
|
||||
long MP3_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) {
|
||||
lame_global_flags* gfp;
|
||||
int ret_code;
|
||||
|
||||
DBG("MP3: creating lame %s\n", get_lame_version());
|
||||
format_description[0].id = 0;
|
||||
gfp = lame_init();
|
||||
|
||||
if (!gfp)
|
||||
return -1;
|
||||
|
||||
lame_set_errorf(gfp, &no_output);
|
||||
lame_set_debugf(gfp, &no_output);
|
||||
lame_set_msgf(gfp, &no_output);
|
||||
|
||||
lame_set_num_channels(gfp,1);
|
||||
lame_set_in_samplerate(gfp,8000);
|
||||
lame_set_brate(gfp,16);
|
||||
lame_set_mode(gfp,3); // mono
|
||||
lame_set_quality(gfp,7); /* 2=high 5 = medium 7=low */
|
||||
|
||||
id3tag_init(gfp);
|
||||
id3tag_set_title(gfp, "mp3 voicemail by iptel.org");
|
||||
ret_code = lame_init_params(gfp);
|
||||
|
||||
if (ret_code < 0) {
|
||||
DBG("lame encoder init failed: return code is %d\n", ret_code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (long)gfp;
|
||||
}
|
||||
|
||||
void MP3_destroy(long h_inst) {
|
||||
if (h_inst)
|
||||
free((lame_global_flags*) h_inst);
|
||||
}
|
||||
|
||||
static int Pcm16_2_MP3( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec )
|
||||
{
|
||||
|
||||
if (!h_codec){
|
||||
ERROR("MP3 codec not initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
if ((channels!=1)||(rate!=8000)) {
|
||||
ERROR("Unsupported input format for MP3 encoder.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DBG("h_codec=0x%lx; in_buf=0x%lx; size=%i\n", */
|
||||
/* (unsigned long)h_codec,(unsigned long)in_buf,size); */
|
||||
|
||||
int ret = lame_encode_buffer((lame_global_flags*)h_codec,
|
||||
(short*) in_buf, // left channel
|
||||
/* (short*) in_buf */0, // right channel
|
||||
size / 2 , // no of samples (size is in bytes!)
|
||||
out_buf,
|
||||
AUDIO_BUFFER_SIZE);
|
||||
|
||||
switch(ret){
|
||||
// 0 is valid: if not enough samples for an mp3
|
||||
//frame lame will not return anything
|
||||
case 0: /*DBG("lame_encode_buffer returned 0\n");*/ break;
|
||||
case -1: ERROR("mp3buf was too small\n"); break;
|
||||
case -2: ERROR("malloc() problem\n"); break;
|
||||
case -3: ERROR("lame_init_params() not called\n"); break;
|
||||
case -4: ERROR("psycho acoustic problems\n"); break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int MP3_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec )
|
||||
{
|
||||
ERROR("MP3 decoding not supported yet.\n");
|
||||
return -1;
|
||||
|
||||
/* mp3data_struct mp3data; */
|
||||
/* int dec_length = 0; */
|
||||
/* dec_length = lame_decode( */
|
||||
/* in_buf, */
|
||||
/* size, */
|
||||
/* (short*) out_buf, // left channel */
|
||||
/* (short*) out_buf); //right channel -- we assume mono. */
|
||||
|
||||
/* return dec_length*2; // sample size = 2 */
|
||||
}
|
||||
|
||||
#define SAFE_READ(buf,s,fp,sr) \
|
||||
sr = fread(buf,s,1,fp);\
|
||||
if((sr != 1) || ferror(fp)) return -1;
|
||||
|
||||
#define SAFE_WRITE(buf,s,fp) \
|
||||
fwrite(buf,s,1,fp);\
|
||||
if(ferror(fp)) return -1;
|
||||
|
||||
static int MP3_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec)
|
||||
{
|
||||
// mp3data_struct mp3data;
|
||||
// unsigned char* mp_hdr;
|
||||
// short* dummy_pcm;
|
||||
|
||||
DBG("mp3_open.\n");
|
||||
|
||||
if(options == AMCI_RDONLY){
|
||||
ERROR("Sorry, MP3 file reading is not supported yet.\n");
|
||||
return -1;
|
||||
|
||||
/* if (!(mp_hdr = malloc(0x80))) { */
|
||||
/* ERROR("MP3: could not allocate memory for mp3 header decode.\n"); */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
/* if (!(dummy_pcm = malloc(320*2))) { */
|
||||
/* ERROR("MP3: could not allocate memory for mp3 header decode.\n"); */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
|
||||
/* SAFE_READ(mp_hdr, 1, 0x80, fp); */
|
||||
/* if (lame_decode_headers(mp_hdr, 0x80, dummy_pcm, dummy_pcm, &mp3data)==-1) { */
|
||||
/* ERROR("MP3: cannot decode MP3 header."); */
|
||||
/* return -1; */
|
||||
/* } */
|
||||
|
||||
/* if (mp3data.header_parsed) { */
|
||||
/* fmt_desc->subtype = 1; */
|
||||
/* fmt_desc->sample = 2; */
|
||||
/* fmt_desc->rate = mp3data.bitrate; */
|
||||
/* fmt_desc->channels = mp3data.stereo; */
|
||||
/* } else { */
|
||||
/* ERROR("MP3: header could not be parsed.\n"); */
|
||||
/* } */
|
||||
|
||||
/* free(mp_hdr); */
|
||||
/* free(dummy_pcm); */
|
||||
|
||||
/* return 0; */
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int MP3_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec)
|
||||
{
|
||||
int final_samples;
|
||||
|
||||
char mp3buffer[7200];
|
||||
DBG("MP3: close. \n");
|
||||
if(options == AMCI_WRONLY) {
|
||||
if ((final_samples = lame_encode_flush((lame_global_flags *)h_codec,mp3buffer, 7200))) {
|
||||
fwrite(mp3buffer, 1, final_samples, fp);
|
||||
DBG("MP3: flushing %d bytes from MP3 encoder.\n", final_samples);
|
||||
}
|
||||
lame_mp3_tags_fid((lame_global_flags *)h_codec,fp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in new issue