internal void set_frame_pinfo(LameGlobalFlags gfp, III_psy_ratio[][] ratio) { var gfc = gfp.internal_flags; gfc.masking_lower = 1.0f; for (var gr = 0; gr < gfc.mode_gr; gr++) { for (var ch = 0; ch < gfc.channels_out; ch++) { var cod_info = gfc.l3_side.tt[gr][ch]; var scalefac_sav = new int[L3Side.SFBMAX]; Array.Copy(cod_info.scalefac, 0, scalefac_sav, 0, scalefac_sav.Length); if (gr == 1) { int sfb; for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { if (cod_info.scalefac[sfb] < 0) { cod_info.scalefac[sfb] = gfc.l3_side.tt[0][ch].scalefac[sfb]; } } } set_pinfo(gfp, cod_info, ratio[gr][ch], gr, ch); Array.Copy(scalefac_sav, 0, cod_info.scalefac, 0, scalefac_sav.Length); } } }
internal virtual int read_samples_mp3(LameGlobalFlags gfp, FileStream musicin, short[][] mpg123pcm) { int @out; @out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], parse.mp3input_data); if (@out < 0) { Arrays.Fill(mpg123pcm[0], (short)0); Arrays.Fill(mpg123pcm[1], (short)0); return(0); } if (gfp.num_channels != parse.mp3input_data.stereo) { if (parse.silent < 10) { Console.WriteLine("Error: number of channels has changed in %s - not supported\n", type_name); } @out = -1; } if (gfp.in_samplerate != parse.mp3input_data.samplerate) { if (parse.silent < 10) { Console.WriteLine("Error: sample frequency has changed in %s - not supported\n", type_name); } @out = -1; } return(@out); }
} // main_data /* * compute the number of bits required to flush all mp3 frames currently in * the buffer. This should be the same as the reservoir size. Only call this * routine between frames - i.e. only after all headers and data have been * added to the buffer by format_bitstream(). * * Also compute total_bits_output = size of mp3 buffer (including frame * headers which may not have yet been send to the mp3 buffer) + number of * bits needed to flush all mp3 frames. * * total_bytes_output is the size of the mp3 output buffer if * lame_encode_flush_nogap() was called right now. */ private int compute_flushbits(LameGlobalFlags gfp, TotalBytes total_bytes_output) { var gfc = gfp.internal_flags; int flushbits, remaining_headers; int bitsPerFrame; int last_ptr, first_ptr; first_ptr = gfc.w_ptr; /* first header to add to bitstream */ last_ptr = gfc.h_ptr - 1; /* last header to add to bitstream */ if (last_ptr == -1) { last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; } /* add this many bits to bitstream so we can flush all headers */ flushbits = gfc.header[last_ptr].write_timing - totbit; total_bytes_output.total = flushbits; if (flushbits >= 0) { /* if flushbits >= 0, some headers have not yet been written */ /* reduce flushbits by the size of the headers */ remaining_headers = 1 + last_ptr - first_ptr; if (last_ptr < first_ptr) { remaining_headers = 1 + last_ptr - first_ptr + LameInternalFlags.MAX_HEADER_BUF; } flushbits -= remaining_headers * 8 * gfc.sideinfo_len; } /* * finally, add some bits so that the last frame is complete these bits * are not necessary to decode the last frame, but some decoders will * ignore last frame if these bits are missing */ bitsPerFrame = getframebits(gfp); flushbits += bitsPerFrame; total_bytes_output.total += bitsPerFrame; /* round up: */ if (total_bytes_output.total % 8 != 0) { total_bytes_output.total = 1 + total_bytes_output.total / 8; } else { total_bytes_output.total = total_bytes_output.total / 8; } total_bytes_output.total += bufByteIdx + 1; if (flushbits < 0) { Console.Error.WriteLine("strange error flushing buffer ... \n"); } return(flushbits); }
private int id3tag_set_textinfo_latin1(LameGlobalFlags gfp, string id, string text) { long t_mask = FRAME_ID('T', (char)0, (char)0, (char)0); var frame_id = toID3v2TagId(id); if (frame_id == 0) { return(-1); } if ((frame_id & t_mask) == t_mask) { if (ReferenceEquals(text, null)) { return(0); } if (gfp != null) { id3v2_add_latin1(gfp, frame_id, null, null, text); return(0); } } return(-255); }
public int seek(LameGlobalFlags gfp) { int samples_read; int framesize; var num_channels = gfp.num_channels; int samples_to_read = framesize = gfp.framesize; if (is_mpeg_file_format(parse.input_format)) { if (first) { first = false; offset = (int)(musicin.Position - hip.bsize - hip.tail.pos); FirstFrameOffset = offset; } samples_read = lame_decode_fromfile(musicin, null, null, parse.mp3input_data, true); LastHeaderPosition = hip.lastHeader + FirstFrameOffset; if (samples_read < 0) { return(samples_read); } } else { // TODO: Not supported throw new Exception("PCM Seek not supported"); samples_read = 0;//ead_samples_pcm(musicin, insamp, num_channels * samples_to_read); } return(samples_read); }
internal void id3tag_v2_only(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; gfc.tag_spec.flags &= ~V1_ONLY_FLAG; gfc.tag_spec.flags |= V2_ONLY_FLAG; }
private sound_file_format parse_file_header(LameGlobalFlags gfp, Stream sf) { var type = Read32BitsHighLow(sf); count_samples_carefully = false; pcm_is_unsigned_8bit = !parse.in_signed; if (type == WAV_ID_RIFF) { var ret = parse_wave_header(gfp, sf); if (ret > 0) { count_samples_carefully = true; return(sound_file_format.sf_wave); } } else if (type == IFF_ID_FORM) { var ret = parse_aiff_header(gfp, sf); if (ret > 0) { count_samples_carefully = true; return(sound_file_format.sf_aiff); } } else { } return(sound_file_format.sf_unknown); }
internal void id3tag_space_v1(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; gfc.tag_spec.flags &= ~V2_ONLY_FLAG; gfc.tag_spec.flags |= SPACE_V1_FLAG; }
internal void id3tag_add_v2(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; gfc.tag_spec.flags &= ~V1_ONLY_FLAG; gfc.tag_spec.flags |= ADD_V2_FLAG; }
internal void id3tag_v1_only(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; gfc.tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG); gfc.tag_spec.flags |= V1_ONLY_FLAG; }
private void id3v2AddAudioDuration(LameGlobalFlags gfp) { if (gfp.num_samples != -1) { string buffer; double max_ulong = int.MaxValue; double ms = gfp.num_samples; long playlength_ms; ms *= 1000; ms /= gfp.in_samplerate; if (ms > int.MaxValue) { playlength_ms = (long)max_ulong; } else if (ms < 0) { playlength_ms = 0; } else { playlength_ms = (long)ms; } buffer = string.Format("{0:D}", playlength_ms); copyV1ToV2(gfp, ID_PLAYLENGTH, buffer); } }
internal void id3tag_set_year(LameGlobalFlags gfp, string year) { var gfc = gfp.internal_flags; if (!ReferenceEquals(year, null) && year.Length != 0) { var num = Convert.ToInt32(year); if (num < 0) { num = 0; } if (num > 9999) { num = 9999; } if (num != 0) { gfc.tag_spec.year = num; gfc.tag_spec.flags |= CHANGED_FLAG; } copyV1ToV2(gfp, ID_YEAR, year); } }
internal int id3tag_write_v2(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; if ((gfc.tag_spec.flags & CHANGED_FLAG) != 0 && 0 == (gfc.tag_spec.flags & V1_ONLY_FLAG)) { sbyte[] tag = null; int tag_size, n; n = lame_get_id3v2_tag(gfp, null, 0); tag = new sbyte[n]; tag_size = lame_get_id3v2_tag(gfp, tag, n); if (tag_size > n) { return(-1); } for (var i = 0; i < tag_size; ++i) { bits.add_dummy_byte(gfp, tag[i] & 0xff, 1); } return(tag_size); } return(0); }
internal int id3tag_set_fieldvalue(LameGlobalFlags gfp, string fieldvalue) { var gfc = gfp.internal_flags; if (!ReferenceEquals(fieldvalue, null) && fieldvalue.Length != 0) { var frame_id = toID3v2TagId(fieldvalue); if (fieldvalue.Length < 5 || fieldvalue[4] != '=') { return(-1); } if (frame_id != 0) { if (id3tag_set_textinfo_latin1(gfp, fieldvalue, fieldvalue.Substring(5)) != 0) { gfc.tag_spec.values.Add(fieldvalue); gfc.tag_spec.num_values++; } } gfc.tag_spec.flags |= CHANGED_FLAG; } id3tag_add_v2(gfp); return(0); }
private void copyV1ToV2(LameGlobalFlags gfp, int frame_id, string s) { var gfc = gfp.internal_flags; var flags = gfc.tag_spec.flags; id3v2_add_latin1(gfp, frame_id, null, null, s); gfc.tag_spec.flags = flags; }
private float ATHmdct(LameGlobalFlags gfp, float f) { var ath = psy.ATHformula(f, gfp); ath -= NSATHSCALE; ath = (float)Math.Pow(10.0, ath / 10.0 + gfp.ATHlower); return(ath); }
private Stream OpenSndFile(LameGlobalFlags gfp, Stream mp3Stream, Enc enc) { gfp.num_samples = -1; musicin = mp3Stream; if (is_mpeg_file_format(parse.input_format)) { if (-1 == lame_decode_initfile(musicin, parse.mp3input_data, enc)) { throw new Exception(string.Format("Error reading headers in mp3 input file {0}.", mp3Stream)); } gfp.num_channels = parse.mp3input_data.stereo; gfp.in_samplerate = parse.mp3input_data.samplerate; gfp.num_samples = parse.mp3input_data.nsamp; } else if (parse.input_format == sound_file_format.sf_ogg) { throw new Exception("sorry, vorbis support in LAME is deprecated."); } else if (parse.input_format == sound_file_format.sf_raw) { pcmswapbytes = parse.swapbytes; } else { parse.input_format = parse_file_header(gfp, musicin); } if (parse.input_format == sound_file_format.sf_unknown) { throw new Exception("Unknown sound format!"); } if (gfp.num_samples == -1) { double flen = musicin.Length; if (flen >= 0) { if (is_mpeg_file_format(parse.input_format)) { if (parse.mp3input_data.bitrate > 0) { var totalseconds = flen * 8.0 / (1000.0 * parse.mp3input_data.bitrate); var tmp_num_samples = (int)(totalseconds * gfp.in_samplerate); gfp.num_samples = tmp_num_samples; parse.mp3input_data.nsamp = tmp_num_samples; } } else { gfp.num_samples = (int)(flen / (2 * gfp.num_channels)); } } } return(musicin); }
internal void id3tag_init(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; gfc.tag_spec = new ID3TagSpec(); gfc.tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN; gfc.tag_spec.padding_size = 128; id3v2AddLameVersion(gfp); }
internal void id3tag_set_pad(LameGlobalFlags gfp, int n) { var gfc = gfp.internal_flags; gfc.tag_spec.flags &= ~V1_ONLY_FLAG; gfc.tag_spec.flags |= PAD_V2_FLAG; gfc.tag_spec.flags |= ADD_V2_FLAG; gfc.tag_spec.padding_size = n; }
private bool balance_noise(LameGlobalFlags gfp, GrInfo cod_info, float[] distort, float[] xrpow, bool bRefine) { var gfc = gfp.internal_flags; amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine); var status = loop_break(cod_info); if (status) { return(false); } if (gfc.mode_gr == 2) { status = tk.scale_bitcount(cod_info); } else { status = tk.scale_bitcount_lsf(gfc, cod_info); } if (!status) { return(true); } if (gfc.noise_shaping > 1) { Arrays.Fill(gfc.pseudohalf, 0); if (0 == cod_info.scalefac_scale) { inc_scalefac_scale(cod_info, xrpow); status = false; } else { if (cod_info.block_type == Encoder.SHORT_TYPE && gfc.subblock_gain > 0) { status = inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info); } } } if (!status) { if (gfc.mode_gr == 2) { status = tk.scale_bitcount(cod_info); } else { status = tk.scale_bitcount_lsf(gfc, cod_info); } } return(!status); }
internal void init_infile(LameGlobalFlags gfp, Stream mp3Stream, Enc enc) { count_samples_carefully = false; num_samples_read = 0; pcmbitwidth = parse.in_bitwidth; pcmswapbytes = parse.swapbytes; pcm_is_unsigned_8bit = !parse.in_signed; musicin = OpenSndFile(gfp, mp3Stream, enc); }
/// <summary> /// Add VBR entry, used to fill the VBR TOC entries. /// </summary> /// <param name="gfp"> /// global flags /// </param> internal void addVbrFrame(LameGlobalFlags gfp) { var gfc = gfp.internal_flags; var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; Debug.Assert(gfc.VBR_seek_table.bag != null); addVbr(gfc.VBR_seek_table, kbps); }
internal int id3tag_set_comment(LameGlobalFlags gfp, string lang, string desc, string text, int textPos) { if (gfp != null) { id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text); return(0); } return(-255); }
internal bool id3tag_set_albumart(LameGlobalFlags gfp, byte[] image, int size) { var mimetype = MimeType.MIMETYPE_NONE; var data = image; var gfc = gfp.internal_flags; if (Lame.LAME_MAXALBUMART < size) { return(false); } if (2 < size && data[0] == unchecked ((sbyte)0xFF) && data[1] == unchecked ((sbyte)0xD8)) { mimetype = MimeType.MIMETYPE_JPEG; } else if (4 < size && data[0] == unchecked ((sbyte)0x89) && Encoding.GetEncoding(ASCII).GetString(data, 1, 3).StartsWith("PNG", StringComparison.Ordinal)) { mimetype = MimeType.MIMETYPE_PNG; } else if (4 < size && Encoding.GetEncoding(ASCII).GetString(data, 1, 3).StartsWith( "GIF8", StringComparison.Ordinal)) { mimetype = MimeType.MIMETYPE_GIF; } else { return(false); } if (gfc.tag_spec.albumart != null) { gfc.tag_spec.albumart = null; gfc.tag_spec.albumart_size = 0; gfc.tag_spec.albumart_mimetype = MimeType.MIMETYPE_NONE; } if (size < 1) { return(true); } gfc.tag_spec.albumart = new sbyte[size]; if (gfc.tag_spec.albumart != null) { Array.Copy(image, 0, gfc.tag_spec.albumart, 0, size); gfc.tag_spec.albumart_size = size; gfc.tag_spec.albumart_mimetype = mimetype; gfc.tag_spec.flags |= CHANGED_FLAG; id3tag_add_v2(gfp); } return(true); }
private void lame_encode_frame_init(LameGlobalFlags gfp, float[][] inbuf) { var gfc = gfp.internal_flags; int ch, gr; if (gfc.lame_encode_frame_init == 0) { /* prime the MDCT/polyphase filterbank with a short block */ int i, j; var primebuff0 = new float[286 + 1152 + 576]; var primebuff1 = new float[286 + 1152 + 576]; gfc.lame_encode_frame_init = 1; for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) { if (i < 576 * gfc.mode_gr) { primebuff0[i] = 0; if (gfc.channels_out == 2) { primebuff1[i] = 0; } } else { primebuff0[i] = inbuf[0][j]; if (gfc.channels_out == 2) { primebuff1[i] = inbuf[1][j]; } ++j; } } /* polyphase filtering / mdct */ for (gr = 0; gr < gfc.mode_gr; gr++) { for (ch = 0; ch < gfc.channels_out; ch++) { gfc.l3_side.tt[gr][ch].block_type = SHORT_TYPE; } } newMDCT.mdct_sub48(gfc, primebuff0, primebuff1); /* check FFT will not use a negative starting offset */ Debug.Assert(576 >= FFTOFFSET); /* check if we have enough data for FFT */ Debug.Assert(gfc.mf_size >= BLKSIZE + gfp.framesize - FFTOFFSET); /* check if we have enough data for polyphase filterbank */ Debug.Assert(gfc.mf_size >= 512 + gfp.framesize - 32); } }
internal void id3tag_set_title(LameGlobalFlags gfp, string title) { var gfc = gfp.internal_flags; if (!ReferenceEquals(title, null) && title.Length != 0) { gfc.tag_spec.title = title; gfc.tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_TITLE, title); } }
internal void id3tag_set_artist(LameGlobalFlags gfp, string artist) { var gfc = gfp.internal_flags; if (!ReferenceEquals(artist, null) && artist.Length != 0) { gfc.tag_spec.artist = artist; gfc.tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_ARTIST, artist); } }
internal void id3tag_set_album(LameGlobalFlags gfp, string album) { var gfc = gfp.internal_flags; if (!ReferenceEquals(album, null) && album.Length != 0) { gfc.tag_spec.album = album; gfc.tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_ALBUM, album); } }
internal int lame_get_id3v1_tag(LameGlobalFlags gfp, sbyte[] buffer, int size) { var tag_size = 128; LameInternalFlags gfc; if (gfp == null) { return(0); } if (size < tag_size) { return(tag_size); } gfc = gfp.internal_flags; if (gfc == null) { return(0); } if (buffer == null) { return(0); } if ((gfc.tag_spec.flags & CHANGED_FLAG) != 0 && 0 == (gfc.tag_spec.flags & V2_ONLY_FLAG)) { var p = 0; var pad = (gfc.tag_spec.flags & SPACE_V1_FLAG) != 0 ? ' ' : 0; string year; buffer[p++] = (sbyte)'T'; buffer[p++] = (sbyte)'A'; buffer[p++] = (sbyte)'G'; p = set_text_field(buffer, p, gfc.tag_spec.title, 30, pad); p = set_text_field(buffer, p, gfc.tag_spec.artist, 30, pad); p = set_text_field(buffer, p, gfc.tag_spec.album, 30, pad); year = string.Format("{0:D}", Convert.ToInt32(gfc.tag_spec.year)); p = set_text_field(buffer, p, gfc.tag_spec.year != 0 ? year : null, 4, pad); p = set_text_field(buffer, p, gfc.tag_spec.comment, gfc.tag_spec.track_id3v1 != 0 ? 28 : 30, pad); if (gfc.tag_spec.track_id3v1 != 0) { buffer[p++] = 0; buffer[p++] = (sbyte)gfc.tag_spec.track_id3v1; } buffer[p++] = (sbyte)gfc.tag_spec.genre_id3v1; return(tag_size); } return(0); }
/// <summary> /// Some combinations of bitrate, Fs, and stereo make it impossible to stuff /// out a frame using just main_data, due to the limited number of bits to /// indicate main_data_length. In these situations, we put stuffing bits into /// the ancillary data... /// </summary> private void drain_into_ancillary(LameGlobalFlags gfp, int remainingBits) { var gfc = gfp.internal_flags; int i; Debug.Assert(remainingBits >= 0); if (remainingBits >= 8) { putbits2(gfc, 0x4c, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x41, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x4d, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x45, 8); remainingBits -= 8; } if (remainingBits >= 32) { var version = ver.LameShortVersion; if (remainingBits >= 32) { for (i = 0; i < version.Length && remainingBits >= 8; ++i) { remainingBits -= 8; putbits2(gfc, version[i], 8); } } } for (; remainingBits >= 1; remainingBits -= 1) { putbits2(gfc, gfc.ancillary_flag, 1); gfc.ancillary_flag ^= !gfp.disable_reservoir ? 1 : 0; } Debug.Assert(remainingBits == 0); }