OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); FLAC__ASSERT(0 != encoder->protected_); FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder); if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) return false; return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value); }
static int flac_output_open(const char *fname, const char *comment) { int fd; int nch; FLAC__StreamMetadata padding; FLAC__StreamMetadata *metadata[4]; int num_metadata = 0; #ifndef LEGACY_FLAC FLAC__StreamEncoderInitStatus init_status; #endif FLAC_ctx *ctx; if (flac_ctx == NULL) flac_session_close(); if (!(flac_ctx = (FLAC_ctx *)calloc(sizeof(FLAC_ctx), 1))) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s", strerror(errno)); return -1; } ctx = flac_ctx; ctx->in_bytes = ctx->out_bytes = 0; if(strcmp(fname, "-") == 0) { fd = 1; /* data to stdout */ if (comment == NULL) comment = "(stdout)"; } else { /* Open the audio file */ fd = open(fname, FILE_OUTPUT_MODE); if(fd < 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", fname, strerror(errno)); return -1; } if(comment == NULL) comment = fname; } dpm.fd = fd; nch = (dpm.encoding & PE_MONO) ? 1 : 2; if (0 < flac_options.padding) { padding.is_last = 0; padding.type = FLAC__METADATA_TYPE_PADDING; padding.length = flac_options.padding; metadata[num_metadata++] = &padding; } #ifdef LEGACY_FLAC #ifdef AU_OGGFLAC if (flac_options.isogg) { if ((ctx->encoder.ogg.stream = OggFLAC__stream_encoder_new()) == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create OggFLAC stream"); flac_session_close(); return -1; } OggFLAC__stream_encoder_set_channels(ctx->encoder.ogg.stream, nch); /* 16bps only */ OggFLAC__stream_encoder_set_bits_per_sample(ctx->encoder.ogg.stream, 16); /* set sequential number for serial */ serial_number++; if (serial_number == 1) { srand(time(NULL)); serial_number = rand(); } OggFLAC__stream_encoder_set_serial_number(ctx->encoder.ogg.stream, serial_number); OggFLAC__stream_encoder_set_verify(ctx->encoder.ogg.stream, flac_options.verify); if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); flac_session_close(); return -1; } OggFLAC__stream_encoder_set_sample_rate(ctx->encoder.ogg.stream, dpm.rate); OggFLAC__stream_encoder_set_qlp_coeff_precision(ctx->encoder.ogg.stream, flac_options.qlp_coeff_precision); /* expensive! */ OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.ogg.stream, flac_options.qlp_coeff_precision_search); if (nch == 2) { OggFLAC__stream_encoder_set_do_mid_side_stereo(ctx->encoder.ogg.stream, flac_options.mid_side); OggFLAC__stream_encoder_set_loose_mid_side_stereo(ctx->encoder.ogg.stream, flac_options.adaptive_mid_side); } OggFLAC__stream_encoder_set_max_lpc_order(ctx->encoder.ogg.stream, flac_options.max_lpc_order); OggFLAC__stream_encoder_set_min_residual_partition_order(ctx->encoder.ogg.stream, flac_options.min_residual_partition_order); OggFLAC__stream_encoder_set_max_residual_partition_order(ctx->encoder.ogg.stream, flac_options.max_residual_partition_order); OggFLAC__stream_encoder_set_blocksize(ctx->encoder.ogg.stream, flac_options.blocksize); OggFLAC__stream_encoder_set_client_data(ctx->encoder.ogg.stream, ctx); if (0 < num_metadata) OggFLAC__stream_encoder_set_metadata(ctx->encoder.ogg.stream, metadata, num_metadata); /* set callback */ OggFLAC__stream_encoder_set_write_callback(ctx->encoder.ogg.stream, ogg_stream_encoder_write_callback); ctx->state.ogg = OggFLAC__stream_encoder_init(ctx->encoder.ogg.stream); if (ctx->state.ogg != OggFLAC__STREAM_ENCODER_OK) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create OggFLAC state (%s)", OggFLAC__StreamEncoderStateString[ctx->state.ogg]); flac_session_close(); return -1; } } else #endif /* AU_OGGFLAC */ if (flac_options.seekable) { if ((ctx->encoder.flac.s_stream = FLAC__seekable_stream_encoder_new()) == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC stream"); flac_session_close(); return -1; } FLAC__seekable_stream_encoder_set_channels(ctx->encoder.flac.s_stream, nch); /* 16bps only */ FLAC__seekable_stream_encoder_set_bits_per_sample(ctx->encoder.flac.s_stream, 16); FLAC__seekable_stream_encoder_set_verify(ctx->encoder.flac.s_stream, flac_options.verify); if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); flac_session_close(); return -1; } FLAC__seekable_stream_encoder_set_sample_rate(ctx->encoder.flac.s_stream, dpm.rate); FLAC__seekable_stream_encoder_set_qlp_coeff_precision(ctx->encoder.flac.s_stream, flac_options.qlp_coeff_precision); /* expensive! */ FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.flac.s_stream, flac_options.qlp_coeff_precision_search); if (nch == 2) { FLAC__seekable_stream_encoder_set_do_mid_side_stereo(ctx->encoder.flac.s_stream, flac_options.mid_side); FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(ctx->encoder.flac.s_stream, flac_options.adaptive_mid_side); } FLAC__seekable_stream_encoder_set_max_lpc_order(ctx->encoder.flac.s_stream, flac_options.max_lpc_order); FLAC__seekable_stream_encoder_set_min_residual_partition_order(ctx->encoder.flac.s_stream, flac_options.min_residual_partition_order); FLAC__seekable_stream_encoder_set_max_residual_partition_order(ctx->encoder.flac.s_stream, flac_options.max_residual_partition_order); FLAC__seekable_stream_encoder_set_blocksize(ctx->encoder.flac.s_stream, flac_options.blocksize); FLAC__seekable_stream_encoder_set_client_data(ctx->encoder.flac.s_stream, ctx); if (0 < num_metadata) FLAC__seekable_stream_encoder_set_metadata(ctx->encoder.flac.s_stream, metadata, num_metadata); /* set callback */ /* FLAC__seekable_stream_encoder_set_metadata_callback(ctx->encoder.flac.s_stream, flac_seekable_stream_encoder_metadata_callback); /* */ #if (!defined(__BORLANDC__) && !defined(__POCC__)) FLAC__stream_encoder_set_metadata_callback(ctx->encoder.flac.s_stream, flac_seekable_stream_encoder_metadata_callback); /* */ #endif FLAC__seekable_stream_encoder_set_write_callback(ctx->encoder.flac.s_stream, flac_seekable_stream_encoder_write_callback); ctx->state.s_flac = FLAC__seekable_stream_encoder_init(ctx->encoder.flac.s_stream); if (ctx->state.s_flac != FLAC__SEEKABLE_STREAM_ENCODER_OK) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC state (%s)", FLAC__SeekableStreamEncoderStateString[ctx->state.s_flac]); flac_session_close(); return -1; } } else { if ((ctx->encoder.flac.stream = FLAC__stream_encoder_new()) == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC stream"); flac_session_close(); return -1; } FLAC__stream_encoder_set_channels(ctx->encoder.flac.stream, nch); /* 16bps only */ FLAC__stream_encoder_set_bits_per_sample(ctx->encoder.flac.stream, 16); FLAC__stream_encoder_set_verify(ctx->encoder.flac.stream, flac_options.verify); if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); flac_session_close(); return -1; } FLAC__stream_encoder_set_sample_rate(ctx->encoder.flac.stream, dpm.rate); FLAC__stream_encoder_set_qlp_coeff_precision(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision); /* expensive! */ FLAC__stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision_search); if (nch == 2) { FLAC__stream_encoder_set_do_mid_side_stereo(ctx->encoder.flac.stream, flac_options.mid_side); FLAC__stream_encoder_set_loose_mid_side_stereo(ctx->encoder.flac.stream, flac_options.adaptive_mid_side); } FLAC__stream_encoder_set_max_lpc_order(ctx->encoder.flac.stream, flac_options.max_lpc_order); FLAC__stream_encoder_set_min_residual_partition_order(ctx->encoder.flac.stream, flac_options.min_residual_partition_order); FLAC__stream_encoder_set_max_residual_partition_order(ctx->encoder.flac.stream, flac_options.max_residual_partition_order); FLAC__stream_encoder_set_blocksize(ctx->encoder.flac.stream, flac_options.blocksize); FLAC__stream_encoder_set_client_data(ctx->encoder.flac.stream, ctx); if (0 < num_metadata) FLAC__stream_encoder_set_metadata(ctx->encoder.flac.stream, metadata, num_metadata); /* set callback */ FLAC__stream_encoder_set_metadata_callback(ctx->encoder.flac.stream, flac_stream_encoder_metadata_callback); FLAC__stream_encoder_set_write_callback(ctx->encoder.flac.stream, flac_stream_encoder_write_callback); ctx->state.flac = FLAC__stream_encoder_init(ctx->encoder.flac.stream); if (ctx->state.flac != FLAC__STREAM_ENCODER_OK) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC state (%s)", FLAC__StreamEncoderStateString[ctx->state.flac]); flac_session_close(); return -1; } } #else /* !LEGACY_FLAC */ if ((ctx->encoder.flac.stream = FLAC__stream_encoder_new()) == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC stream"); flac_session_close(); return -1; } #ifdef AU_OGGFLAC if (flac_options.isogg) { /* set sequential number for serial */ serial_number++; if (serial_number == 1) { srand(time(NULL)); serial_number = rand(); } FLAC__stream_encoder_set_ogg_serial_number(ctx->encoder.flac.stream, serial_number); } #endif /* AU_OGGFLAC */ FLAC__stream_encoder_set_channels(ctx->encoder.flac.stream, nch); /* 16bps only */ FLAC__stream_encoder_set_bits_per_sample(ctx->encoder.flac.stream, 16); FLAC__stream_encoder_set_verify(ctx->encoder.flac.stream, flac_options.verify); if (!FLAC__format_sample_rate_is_valid(dpm.rate)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "invalid sampling rate %d", dpm.rate); flac_session_close(); return -1; } FLAC__stream_encoder_set_sample_rate(ctx->encoder.flac.stream, dpm.rate); FLAC__stream_encoder_set_qlp_coeff_precision(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision); /* expensive! */ FLAC__stream_encoder_set_do_qlp_coeff_prec_search(ctx->encoder.flac.stream, flac_options.qlp_coeff_precision_search); if (nch == 2) { FLAC__stream_encoder_set_do_mid_side_stereo(ctx->encoder.flac.stream, flac_options.mid_side); FLAC__stream_encoder_set_loose_mid_side_stereo(ctx->encoder.flac.stream, flac_options.adaptive_mid_side); } FLAC__stream_encoder_set_max_lpc_order(ctx->encoder.flac.stream, flac_options.max_lpc_order); FLAC__stream_encoder_set_min_residual_partition_order(ctx->encoder.flac.stream, flac_options.min_residual_partition_order); FLAC__stream_encoder_set_max_residual_partition_order(ctx->encoder.flac.stream, flac_options.max_residual_partition_order); FLAC__stream_encoder_set_blocksize(ctx->encoder.flac.stream, flac_options.blocksize); if (0 < num_metadata) FLAC__stream_encoder_set_metadata(ctx->encoder.flac.stream, metadata, num_metadata); #ifdef AU_OGGFLAC if (flac_options.isogg) init_status = FLAC__stream_encoder_init_ogg_stream(ctx->encoder.flac.stream, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); else #endif init_status = FLAC__stream_encoder_init_stream(ctx->encoder.flac.stream, flac_stream_encoder_write_callback, NULL, NULL, NULL, ctx); if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot create FLAC encoder (init status: %s)", FLAC__StreamEncoderInitStatusString[init_status]); flac_session_close(); return -1; } #endif return 0; }
QString & SampleBuffer::toBase64( QString & _dst ) const { #ifdef LMMS_HAVE_FLAC_STREAM_ENCODER_H const f_cnt_t FRAMES_PER_BUF = 1152; FLAC__StreamEncoder * flac_enc = FLAC__stream_encoder_new(); FLAC__stream_encoder_set_channels( flac_enc, DEFAULT_CHANNELS ); FLAC__stream_encoder_set_blocksize( flac_enc, FRAMES_PER_BUF ); /* FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, true ); FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, true );*/ FLAC__stream_encoder_set_sample_rate( flac_enc, engine::mixer()->sampleRate() ); QBuffer ba_writer; ba_writer.open( QBuffer::WriteOnly ); FLAC__stream_encoder_set_write_callback( flac_enc, flacStreamEncoderWriteCallback ); FLAC__stream_encoder_set_metadata_callback( flac_enc, flacStreamEncoderMetadataCallback ); FLAC__stream_encoder_set_client_data( flac_enc, &ba_writer ); if( FLAC__stream_encoder_init( flac_enc ) != FLAC__STREAM_ENCODER_OK ) { printf( "error within FLAC__stream_encoder_init()!\n" ); } f_cnt_t frame_cnt = 0; while( frame_cnt < m_frames ) { f_cnt_t remaining = qMin<f_cnt_t>( FRAMES_PER_BUF, m_frames - frame_cnt ); FLAC__int32 buf[FRAMES_PER_BUF * DEFAULT_CHANNELS]; for( f_cnt_t f = 0; f < remaining; ++f ) { for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) { buf[f*DEFAULT_CHANNELS+ch] = (FLAC__int32)( Mixer::clip( m_data[f+frame_cnt][ch] ) * OUTPUT_SAMPLE_MULTIPLIER ); } } FLAC__stream_encoder_process_interleaved( flac_enc, buf, remaining ); frame_cnt += remaining; } FLAC__stream_encoder_finish( flac_enc ); FLAC__stream_encoder_delete( flac_enc ); printf("%d %d\n", frame_cnt, (int)ba_writer.size() ); ba_writer.close(); base64::encode( ba_writer.buffer().data(), ba_writer.buffer().size(), _dst ); #else /* LMMS_HAVE_FLAC_STREAM_ENCODER_H */ base64::encode( (const char *) m_data, m_frames * sizeof( sampleFrame ), _dst ); #endif /* LMMS_HAVE_FLAC_STREAM_ENCODER_H */ return _dst; }
FLAC__bool file_utils__generate_flacfile(FLAC__bool is_ogg, const char *output_filename, off_t *output_filesize, unsigned length, const FLAC__StreamMetadata *streaminfo, FLAC__StreamMetadata **metadata, unsigned num_metadata) { FLAC__int32 samples[1024]; FLAC__StreamEncoder *encoder; FLAC__StreamEncoderInitStatus init_status; encoder_client_struct encoder_client_data; unsigned i, n; FLAC__ASSERT(0 != output_filename); FLAC__ASSERT(0 != streaminfo); FLAC__ASSERT(streaminfo->type == FLAC__METADATA_TYPE_STREAMINFO); FLAC__ASSERT((streaminfo->is_last && num_metadata == 0) || (!streaminfo->is_last && num_metadata > 0)); if(0 == (encoder_client_data.file = fopen(output_filename, "wb"))) return false; encoder = FLAC__stream_encoder_new(); if(0 == encoder) { fclose(encoder_client_data.file); return false; } FLAC__stream_encoder_set_ogg_serial_number(encoder, file_utils__ogg_serial_number); FLAC__stream_encoder_set_verify(encoder, true); FLAC__stream_encoder_set_streamable_subset(encoder, true); FLAC__stream_encoder_set_do_mid_side_stereo(encoder, false); FLAC__stream_encoder_set_loose_mid_side_stereo(encoder, false); FLAC__stream_encoder_set_channels(encoder, streaminfo->data.stream_info.channels); FLAC__stream_encoder_set_bits_per_sample(encoder, streaminfo->data.stream_info.bits_per_sample); FLAC__stream_encoder_set_sample_rate(encoder, streaminfo->data.stream_info.sample_rate); FLAC__stream_encoder_set_blocksize(encoder, streaminfo->data.stream_info.min_blocksize); FLAC__stream_encoder_set_max_lpc_order(encoder, 0); FLAC__stream_encoder_set_qlp_coeff_precision(encoder, 0); FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder, false); FLAC__stream_encoder_set_do_escape_coding(encoder, false); FLAC__stream_encoder_set_do_exhaustive_model_search(encoder, false); FLAC__stream_encoder_set_min_residual_partition_order(encoder, 0); FLAC__stream_encoder_set_max_residual_partition_order(encoder, 0); FLAC__stream_encoder_set_rice_parameter_search_dist(encoder, 0); FLAC__stream_encoder_set_total_samples_estimate(encoder, streaminfo->data.stream_info.total_samples); FLAC__stream_encoder_set_metadata(encoder, metadata, num_metadata); if(is_ogg) init_status = FLAC__stream_encoder_init_ogg_stream(encoder, /*read_callback=*/0, encoder_write_callback_, /*seek_callback=*/0, /*tell_callback=*/0, encoder_metadata_callback_, &encoder_client_data); else init_status = FLAC__stream_encoder_init_stream(encoder, encoder_write_callback_, /*seek_callback=*/0, /*tell_callback=*/0, encoder_metadata_callback_, &encoder_client_data); if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { fclose(encoder_client_data.file); return false; } /* init the dummy sample buffer */ for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++) samples[i] = i & 7; while(length > 0) { n = min(length, sizeof(samples) / sizeof(FLAC__int32)); if(!FLAC__stream_encoder_process_interleaved(encoder, samples, n)) { fclose(encoder_client_data.file); return false; } length -= n; } (void)FLAC__stream_encoder_finish(encoder); fclose(encoder_client_data.file); FLAC__stream_encoder_delete(encoder); if(0 != output_filesize) { struct stat filestats; if(stat(output_filename, &filestats) != 0) return false; else *output_filesize = filestats.st_size; } return true; }
void CompressionTool::encodeRaw(const char *rawData, int length, int samplerate, const char *outname, AudioFormat compmode) { print(" - len=%ld, ch=%d, rate=%d, %dbits", length, (rawAudioType.isStereo ? 2 : 1), samplerate, rawAudioType.bitsPerSample); #ifdef USE_VORBIS if (compmode == AUDIO_VORBIS) { char outputString[256] = ""; int numChannels = (rawAudioType.isStereo ? 2 : 1); int totalSamples = length / ((rawAudioType.bitsPerSample / 8) * numChannels); int samplesLeft = totalSamples; int eos = 0; int totalBytes = 0; vorbis_info vi; vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; ogg_stream_state os; ogg_page og; ogg_packet op; ogg_packet header; ogg_packet header_comm; ogg_packet header_code; Common::File outputOgg(outname, "wb"); vorbis_info_init(&vi); if (oggparms.nominalBitr > 0) { int result = 0; /* Input is in kbps, function takes bps */ result = vorbis_encode_setup_managed(&vi, numChannels, samplerate, (oggparms.maxBitr > 0 ? 1000 * oggparms.maxBitr : -1), (1000 * oggparms.nominalBitr), (oggparms.minBitr > 0 ? 1000 * oggparms.minBitr : -1)); if (result == OV_EFAULT) { vorbis_info_clear(&vi); error("Error: Internal Logic Fault"); } else if ((result == OV_EINVAL) || (result == OV_EIMPL)) { vorbis_info_clear(&vi); error("Error: Invalid bitrate parameters"); } if (!oggparms.silent) { sprintf(outputString, "Encoding to\n \"%s\"\nat average bitrate %i kbps (", outname, oggparms.nominalBitr); if (oggparms.minBitr > 0) { sprintf(outputString + strlen(outputString), "min %i kbps, ", oggparms.minBitr); } else { sprintf(outputString + strlen(outputString), "no min, "); } if (oggparms.maxBitr > 0) { sprintf(outputString + strlen(outputString), "max %i kbps),\nusing full bitrate management engine\nSet optional hard quality restrictions\n", oggparms.maxBitr); } else { sprintf(outputString + strlen(outputString), "no max),\nusing full bitrate management engine\nSet optional hard quality restrictions\n"); } } } else { int result = 0; /* Quality input is -1 - 10, function takes -0.1 through 1.0 */ result = vorbis_encode_setup_vbr(&vi, numChannels, samplerate, oggparms.quality * 0.1f); if (result == OV_EFAULT) { vorbis_info_clear(&vi); error("Internal Logic Fault"); } else if ((result == OV_EINVAL) || (result == OV_EIMPL)) { vorbis_info_clear(&vi); error("Invalid bitrate parameters"); } if (!oggparms.silent) { sprintf(outputString, "Encoding to\n \"%s\"\nat quality %2.2f", outname, oggparms.quality); } if ((oggparms.minBitr > 0) || (oggparms.maxBitr > 0)) { struct ovectl_ratemanage_arg extraParam; vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_GET, &extraParam); extraParam.bitrate_hard_min = (oggparms.minBitr > 0 ? (1000 * oggparms.minBitr) : -1); extraParam.bitrate_hard_max = (oggparms.maxBitr > 0 ? (1000 * oggparms.maxBitr) : -1); extraParam.management_active = 1; vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_SET, &extraParam); if (!oggparms.silent) { sprintf(outputString + strlen(outputString), " using constrained VBR ("); if (oggparms.minBitr != -1) { sprintf(outputString + strlen(outputString), "min %i kbps, ", oggparms.minBitr); } else { sprintf(outputString + strlen(outputString), "no min, "); } if (oggparms.maxBitr != -1) { sprintf(outputString + strlen(outputString), "max %i kbps)\nSet optional hard quality restrictions\n", oggparms.maxBitr); } else { sprintf(outputString + strlen(outputString), "no max)\nSet optional hard quality restrictions\n"); } } } else { sprintf(outputString + strlen(outputString), "\n"); } } puts(outputString); vorbis_encode_setup_init(&vi); vorbis_comment_init(&vc); vorbis_analysis_init(&vd, &vi); vorbis_block_init(&vd, &vb); ogg_stream_init(&os, 0); vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code); ogg_stream_packetin(&os, &header); ogg_stream_packetin(&os, &header_comm); ogg_stream_packetin(&os, &header_code); while (!eos) { int result = ogg_stream_flush(&os,&og); if (result == 0) { break; } outputOgg.write(og.header, og.header_len); outputOgg.write(og.body, og.body_len); } while (!eos) { int numSamples = ((samplesLeft < 2048) ? samplesLeft : 2048); float **buffer = vorbis_analysis_buffer(&vd, numSamples); /* We must tell the encoder that we have reached the end of the stream */ if (numSamples == 0) { vorbis_analysis_wrote(&vd, 0); } else { /* Adapted from oggenc 1.1.1 */ if (rawAudioType.bitsPerSample == 8) { const byte *rawDataUnsigned = (const byte *)rawData; for (int i = 0; i < numSamples; i++) { for (int j = 0; j < numChannels; j++) { buffer[j][i] = ((int)(rawDataUnsigned[i * numChannels + j]) - 128) / 128.0f; } } } else if (rawAudioType.bitsPerSample == 16) { if (rawAudioType.isLittleEndian) { for (int i = 0; i < numSamples; i++) { for (int j = 0; j < numChannels; j++) { buffer[j][i] = ((rawData[(i * 2 * numChannels) + (2 * j) + 1] << 8) | (rawData[(i * 2 * numChannels) + (2 * j)] & 0xff)) / 32768.0f; } } } else { for (int i = 0; i < numSamples; i++) { for (int j = 0; j < numChannels; j++) { buffer[j][i] = ((rawData[(i * 2 * numChannels) + (2 * j)] << 8) | (rawData[(i * 2 * numChannels) + (2 * j) + 1] & 0xff)) / 32768.0f; } } } } vorbis_analysis_wrote(&vd, numSamples); } while (vorbis_analysis_blockout(&vd, &vb) == 1) { vorbis_analysis(&vb, NULL); vorbis_bitrate_addblock(&vb); while (vorbis_bitrate_flushpacket(&vd, &op)) { ogg_stream_packetin(&os, &op); while (!eos) { int result = ogg_stream_pageout(&os, &og); if (result == 0) { break; } totalBytes += outputOgg.write(og.header, og.header_len); totalBytes += outputOgg.write(og.body, og.body_len); if (ogg_page_eos(&og)) { eos = 1; } } } } rawData += 2048 * (rawAudioType.bitsPerSample / 8) * numChannels; samplesLeft -= 2048; } ogg_stream_clear(&os); vorbis_block_clear(&vb); vorbis_dsp_clear(&vd); vorbis_info_clear(&vi); if (!oggparms.silent) { print("\nDone encoding file \"%s\"", outname); print("\n\tFile length: %dm %ds", (int)(totalSamples / samplerate / 60), (totalSamples / samplerate % 60)); print("\tAverage bitrate: %.1f kb/s\n", (8.0 * (double)totalBytes / 1000.0) / ((double)totalSamples / (double)samplerate)); } } #endif #ifdef USE_FLAC if (compmode == AUDIO_FLAC) { int i; int numChannels = (rawAudioType.isStereo ? 2 : 1); int samplesPerChannel = length / ((rawAudioType.bitsPerSample / 8) * numChannels); FLAC__StreamEncoder *encoder; FLAC__StreamEncoderInitStatus initStatus; FLAC__int32 *flacData; flacData = (FLAC__int32 *)malloc(samplesPerChannel * numChannels * sizeof(FLAC__int32)); if (rawAudioType.bitsPerSample == 8) { for (i = 0; i < samplesPerChannel * numChannels; i++) { FLAC__uint8 *rawDataUnsigned; rawDataUnsigned = (FLAC__uint8 *)rawData; flacData[i] = (FLAC__int32)rawDataUnsigned[i] - 0x80; } } else if (rawAudioType.bitsPerSample == 16) { /* The rawData pointer is an 8-bit char so we must create a new pointer to access 16-bit samples */ FLAC__int16 *rawData16; rawData16 = (FLAC__int16 *)rawData; for (i = 0; i < samplesPerChannel * numChannels; i++) { flacData[i] = (FLAC__int32)rawData16[i]; } } if (!flacparms.silent) { print("Encoding to\n \"%s\"\nat compression level %d using blocksize %d\n", outname, flacparms.compressionLevel, flacparms.blocksize); } encoder = FLAC__stream_encoder_new(); FLAC__stream_encoder_set_bits_per_sample(encoder, rawAudioType.bitsPerSample); FLAC__stream_encoder_set_blocksize(encoder, flacparms.blocksize); FLAC__stream_encoder_set_channels(encoder, numChannels); FLAC__stream_encoder_set_compression_level(encoder, flacparms.compressionLevel); FLAC__stream_encoder_set_sample_rate(encoder, samplerate); FLAC__stream_encoder_set_streamable_subset(encoder, false); FLAC__stream_encoder_set_total_samples_estimate(encoder, samplesPerChannel); FLAC__stream_encoder_set_verify(encoder, flacparms.verify); initStatus = FLAC__stream_encoder_init_file(encoder, outname, NULL, NULL); if (initStatus != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { char buf[2048]; sprintf(buf, "Error in FLAC encoder. (check the parameters)\nExact error was:%s", FLAC__StreamEncoderInitStatusString[initStatus]); free(flacData); throw ToolException(buf); } else { FLAC__stream_encoder_process_interleaved(encoder, flacData, samplesPerChannel); } FLAC__stream_encoder_finish(encoder); FLAC__stream_encoder_delete(encoder); free(flacData); if (!flacparms.silent) { print("\nDone encoding file \"%s\"", outname); print("\n\tFile length: %dm %ds\n", (int)(samplesPerChannel / samplerate / 60), (samplesPerChannel / samplerate % 60)); } } #endif }