Пример #1
0
int  main ( int argc, char **argv )
{
    unsigned char       mp3buffer [LAME_MAXMP3BUFFER];
    char       inPath    [PATH_MAX + 1];
    char       outPath   [PATH_MAX + 1];
    int        Buffer [2] [1152];

    lame_global_flags *gf;
    
    int        ret;
    int        wavsamples;
    int        mp3bytes;
    FILE*      outf;

    char       ip [16];
    unsigned   port = 5004;
    unsigned   ttl  =    2;
    char       dummy;

    if ( argc <= 2 ) {
        fprintf ( stderr, 
"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:
        fprintf (stderr, "Illegal destination selector '%s', must be ip[:port[:ttl]]\n", argv[1] );
	return -1;
    }

    rtpsocket = makesocket ( ip, port, ttl, &rtpsi );
    srand ( getpid () ^ time (NULL) );
    initrtp ( &RTPheader );

    /* initialize encoder */
    gf=lame_init();

    /* 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)
     */
     
    argv[1] = argv[0]; 
    parse_args(gf, argc - 1, argv + 1, inPath, outPath,NULL,NULL);

    /* open the output file.  Filename parsed into gf.inPath */
    if ( 0 == strcmp ( outPath, "-" ) ) {
        lame_set_stream_binary_mode (outf = stdout);
    }
    else {
        if ((outf = fopen (outPath, "wb+")) == NULL) {
            fprintf (stderr, "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.  
     */
    init_infile(gf,inPath);


    /* 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);
        fprintf (stderr, "fatal error during initialization\n");
        return -1;
    }

    lame_print_config(gf); /* print useful information about options being used */

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

    /* encode until we hit EOF */
    while ( (wavsamples = get_audio(gf, Buffer)) > 0 ) { /* read in 'wavsamples' samples */
        levelmessage ( maxvalue (Buffer) );
        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 */
    
    lame_close(gf);
    fclose(outf);
    close_infile();                 /* close the sound input file */
    
    return 0;
}
Пример #2
0
bool Mp3Writer::write(QByteArray &left, QByteArray &right, long samples, bool flush) {
	int ret;
	QByteArray output;
	// rough upper bound formula taken from lame.h
	long size = samples + samples / 4 + 7200;

	do {
		output.resize(size);

		if (stereo) {
			ret = lame_encode_buffer(lame, reinterpret_cast<const short *>(left.constData()),
				reinterpret_cast<const short *>(right.constData()), samples,
				reinterpret_cast<unsigned char *>(output.data()), output.size());
		} else {
			// lame.h claims to write to the buffers, even though they're declared const, be safe
			// TODO: this mixes both channels again!  can lame take only mono samples?
			ret = lame_encode_buffer(lame, reinterpret_cast<const short *>(left.data()),
				reinterpret_cast<const short *>(left.data()), samples,
				reinterpret_cast<unsigned char *>(output.data()), output.size());
		}

		if (ret == -1) {
			// there wasn't enough space in output
			size *= 2;
			continue;
		}
	} while (false);

	if (ret < 0) {
		debug(QString("Error while writing MP3 file, code = %1").arg(ret));
		return false;
	}

	samplesWritten += samples;

	if (ret > 0) {
		output.truncate(ret);
		file.write(output);
	}

	left.remove(0, samples * 2);
	if (stereo)
		right.remove(0, samples * 2);

	if (!flush)
		return true;

	// flush mp3

	output.resize(10240);
	ret = lame_encode_flush(lame, reinterpret_cast<unsigned char *>(output.data()), output.size());

	lame_close(lame);
	lame = NULL;
	hasFlushed = true;

	if (ret < 0) {
		debug(QString("Error while flushing MP3 file, code = %1").arg(ret));
		return false;
	}

	if (ret > 0) {
		output.truncate(ret);
		file.write(output);
	}

	return true;
}
void Java_ice_caster_android_shout_Lame_close(
		JNIEnv *env, jclass cls) {
	lame_close(glf);
	glf = NULL;
}
Пример #4
0
/* ======================================================================= */
BOOL EncodeTrack(PWINDOWHANDLES H, DWORD Index, PCHAR BasePath, HANDLE CDHandle, PCDTRACK CDTrackData, PDWORD DiscCurrent, PDWORD DiscTotal, PDWORD TrackCount)
{
  Log(LOG_WRITE, "Encoding track %u/%u; Sector %u-%u/%u", Index+1, *TrackCount, CDTrackData[Index].Address, CDTrackData[Index].Address + CDTrackData[Index].Length - 1, CDTrackData[Index].Length);

  CHAR MP3FilePath[MAX_PATH];
  CHAR MP3FilePathFancy[MAX_PATH];

  HANDLE MP3FileHandle = INVALID_HANDLE_VALUE;
  static lame_global_flags *GFP = NULL;

  if(OneTrackOnly == 0)
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Track %u.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    SetLabel(H->WT, "Creating file %s...", MP3FilePath);
    MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  }
  else
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Audio.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    switch(OneTrackOnly)
    {
      case 1:
        SetLabel(H->WT, "Creating solid file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        OneTrackOnly = 2;
        break;
      case 2:
        SetLabel(H->WT, "Re-opening file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if(MP3FileHandle != INVALID_HANDLE_VALUE)
          SetFilePointer(MP3FileHandle, 0, NULL, FILE_END);
        break;
    }
  }

  BOOL Success = TRUE;
  INT EncoderReturnCode = 0;

  if(MP3FileHandle != INVALID_HANDLE_VALUE)
  {
    Log(LOG_WRITE, "Created file %s", MP3FilePath);

    DWORD DiscLastCurrent = *DiscCurrent;
    DWORD SectorTotal = CDTrackData[Index].Length/SECTORS_AT_READ;
    DWORD MP3BytesWritten;

    SendMessage(H->PO, PBM_SETRANGE32, 0, SectorTotal);
    SendMessage(H->PO, PBM_SETPOS, 0, 0);
    SendMessage(H->PA, PBM_SETRANGE32, 0, *DiscTotal);

    if(GFP == NULL)
    {
      GFP = lame_init();

      lame_set_preset(GFP, MP3Quality);
      lame_set_copyright(GFP, 1);
      lame_set_original(GFP, 1);
      lame_set_error_protection(GFP, 1);
      lame_set_extension(GFP, 1);
      lame_set_quality(GFP, Quality);

      EncoderReturnCode = lame_init_params(GFP);
    }

    if(EncoderReturnCode == 0)
    {
      DWORD dwWAVBufferSize=(1152 * lame_get_num_channels(GFP));
      DWORD dwMP3BufferSize=(DWORD)(1.25*(dwWAVBufferSize/lame_get_num_channels(GFP))+7200);
      PBYTE MP3Buffer = new BYTE[dwMP3BufferSize];
      PBYTE CDBuffer = new BYTE[SECTORS_AT_READ * RAW_SECTOR_SIZE];
      INT nOutputSamples;
      DWORD CDBytesWritten;
      RAW_READ_INFO Info;
      Info.TrackMode = CDDA;
      Info.SectorCount = SECTORS_AT_READ;
      DWORD SectorCurrent;
      TCHAR NumWritten[30];
      TCHAR NumWrittenKB[30];

      for(SectorCurrent = 0; SectorCurrent < SectorTotal; ++SectorCurrent, ++*DiscCurrent)
      {
        Info.DiskOffset.QuadPart = (CDTrackData[Index].Address + SectorCurrent*SECTORS_AT_READ) * CD_SECTOR_SIZE;
        MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
        Comma(MP3BytesWritten, NumWritten, sizeof(NumWritten));
        Comma(MP3BytesWritten / 1024, NumWrittenKB, sizeof(NumWrittenKB));
        SetLabel(H->WT, "Encoding track %u of %u and sector %u of %u\nTo %s\nWritten %s bytes (%s KB) to file", Index + 1, *TrackCount, SectorCurrent, SectorTotal - 1, MP3FilePathFancy, NumWritten, NumWrittenKB);
        if(DeviceIoControl(CDHandle, IOCTL_CDROM_RAW_READ, &Info, sizeof(Info), CDBuffer, SECTORS_AT_READ*RAW_SECTOR_SIZE, &CDBytesWritten, NULL) != 0)
        {
          if(EncodeAudioBuffer(CDBuffer, CDBytesWritten, dwWAVBufferSize, MP3FileHandle, MP3Buffer, GFP) == FALSE)
          {
            Log(LOG_WRITE, "Encoding of audio buffer failed");
            Success = FALSE;
            break;
          }
        }
        else
        {
          DWORD ErrorCode = GetLastError();
          if(ErrorCode == ERROR_INVALID_FUNCTION)
          {
            Log(LOG_WRITE, "Track %u is not a valid CDDA track", Index + 1);
            Success = FALSE;
            break;
          }
          else if(ErrorCode != ERROR_INVALID_PARAMETER)
          {
            Log(LOG_WRITE, "Error code %u reading track %u!", ErrorCode, Index + 1);
            Success = FALSE;
            break;
          }
        }
        SendMessage(H->PO, PBM_SETPOS, SectorCurrent, 0);
        SendMessage(H->PA, PBM_SETPOS, *DiscCurrent, 0);
        Percentage = (float)((float)*DiscCurrent / (float)*DiscTotal) * 100;
      }

      if(Success == FALSE)
      {
        *DiscTotal -= SectorTotal;
        SectorTotal = 0;
      }
      else if(OneTrackOnly == 0 || Index+1 == *TrackCount)
      {
        nOutputSamples = lame_encode_flush_nogap(GFP, MP3Buffer, LAME_MAXMP3BUFFER);

        if(nOutputSamples > 0)
        {
          if(WriteFile(MP3FileHandle, MP3Buffer, nOutputSamples, &MP3BytesWritten, NULL) == FALSE)
          {
            Log(LOG_WRITE, "Failed to write %u final bytes to file", nOutputSamples);
            Success = FALSE;
          }
          else if(nOutputSamples != (int)MP3BytesWritten)
          {
            Log(LOG_WRITE, "Written %u final bytes instead of %u bytes to file", MP3BytesWritten, nOutputSamples);
            Success = FALSE;
          }
        }
        else if(nOutputSamples < 0)
        {
          Log(LOG_WRITE, "Error code %d flushing encoded audio buffer", nOutputSamples);
          Success = FALSE;
        }
      }

      *DiscCurrent = DiscLastCurrent + SectorTotal;
      SendMessage(H->PO, PBM_SETPOS, *DiscCurrent, 0);
    }
    else
    {
      Log(LOG_WRITE, "Error code %d initialising audio encoder", EncoderReturnCode);
      Success = FALSE;
    }

    MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
    if(CloseHandle(MP3FileHandle) == FALSE)
    {
      Log(LOG_WRITE, "Error code %u closing file handle");
      Success = FALSE;
    }
    if(OneTrackOnly == 0 && (MP3BytesWritten == 0 || Success == FALSE))
    {
      if(DeleteFile(MP3FilePath) == FALSE)
        Log(LOG_WRITE, "Error code %u deleting file");
      else
        Log(LOG_WRITE, "Deleted the file due to error");
    }
    else Log(LOG_WRITE, "Written %u bytes to file", MP3BytesWritten);
  }
  else
  {
    Log(LOG_WRITE, "Error code %u creating %s", GetLastError(), MP3FilePath);
    Success = FALSE;
  }

  if(EncoderReturnCode == 0 && (OneTrackOnly == 0 || Index+1 == *TrackCount))
  {
    lame_close(GFP);
    GFP = NULL;
  }

  return Success;
}
Пример #5
0
int WMp3Encoder::Initialize(unsigned int nSampleRate, unsigned int nNumberOfChannels, unsigned int nBitPerSample,
			unsigned int custom_value,
			TEncoderReadCallback read_callback,
			TEncoderWriteCallback write_callback,
			TEncoderSeekCallback seek_callback,
			TEncoderTellCallback tell_callback)
{
	c_nSampleRate = nSampleRate;
	c_nNumberOfChannels = nNumberOfChannels;
	c_nBitBerSample = nBitPerSample;

	c_read_calllback = read_callback;
	c_write_callback = write_callback;
	c_seek_callback = seek_callback;
	c_tell_callback = tell_callback;

	c_user_data = (void*) custom_value;

	// init encoder
	gfp = lame_init();

	if(gfp == NULL)
	{
		err(ENCODER_INIT_ERROR);
		return 0;
	}

   lame_set_num_channels(gfp, c_nNumberOfChannels);
   lame_set_in_samplerate(gfp, c_nSampleRate);
   lame_set_brate(gfp, 128);
   lame_set_mode(gfp, JOINT_STEREO);
   lame_set_quality(gfp, 7);   /* 2=high  5 = medium  7=low */ 
   lame_set_VBR(gfp, vbr_off);

   if(lame_init_params(gfp) < 0)
   {
		lame_close(gfp);
		err(ENCODER_INIT_ERROR);
		return 0;
   }


  //LAME encoding call will accept any number of samples.  
    if ( 0 == lame_get_version( gfp ) )
    {
        // For MPEG-II, only 576 samples per frame per channel
        c_NumberOfInputSamples = 576 * lame_get_num_channels( gfp );
    }
    else
    {
        // For MPEG-I, 1152 samples per frame per channel
        c_NumberOfInputSamples = 1152 * lame_get_num_channels( gfp );
    }


    // Set MP3 buffer size, conservative estimate
    c_nSamplesBufferSizeInBytes = (DWORD)( 1.25 * ( c_NumberOfInputSamples / lame_get_num_channels( gfp ) ) + 7200 );

	// allocate  working buffer
	c_pWorkingBuffer = (unsigned char*) malloc(c_nSamplesBufferSizeInBytes);
	if(c_pWorkingBuffer == NULL)
	{
		lame_close(gfp);
		err(ENCODER_MEMORY_ALLOCATION_FAIL);
		return 0;

	}


	c_fReady = 1;
	return 1;
}
Пример #6
0
 ~MP3Encoder()
 {
     lame_close(lgf);
 }
Пример #7
0
/*
 * Class:     lzzy_soft_lamemp3_JNIMp3Encode
 * Method:    destroy
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_lzzy_soft_lamemp3_JNIMp3Encode_destroy
(JNIEnv *env, jobject obj)
{
	lame_close(lame);
}
Пример #8
0
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(gf, 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 || lame_get_VBR(gf) == vbr_off) {
        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);
                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;
}
JNIEXPORT void JNICALL Java_cn_net_xyd_videoaudiodemo_mp3lame_SimpleLame_close(
        JNIEnv *env, jclass cls) {
lame_close(glf);
glf = NULL;
}
Пример #10
0
OutLame::~OutLame() {
  func("OutLame::~OutLame() %p",this);
  act("closing lame encoder");
  //  if(running) flush();
  if(enc_flags) lame_close(enc_flags);
}
Пример #11
0
bool OutLame::apply_profile() {


  if(enc_flags) lame_close(enc_flags);
  enc_flags = lame_init();

  lame_set_errorf(enc_flags,(void (*)(const char*, va_list))error);
  lame_set_debugf(enc_flags,(void (*)(const char*, va_list))func);
  lame_set_msgf(enc_flags,(void (*)(const char*, va_list))act);
  
  lame_set_num_samples(enc_flags,OUT_CHUNK);
  lame_set_num_channels(enc_flags,2); // the mixed input stream is stereo
  lame_set_in_samplerate(enc_flags,SAMPLE_RATE); // the mixed input stream is 44khz
  lame_set_error_protection(enc_flags,1); // 2 bytes per frame for a CRC checksum
  lame_set_compression_ratio(enc_flags,0);
  lame_set_quality(enc_flags,2); // 1..9 1=best 9=worst (suggested: 2, 5, 7)
  //  lame_set_VBR(enc_flags,vbr_abr);


  /* BITRATE */
  lame_set_brate(enc_flags,bps());

  Shouter *ice = (Shouter*)icelist.begin();
  while(ice) {
    char tmp[256];

    snprintf(tmp,256,"%u",bps());       ice->bps( tmp );
    snprintf(tmp,256,"%u",freq());      ice->freq( tmp );
    snprintf(tmp,256,"%u",channels());  ice->channels( tmp );
    
    ice = (Shouter*)ice->next;
  }

  lame_set_out_samplerate(enc_flags,freq());

  /* CHANNELS
     mode 2 (double channel) is unsupported */
  int mode;
  switch( channels() ) {
    /* 0,1,2,3 stereo,jstereo,dual channel,mono */
  case 1: mode = 3; break;
  case 2: mode = 1; break;
  default: mode = 3; break;
  }
  lame_set_mode(enc_flags,(MPEG_mode_e)mode);


  /* in case of VBR 
  func("reversed quality is %i, guessed bps %i",(int)fabs( 10 - quality()),bps());
  lame_set_VBR_q(enc_flags,(int)fabs( 10 - quality() ));
  lame_set_VBR_mean_bitrate_kbps(enc_flags,bps());
  */

  /* lame chooses for us frequency filtering when values are 0 */
  lame_set_lowpassfreq(enc_flags,lowpass());
  lame_set_highpassfreq(enc_flags,highpass());  
  
  int res = lame_init_params(enc_flags);
  if(res<0) {
    error("lame_init_params failed");
    lame_close(enc_flags);
    enc_flags = NULL;
  }

  return (res<0)?false:true;

}