Пример #1
0
bool SoundFileWriterFlac::open(const std::string& filename, unsigned int sampleRate, unsigned int channelCount)
{
    // Create the encoder
    m_encoder = FLAC__stream_encoder_new();
    if (!m_encoder)
    {
        err() << "Failed to write flac file \"" << filename << "\" (failed to allocate encoder)" << std::endl;
        return false;
    }

    // Setup the encoder
    FLAC__stream_encoder_set_channels(m_encoder, channelCount);
    FLAC__stream_encoder_set_bits_per_sample(m_encoder, 16);
    FLAC__stream_encoder_set_sample_rate(m_encoder, sampleRate);

    // Initialize the output stream
    if (FLAC__stream_encoder_init_file(m_encoder, filename.c_str(), NULL, NULL) != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
    {
        err() << "Failed to write flac file \"" << filename << "\" (failed to open the file)" << std::endl;
        close();
        return false;
    }

    // Store the channel count
    m_channelCount = channelCount;

    return true;
}
Пример #2
0
	virtual void SetFormat(const Encoder::Settings &settings)
	{
		FinishStream();

		ASSERT(!inited && !started);

		formatInfo = enc.GetTraits().formats[settings.Format];
		ASSERT(formatInfo.Sampleformat.IsValid());
		ASSERT(formatInfo.Samplerate > 0);
		ASSERT(formatInfo.Channels > 0);

		writeTags = settings.Tags;

		encoder = FLAC__stream_encoder_new();

		FLAC__stream_encoder_set_channels(encoder, formatInfo.Channels);
		FLAC__stream_encoder_set_bits_per_sample(encoder, formatInfo.Sampleformat.GetBitsPerSample());
		FLAC__stream_encoder_set_sample_rate(encoder, formatInfo.Samplerate);

		int compressionLevel = StreamEncoderSettings::Instance().FLACCompressionLevel;
		FLAC__stream_encoder_set_compression_level(encoder, compressionLevel);
		
		inited = true;

		ASSERT(inited && !started);
	}
Пример #3
0
static gint flac_open(void)
{
    flac_encoder = FLAC__stream_encoder_new();

    FLAC__stream_encoder_set_channels(flac_encoder, input.channels);
    FLAC__stream_encoder_set_sample_rate(flac_encoder, input.frequency);
    FLAC__stream_encoder_init_stream(flac_encoder, flac_write_cb, flac_seek_cb, flac_tell_cb,
				     NULL, output_file);

    if (tuple)
    {
        FLAC__StreamMetadata *meta;
        meta = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);

        insert_vorbis_comment (meta, "title", tuple, FIELD_TITLE);
        insert_vorbis_comment (meta, "artist", tuple, FIELD_ARTIST);
        insert_vorbis_comment (meta, "album", tuple, FIELD_ALBUM);
        insert_vorbis_comment (meta, "genre", tuple, FIELD_GENRE);
        insert_vorbis_comment (meta, "comment", tuple, FIELD_COMMENT);
        insert_vorbis_comment (meta, "date", tuple, FIELD_DATE);
        insert_vorbis_comment (meta, "year", tuple, FIELD_YEAR);
        insert_vorbis_comment (meta, "tracknumber", tuple, FIELD_TRACK_NUMBER);

        FLAC__stream_encoder_set_metadata(flac_encoder, &meta, 1);
    }

    return 1;
}
Пример #4
0
CEncoderFlac::CEncoderFlac(KODI_HANDLE instance)
  : CInstanceAudioEncoder(instance),
    m_tellPos(0)
{
  m_metadata[0] = nullptr;
  m_metadata[1] = nullptr;

  m_encoder = FLAC__stream_encoder_new();
  if (m_encoder == nullptr)
    kodi::Log(ADDON_LOG_ERROR, "Failed to construct flac stream encoder");
}
Пример #5
0
void FlacAudioEncoder::setup(AudioEncoderProfile::SharedPtr profile, AudioMetaData::SharedPtr metadata, uint32_t data_size)
{
   _profile = profile;

   // allocate the encoder 
   _encoder = FLAC__stream_encoder_new();

   if (_encoder == nullptr) 
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: allocating encoder");
      return;
   }

   if (not FLAC__stream_encoder_set_channels(_encoder, profile->channels()))
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: could not set channel count");
      return;
   }

   if (not FLAC__stream_encoder_set_sample_rate(_encoder, profile->sample_rate()))
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: could not set sample rate");
      return;
   }

   if (not FLAC__stream_encoder_set_bits_per_sample(_encoder, profile->bits_per_sample()))
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: could not set sample width");
      return;
   }

   if (not FLAC__stream_encoder_set_compression_level(_encoder, profile->quality_level()))
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: could not set compression level");
      return;
   }

   FLAC__stream_encoder_set_verify(_encoder, true);
   //FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples);

   set_tags(metadata);

   FLAC__StreamEncoderInitStatus init_status = FLAC__stream_encoder_init_stream(_encoder,
                                                                                write_callback,
                                                                                seek_callback,
                                                                                tell_callback,
                                                                                nullptr,
		                                                                this);
   if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) 
   {
      THROW_EXCEPTION(AudioEncoderException, "ERROR: could not initialize FLAC encoder");
   }

}
Пример #6
0
void* Create(audioenc_callbacks *callbacks)
{
  if (callbacks && callbacks->write && callbacks->seek)
  {
    // allocate libFLAC encoder
    FLAC__StreamEncoder *encoder = FLAC__stream_encoder_new();
    if (!encoder)
      return NULL;

    return new flac_context(encoder, *callbacks);
  }
  return NULL;
}
Пример #7
0
int flac_enc_init(flac_enc *flac)
{
    FLAC__bool ok = true;
   
    if((flac->encoder = FLAC__stream_encoder_new()) == NULL) 
    {
        printf("%s", _("ERROR: allocating encoder\n"));
        return 1;
    }


    ok &= FLAC__stream_encoder_set_verify(flac->encoder, false);
    ok &= FLAC__stream_encoder_set_compression_level(flac->encoder, 5);
    ok &= FLAC__stream_encoder_set_channels(flac->encoder, flac->channel);
    ok &= FLAC__stream_encoder_set_bits_per_sample(flac->encoder, 16);
    ok &= FLAC__stream_encoder_set_sample_rate(flac->encoder, flac->samplerate);
    ok &= FLAC__stream_encoder_set_total_samples_estimate(flac->encoder, 0);

    return ok == true ? 0 : 1;
}
Пример #8
0
static bool DecodeFLAC(FILE *f, FILE *of)
{
	fseek(f, 0, SEEK_SET);
	FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
	if(decoder == nullptr)
	{
		return false;
	}

	FLAC__stream_decoder_set_metadata_respond_all(decoder);

	FLACClientData client;
	client.of = of;
	client.started = false;
	client.encoder = FLAC__stream_encoder_new();

	FLAC__StreamDecoderInitStatus initStatus = FLAC__stream_decoder_init_FILE(decoder, f, write_cb, metadata_cb, error_cb, &client);

	if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK || client.encoder == nullptr)
	{
		FLAC__stream_decoder_delete(decoder);
		return false;
	}

	FLAC__stream_decoder_process_until_end_of_stream(decoder);
	FLAC__stream_decoder_finish(decoder);
	FLAC__stream_decoder_delete(decoder);
	FLAC__stream_encoder_finish(client.encoder);
	FLAC__stream_encoder_delete(client.encoder);

	for(auto m = client.metadata.begin(); m != client.metadata.end(); m++)
	{
		FLAC__metadata_object_delete(*m);
	}

	return client.started;
}
SoftFlacEncoder::SoftFlacEncoder(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component)
    : SimpleSoftOMXComponent(name, callbacks, appData, component),
      mSignalledError(false),
      mNumChannels(1),
      mSampleRate(44100),
      mCompressionLevel(FLAC_COMPRESSION_LEVEL_DEFAULT),
      mEncoderWriteData(false),
      mEncoderReturnedEncodedData(false),
      mEncoderReturnedNbBytes(0),
      mInputBufferPcm32(NULL)
#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
      , mHeaderOffset(0)
      , mWroteHeader(false)
#endif
{
    ALOGV("SoftFlacEncoder::SoftFlacEncoder(name=%s)", name);
    initPorts();

    mFlacStreamEncoder = FLAC__stream_encoder_new();
    if (mFlacStreamEncoder == NULL) {
        ALOGE("SoftFlacEncoder::SoftFlacEncoder(name=%s) error instantiating FLAC encoder", name);
        mSignalledError = true;
    }

    if (!mSignalledError) { // no use allocating input buffer if we had an error above
        mInputBufferPcm32 = (FLAC__int32*) malloc(sizeof(FLAC__int32) * 2 * kMaxNumSamplesPerFrame);
        if (mInputBufferPcm32 == NULL) {
            ALOGE("SoftFlacEncoder::SoftFlacEncoder(name=%s) error allocating internal input buffer", name);
            mSignalledError = true;
        }
    }
}
Пример #10
0
/***********************************************************************
 *
 * Class constructor/destructor
 *
 */
OggFLAC_API OggFLAC__SeekableStreamEncoder *OggFLAC__seekable_stream_encoder_new()
{
	OggFLAC__SeekableStreamEncoder *encoder;

	encoder = (OggFLAC__SeekableStreamEncoder*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoder));
	if(encoder == 0) {
		return 0;
	}

	encoder->protected_ = (OggFLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderProtected));
	if(encoder->protected_ == 0) {
		free(encoder);
		return 0;
	}

	encoder->private_ = (OggFLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderPrivate));
	if(encoder->private_ == 0) {
		free(encoder->protected_);
		free(encoder);
		return 0;
	}

	encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
	if(0 == encoder->private_->FLAC_stream_encoder) {
		free(encoder->private_);
		free(encoder->protected_);
		free(encoder);
		return 0;
	}

	set_defaults_(encoder);

	encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;

	return encoder;
}
Пример #11
0
Файл: main.c Проект: kode54/flac
int main(int argc, char *argv[])
{
	FLAC__bool ok = true;
	FLAC__StreamEncoder *encoder = 0;
	FLAC__StreamEncoderInitStatus init_status;
	FLAC__StreamMetadata *metadata[2];
	FLAC__StreamMetadata_VorbisComment_Entry entry;
	FILE *fin;
	unsigned sample_rate = 0;
	unsigned channels = 0;
	unsigned bps = 0;

	if(argc != 3) {
		fprintf(stderr, "usage: %s infile.wav outfile.flac\n", argv[0]);
		return 1;
	}

	if((fin = fopen(argv[1], "rb")) == NULL) {
		fprintf(stderr, "ERROR: opening %s for output\n", argv[1]);
		return 1;
	}

	/* read wav header and validate it */
	if(
		fread(buffer, 1, 44, fin) != 44 ||
		memcmp(buffer, "RIFF", 4) ||
		memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) ||
		memcmp(buffer+32, "\004\000\020\000data", 8)
	) {
		fprintf(stderr, "ERROR: invalid/unsupported WAVE file, only 16bps stereo WAVE in canonical form allowed\n");
		fclose(fin);
		return 1;
	}
	sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) | buffer[25]) << 8) | buffer[24];
	channels = 2;
	bps = 16;
	total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8) | buffer[41]) << 8) | buffer[40]) / 4;

	/* allocate the encoder */
	if((encoder = FLAC__stream_encoder_new()) == NULL) {
		fprintf(stderr, "ERROR: allocating encoder\n");
		fclose(fin);
		return 1;
	}

	ok &= FLAC__stream_encoder_set_verify(encoder, true);
	ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
	ok &= FLAC__stream_encoder_set_channels(encoder, channels);
	ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
	ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
	ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples);

	/* now add some metadata; we'll add some tags and a padding block */
	if(ok) {
		if(
			(metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL ||
			(metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL ||
			/* there are many tag (vorbiscomment) functions but these are convenient for this particular use: */
			!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ARTIST", "Some Artist") ||
			!FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) || /* copy=false: let metadata object take control of entry's allocated string */
			!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "YEAR", "1984") ||
			!FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false)
		) {
			fprintf(stderr, "ERROR: out of memory or tag error\n");
			ok = false;
		}

		metadata[1]->length = 1234; /* set the padding length */

		ok = FLAC__stream_encoder_set_metadata(encoder, metadata, 2);
	}

	/* initialize encoder */
	if(ok) {
		init_status = FLAC__stream_encoder_init_file(encoder, argv[2], progress_callback, /*client_data=*/NULL);
		if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
			fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]);
			ok = false;
		}
	}

	/* read blocks of samples from WAVE file and feed to encoder */
	if(ok) {
		size_t left = (size_t)total_samples;
		while(ok && left) {
			size_t need = (left>READSIZE? (size_t)READSIZE : (size_t)left);
			if(fread(buffer, channels*(bps/8), need, fin) != need) {
				fprintf(stderr, "ERROR: reading from WAVE file\n");
				ok = false;
			}
			else {
				/* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */
				size_t i;
				for(i = 0; i < need*channels; i++) {
					/* inefficient but simple and works on big- or little-endian machines */
					pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]);
				}
				/* feed samples to encoder */
				ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
			}
			left -= need;
		}
	}

	ok &= FLAC__stream_encoder_finish(encoder);

	fprintf(stderr, "encoding: %s\n", ok? "succeeded" : "FAILED");
	fprintf(stderr, "   state: %s\n", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]);

	/* now that encoding is finished, the metadata can be freed */
	FLAC__metadata_object_delete(metadata[0]);
	FLAC__metadata_object_delete(metadata[1]);

	FLAC__stream_encoder_delete(encoder);
	fclose(fin);

	return 0;
}
Пример #12
0
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;
}
Пример #13
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;
}
Пример #14
0
int __stdcall
WWFlacRW_EncodeInit(const WWFlacMetadata &meta)
{
    FLAC__bool                    ok = true;
    FLAC__StreamMetadata_VorbisComment_Entry entry;

    FlacEncodeInfo *fei = FlacTInfoNew<FlacEncodeInfo>(g_flacEncodeInfoMap);
    if (NULL == fei) {
        return FRT_OtherError;
    }
    
    fei->errorCode = FRT_Success;

    fei->sampleRate = meta.sampleRate;
    fei->channels = meta.channels;
    fei->bitsPerSample = meta.bitsPerSample;
    fei->totalSamples = meta.totalSamples;
    fei->totalBytesPerChannel = meta.totalSamples * fei->bitsPerSample/8;
    fei->pictureBytes = meta.pictureBytes;

    assert(NULL == fei->buffPerChannel);
    fei->buffPerChannel = new uint8_t*[fei->channels];
    if (NULL == fei->buffPerChannel) {
        return FRT_MemoryExhausted;
    }
    memset(fei->buffPerChannel, 0, sizeof(uint8_t*)*fei->channels);
    
    WCTOUTF8(titleStr);
    WCTOUTF8(artistStr);
    WCTOUTF8(albumStr);
    WCTOUTF8(albumArtistStr);
    WCTOUTF8(genreStr);

    WCTOUTF8(dateStr);
    WCTOUTF8(trackNumberStr);
    WCTOUTF8(discNumberStr);
    WCTOUTF8(pictureMimeTypeStr);
    WCTOUTF8(pictureDescriptionStr);

    if((fei->encoder = FLAC__stream_encoder_new()) == NULL) {
        dprintf("FLAC__stream_encoder_new failed\n");
        fei->errorCode = FRT_OtherError;
        goto end;
    }

    ok &= FLAC__stream_encoder_set_verify(fei->encoder, true);
    ok &= FLAC__stream_encoder_set_compression_level(fei->encoder, 5);
    ok &= FLAC__stream_encoder_set_channels(fei->encoder, fei->channels);
    ok &= FLAC__stream_encoder_set_bits_per_sample(fei->encoder, fei->bitsPerSample);
    ok &= FLAC__stream_encoder_set_sample_rate(fei->encoder, fei->sampleRate);
    ok &= FLAC__stream_encoder_set_total_samples_estimate(fei->encoder, fei->totalSamples);

    if(!ok) {
        dprintf("FLAC__stream_encoder_set_??? failed\n");
        fei->errorCode = FRT_OtherError;
        goto end;
    }

    if((fei->flacMetaArray[FMT_VorbisComment] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL) {
        dprintf("FLAC__metadata_object_new vorbis comment failed\n");
        fei->errorCode = FRT_OtherError;
        goto end;
    }
    if((fei->flacMetaArray[FMT_Picture] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE)) == NULL) {
        dprintf("FLAC__metadata_object_new picture failed\n");
        fei->errorCode = FRT_OtherError;
        goto end;
    }

    fei->flacMetaCount = 1;

    ADD_TAG(titleStr,       "TITLE");
    ADD_TAG(artistStr,      "ARTIST");
    ADD_TAG(albumStr,       "ALBUM");
    ADD_TAG(albumArtistStr, "ALBUMARTIST");
    ADD_TAG(genreStr,       "GENRE");

    ADD_TAG(dateStr,        "DATE");
    ADD_TAG(trackNumberStr, "TRACKNUMBER");
    ADD_TAG(discNumberStr,  "DISCNUMBER");

end:
    if (fei->errorCode < 0) {
        if (NULL != fei->encoder) {
            FLAC__stream_encoder_delete(fei->encoder);
            fei->encoder = NULL;
        }

        DeleteFlacMetaArray(fei);

        int result = fei->errorCode;
        FlacTInfoDelete<FlacEncodeInfo>(g_flacEncodeInfoMap, fei);
        fei = NULL;

        return result;
    }

    return fei->id;
}
Пример #15
0
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;
}
Пример #16
0
ACFLACEncoder::ACFLACEncoder(OSType theSubType)
:
	ACFLACCodec(kInputBufferPackets * kFramesPerPacket * sizeof(SInt16), theSubType)
{	
	//	This encoder only accepts (16- or 24-bit) native endian signed integers as it's input,
	//	but can handle any sample rate and any number of channels
	CAStreamBasicDescription theInputFormat1(kAudioStreamAnyRate, kAudioFormatLinearPCM, 0, 1, 0, 0, 16, kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
	AddInputFormat(theInputFormat1);
	
	CAStreamBasicDescription theInputFormat2(kAudioStreamAnyRate, kAudioFormatLinearPCM, 0, 1, 0, 0, 24, kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
	AddInputFormat(theInputFormat2);

	// These are some additional formats that FLAC can support
	//CAStreamBasicDescription theInputFormat3(kAudioStreamAnyRate, kAudioFormatLinearPCM, 0, 1, 0, 0, 32, kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
	//AddInputFormat(theInputFormat3);

	//CAStreamBasicDescription theInputFormat4(kAudioStreamAnyRate, kAudioFormatLinearPCM, 0, 1, 0, 0, 20, kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsAlignedHigh);
	//AddInputFormat(theInputFormat4);
	
	//	set our intial input format to stereo 32 bit native endian signed integer at a 44100 sample rate
	mInputFormat.mSampleRate = 44100;
	mInputFormat.mFormatID = kAudioFormatLinearPCM;
	mInputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
	mInputFormat.mBytesPerPacket = 4;
	mInputFormat.mFramesPerPacket = 1;
	mInputFormat.mBytesPerFrame = 4;
	mInputFormat.mChannelsPerFrame = 2;
	mInputFormat.mBitsPerChannel = 16;
	
	//	This encoder only puts out a FLAC stream
	CAStreamBasicDescription theOutputFormat1(kAudioStreamAnyRate, kAudioFormatFLAC, 0, kFramesPerPacket, 0, 0, 0, 0);
	AddOutputFormat(theOutputFormat1);

	//	set our intial output format to stereo FLAC at a 44100 sample rate -- note however the 16 bit bit depth
	mOutputFormat.mSampleRate = 44100;
	mOutputFormat.mFormatFlags = kFLACFormatFlag_16BitSourceData;
	mOutputFormat.mBytesPerPacket = 0;
	mOutputFormat.mFramesPerPacket = kFramesPerPacket;
	mOutputFormat.mFormatID = kAudioFormatFLAC;
	mOutputFormat.mBytesPerFrame = 0;
	mOutputFormat.mChannelsPerFrame = 2;
	mOutputFormat.mBitsPerChannel = 0;
	
	mSupportedChannelTotals[0] = 1;
	mSupportedChannelTotals[1] = 2;
	mSupportedChannelTotals[2] = 3;
	mSupportedChannelTotals[3] = 4;
	mSupportedChannelTotals[4] = 5;
	mSupportedChannelTotals[5] = 6;
	mSupportedChannelTotals[6] = 7;
	mSupportedChannelTotals[7] = 8;
	
	mPacketInInputBuffer = false;

	mFormat = 0;

	mTotalBytesGenerated = 0;
	
	mQuality = 0; // Compression Quality
	mInputBufferBytesUsed = 0;
	mFlushPacket = false;
	mFinished = false;
	mTrailingFrames = 0;
	mBitDepth = 16;
	mEncoder = FLAC__stream_encoder_new();
	mEncoderState = FLAC__stream_encoder_get_state(mEncoder);
}
Пример #17
0
int convertWavToFlac(const char *wave_file, const char *flac_file, int split_interval_seconds, char** out_flac_files) {
    FILE *fin;
    if((fin = fopen(wave_file, "rb")) == NULL) {
        fprintf(stderr, "ERROR: opening %s for output\n", wave_file);
        return 1;
    }
    
    // read wav header and validate it, note this will most likely fail for WAVE files not created by Apple
    if(fread(buffer, 1, 44, fin) != 44 ||
       memcmp(buffer, "RIFF", 4) ||
       memcmp(buffer+36, "FLLR", 4)) {
        fprintf(stderr, "ERROR: invalid/unsupported WAVE file\n");
        fclose(fin);
        return 1;
    }
    unsigned num_channels = ((unsigned)buffer[23] << 8) | buffer[22];;
    unsigned sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) | buffer[25]) << 8) | buffer[24];
    //unsigned byte_rate = ((((((unsigned)buffer[31] << 8) | buffer[30]) << 8) | buffer[29]) << 8) | buffer[28];
    //unsigned block_align = ((unsigned)buffer[33] << 8) | buffer[32];
    unsigned bps = ((unsigned)buffer[35] << 8) | buffer[34];
    
    //Apple puts the number of filler bytes in the 2 bytes following FLLR in the filler chunk
    //get the int value of the hex
    unsigned filler_byte_count = ((unsigned)buffer[41] << 8) | buffer[40];
    //swallow the filler bytes, exiting if there were not enough
    if(fread(buffer, 1, filler_byte_count, fin) != filler_byte_count) {
        fprintf(stderr, "ERROR: invalid number of filler bytes\n");
        return 1;
    }
    //swallow the beginning of the data chunk, i.e. the word 'data'
    unsigned data_subchunk_size = 0;
    if(fread(buffer, 1, 8, fin) != 8 || memcmp(buffer, "data", 4))  {
        fprintf(stderr, "ERROR: bad data start section\n");
        return 1;
    }
    else {
        //Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
        data_subchunk_size = ((((((unsigned)buffer[7] << 8) | buffer[6]) << 8) | buffer[5]) << 8) | buffer[4];
    }

    //create the flac encoder
    FLAC__StreamEncoder *encoder = FLAC__stream_encoder_new();
    FLAC__stream_encoder_set_verify(encoder, true);
    FLAC__stream_encoder_set_compression_level(encoder, 5);
    FLAC__stream_encoder_set_channels(encoder, num_channels);
    FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
    FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
    //unknown total samples
    FLAC__stream_encoder_set_total_samples_estimate(encoder, 0);
    char* next_flac_file = malloc(sizeof(char) * 1024);
    sprintf(next_flac_file, "%s.flac", flac_file);
    //fprintf(stderr, "writing to new flac file %s\n", next_flac_file);
    FLAC__stream_encoder_init_file(encoder, next_flac_file, progress_callback, NULL);
    
    long total_bytes_read = 0;
    int did_split_at_interval[1024];
    for(int i = 0; i < 1024; i++) {
        did_split_at_interval[i] = 0;
    }

    //read the wav file data chunk until we reach the end of the file.
    size_t bytes_read = 0;
    size_t need = (size_t)READSIZE;
    int flac_file_index = 0;
    while((bytes_read = fread(buffer, num_channels * (bps/8), need, fin)) != 0) {
        /* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */
        size_t i;
        for(i = 0; i < bytes_read*num_channels; i++) {
            /* inefficient but simple and works on big- or little-endian machines */
            pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]);
        }
        /* feed samples to encoder */
        FLAC__stream_encoder_process_interleaved(encoder, pcm, bytes_read);
        total_bytes_read += bytes_read;
        
        if(split_interval_seconds > 0) {
            double elapsed_time_seconds = (total_bytes_read * 16) / (bps * sample_rate);
            int interval = elapsed_time_seconds / split_interval_seconds;
            if(interval > 0) {
                if(!did_split_at_interval[interval-1]) {
                    //finish encoding the current flac file
                    FLAC__stream_encoder_finish(encoder);
                    FLAC__stream_encoder_delete(encoder);
                    
                    //add the flac file to the out_flac_files output parameter
                    *(out_flac_files + flac_file_index) = next_flac_file;
                    flac_file_index += 1;
                    
                    //get a new flac file name
                    //free(next_flac_file);
                    next_flac_file = malloc(sizeof(char) * 1024);
                    sprintf(next_flac_file, "%s_%d.flac", flac_file, interval);
                    //fprintf(stderr, "writing to new flac file %s\n", next_flac_file);
                    
                    //create a new encoder
                    encoder = FLAC__stream_encoder_new();
                    FLAC__stream_encoder_set_verify(encoder, true);
                    FLAC__stream_encoder_set_compression_level(encoder, 5);
                    FLAC__stream_encoder_set_channels(encoder, num_channels);
                    FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
                    FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
                    FLAC__stream_encoder_set_total_samples_estimate(encoder, 0);
                    FLAC__stream_encoder_init_file(encoder, next_flac_file, progress_callback, NULL);
                    
                    //mark the interval as split
                    did_split_at_interval[interval-1] = 1;
                }
            }
        }
    }
    //fprintf(stderr, "total bytes read: %ld\nbits per sample: %d\nsample rate: %d\n", total_bytes_read, bps, sample_rate);

    *(out_flac_files + flac_file_index) = next_flac_file;

    //cleanup
    FLAC__stream_encoder_finish(encoder);
    FLAC__stream_encoder_delete(encoder);
    fclose(fin);
    
    return 0;
}
Пример #18
0
static int start_write(sox_format_t * const ft)
{
  priv_t * p = (priv_t *)ft->priv;
  FLAC__StreamEncoderState status;
  unsigned compression_level = MAX_COMPRESSION; /* Default to "best" */

  if (ft->encoding.compression != HUGE_VAL) {
    compression_level = ft->encoding.compression;
    if (compression_level != ft->encoding.compression ||
        compression_level > MAX_COMPRESSION) {
      lsx_fail_errno(ft, SOX_EINVAL,
                 "FLAC compression level must be a whole number from 0 to %i",
                 MAX_COMPRESSION);
      return SOX_EOF;
    }
  }

  p->encoder = FLAC__stream_encoder_new();
  if (p->encoder == NULL) {
    lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder instance");
    return SOX_EOF;
  }
  p->decoded_samples = lsx_malloc(sox_globals.bufsiz * sizeof(FLAC__int32));

  p->bits_per_sample = ft->encoding.bits_per_sample;

  lsx_report("encoding at %i bits per sample", p->bits_per_sample);

  FLAC__stream_encoder_set_channels(p->encoder, ft->signal.channels);
  FLAC__stream_encoder_set_bits_per_sample(p->encoder, p->bits_per_sample);
  FLAC__stream_encoder_set_sample_rate(p->encoder, (unsigned)(ft->signal.rate + .5));

  { /* Check if rate is streamable: */
    static const unsigned streamable_rates[] =
      {8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    size_t i;
    sox_bool streamable = sox_false;
    for (i = 0; !streamable && i < array_length(streamable_rates); ++i)
       streamable = (streamable_rates[i] == ft->signal.rate);
    if (!streamable) {
      lsx_report("non-standard rate; output may not be streamable");
      FLAC__stream_encoder_set_streamable_subset(p->encoder, sox_false);
    }
  }

#if FLAC_API_VERSION_CURRENT >= 10
  FLAC__stream_encoder_set_compression_level(p->encoder, compression_level);
#else
  {
    static struct {
      unsigned blocksize;
      FLAC__bool do_exhaustive_model_search;
      FLAC__bool do_mid_side_stereo;
      FLAC__bool loose_mid_side_stereo;
      unsigned max_lpc_order;
      unsigned max_residual_partition_order;
      unsigned min_residual_partition_order;
    } const options[MAX_COMPRESSION + 1] = {
      {1152, sox_false, sox_false, sox_false, 0, 2, 2},
      {1152, sox_false, sox_true, sox_true, 0, 2, 2},
      {1152, sox_false, sox_true, sox_false, 0, 3, 0},
      {4608, sox_false, sox_false, sox_false, 6, 3, 3},
      {4608, sox_false, sox_true, sox_true, 8, 3, 3},
      {4608, sox_false, sox_true, sox_false, 8, 3, 3},
      {4608, sox_false, sox_true, sox_false, 8, 4, 0},
      {4608, sox_true, sox_true, sox_false, 8, 6, 0},
      {4608, sox_true, sox_true, sox_false, 12, 6, 0},
    };
#define SET_OPTION(x) do {\
  lsx_report(#x" = %i", options[compression_level].x); \
  FLAC__stream_encoder_set_##x(p->encoder, options[compression_level].x);\
} while (0)
    SET_OPTION(blocksize);
    SET_OPTION(do_exhaustive_model_search);
    SET_OPTION(max_lpc_order);
    SET_OPTION(max_residual_partition_order);
    SET_OPTION(min_residual_partition_order);
    if (ft->signal.channels == 2) {
      SET_OPTION(do_mid_side_stereo);
      SET_OPTION(loose_mid_side_stereo);
    }
#undef SET_OPTION
  }
#endif

  if (ft->signal.length != 0) {
    FLAC__stream_encoder_set_total_samples_estimate(p->encoder, (FLAC__uint64)(ft->signal.length / ft->signal.channels));

    p->metadata[p->num_metadata] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE);
    if (p->metadata[p->num_metadata] == NULL) {
      lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder seek table template");
      return SOX_EOF;
    }
    {
#if FLAC_API_VERSION_CURRENT >= 8
      if (!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(p->metadata[p->num_metadata], (unsigned)(10 * ft->signal.rate + .5), (FLAC__uint64)(ft->signal.length/ft->signal.channels))) {
#else
      size_t samples = 10 * ft->signal.rate;
      size_t total_samples = ft->signal.length/ft->signal.channels;
      if (!FLAC__metadata_object_seektable_template_append_spaced_points(p->metadata[p->num_metadata], total_samples / samples + (total_samples % samples != 0), (FLAC__uint64)total_samples)) {
#endif
        lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder seek table points");
        return SOX_EOF;
      }
    }
    p->metadata[p->num_metadata]->is_last = sox_false; /* the encoder will set this for us */
    ++p->num_metadata;
  }

  if (ft->oob.comments) {     /* Make the comment structure */
    FLAC__StreamMetadata_VorbisComment_Entry entry;
    int i;

    p->metadata[p->num_metadata] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
    for (i = 0; ft->oob.comments[i]; ++i) {
      static const char prepend[] = "Comment=";
      char * text = lsx_calloc(strlen(prepend) + strlen(ft->oob.comments[i]) + 1, sizeof(*text));
      /* Prepend `Comment=' if no field-name already in the comment */
      if (!strchr(ft->oob.comments[i], '='))
        strcpy(text, prepend);
      entry.entry = (FLAC__byte *) strcat(text, ft->oob.comments[i]);
      entry.length = strlen(text);
      FLAC__metadata_object_vorbiscomment_append_comment(p->metadata[p->num_metadata], entry, /*copy= */ sox_true);
      free(text);
    }
    ++p->num_metadata;
  }

  if (p->num_metadata)
    FLAC__stream_encoder_set_metadata(p->encoder, p->metadata, p->num_metadata);

#if FLAC_API_VERSION_CURRENT <= 7
  FLAC__stream_encoder_set_write_callback(p->encoder, flac_stream_encoder_write_callback);
  FLAC__stream_encoder_set_metadata_callback(p->encoder, flac_stream_encoder_metadata_callback);
  FLAC__stream_encoder_set_client_data(p->encoder, ft);
  status = FLAC__stream_encoder_init(p->encoder);
#else
  status = FLAC__stream_encoder_init_stream(p->encoder, flac_stream_encoder_write_callback,
      flac_stream_encoder_seek_callback, flac_stream_encoder_tell_callback, flac_stream_encoder_metadata_callback, ft);
#endif

  if (status != FLAC__STREAM_ENCODER_OK) {
    lsx_fail_errno(ft, SOX_EINVAL, "%s", FLAC__StreamEncoderStateString[status]);
    return SOX_EOF;
  }
  return SOX_SUCCESS;
}



static size_t write_samples(sox_format_t * const ft, sox_sample_t const * const sampleBuffer, size_t const len)
{
  priv_t * p = (priv_t *)ft->priv;
  unsigned i;

  for (i = 0; i < len; ++i) {
    long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
    p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample);
    switch (p->bits_per_sample) {
      case  8: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
        break;
      case 16: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
        break;
      case 24: p->decoded_samples[i] = /* sign extension: */
          SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
        p->decoded_samples[i] >>= 8;
        break;
      case 32: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
        break;
    }
  }
  FLAC__stream_encoder_process_interleaved(p->encoder, p->decoded_samples, (unsigned) len / ft->signal.channels);
  return FLAC__stream_encoder_get_state(p->encoder) == FLAC__STREAM_ENCODER_OK ? len : 0;
}
bool ofxFlacEncoder::encode(string wavInput, string flacOutput) {
    
    //ofLog(OF_LOG_VERBOSE, "init encoding (device%d)",deviceId);
	FLAC__bool ok = true;
	FLAC__StreamEncoder *encoder = 0;
	FLAC__StreamEncoderInitStatus init_status;
	FILE *fin;
	unsigned sample_rate = 0;
	unsigned channels = 0;
	unsigned bps = 0;
    
	if((fin = fopen(ofToDataPath(wavInput).c_str(), "rb")) == NULL){
        
		//ofLog(OF_LOG_ERROR, "ERROR: opening %s for output\n", wavFile);
		return false;
	}
    
	// read and validate wav header
	if(fread(buffer, 1, 44, fin) != 44 || memcmp(buffer, "RIFF", 4)
       || memcmp(buffer + 8, "WAVEfmt \020\000\000\000\001\000\002\000", 16)
       || memcmp(buffer + 32, "\004\000\020\000data", 8)){
		ofLog(OF_LOG_ERROR,
              "invalid/unsupported WAVE file, only 16bps stereo WAVE in canonical form allowed");
		//fclose(fin);
		//return false;
	}
	sample_rate = ((((((unsigned) buffer[27] << 8) | buffer[26]) << 8) | buffer[25]) << 8)
    | buffer[24];
	channels = 2;
	bps = 16;
	total_samples = (((((((unsigned) buffer[43] << 8) | buffer[42]) << 8) | buffer[41]) << 8)
                     | buffer[40]) / 4;
    
	// allocate the encoder
	if((encoder = FLAC__stream_encoder_new()) == NULL){
		ofLog(OF_LOG_ERROR, " allocating encoder\n");
		fclose(fin);
		return false;
	}
    
	ok &= FLAC__stream_encoder_set_verify(encoder, true);
	ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
	ok &= FLAC__stream_encoder_set_channels(encoder, channels);
	ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
	ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
	ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples);
    
	// initialize encoder
	if(ok){
		init_status = FLAC__stream_encoder_init_file(encoder, ofToDataPath(flacOutput).c_str(), NULL, NULL);
		if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK){
			ofLog(OF_LOG_ERROR, "initializing encoder: ");
			ofLog(OF_LOG_ERROR, FLAC__StreamEncoderInitStatusString[init_status]);
			ok = false;
		}
	}
    
	//ofLog(OF_LOG_VERBOSE, "start encoding (device%d)",deviceId);
	/* read blocks of samples from WAVE file and feed to encoder */
	if(ok){
		size_t left = (size_t) total_samples;
		while(ok && left){
			size_t need = (left > READSIZE ? (size_t) READSIZE : (size_t) left);
			if(fread(buffer, channels * (bps / 8), need, fin) != need){
				ofLog(OF_LOG_ERROR, "reading from WAVE file");
				ok = false;
			}else{
				/* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */
				size_t i;
				for(i = 0; i < need * channels; i++){
					/* inefficient but simple and works on big- or little-endian machines */
					pcm[i] = (FLAC__int32) (((FLAC__int16) (FLAC__int8) buffer[2 * i + 1] << 8)
                                            | (FLAC__int16) buffer[2 * i]);
				}
				/* feed samples to encoder */
				ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
			}
			left -= need;
		}
	}
    
	ok &= FLAC__stream_encoder_finish(encoder);
    
    //	fprintf(stderr, "encoding: %s\n", ok ? "succeeded" : "FAILED");
    //	fprintf(stderr,
    //			"   state: %s\n",
    //			FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]);
    
	FLAC__stream_encoder_delete(encoder);
	fclose(fin);
    
	return ok;


    
}
Пример #20
0
const char*
_edje_multisense_encode_to_flac(char *snd_path, SF_INFO sfinfo)
{
   unsigned int total_samples = 0; /* can use a 32-bit number due to WAVE size limitations */
   FLAC__bool ok = 1;
   FLAC__StreamEncoder *encoder = 0;
   FLAC__StreamEncoderInitStatus init_status;
   FLAC__StreamMetadata *metadata[2];
   FLAC__StreamMetadata_VorbisComment_Entry entry;
   SNDFILE *sfile;
   sf_count_t size;
   char *tmp;

   sfile = sf_open(snd_path, SFM_READ, &sfinfo);
   if (!sfile) return NULL;
   if (!sf_format_check(&sfinfo))
     {
        sf_close(sfile);
        return NULL;
     }
   size = sf_seek(sfile, 0, SEEK_END);
   sf_seek(sfile, 0, SEEK_SET);
   tmp = malloc(strlen(snd_path) + 1 + 5);
   if (!tmp)
     {
        sf_close(sfile);
        return NULL;
     }
   strcpy(tmp, snd_path);
   snd_path = tmp;
   strcat(snd_path, ".flac");

   total_samples = size;

   /* allocate the encoder */
   if ((encoder = FLAC__stream_encoder_new()) == NULL)
     {
        ERR("ERROR: Creating FLAC encoder\n");
        free(snd_path);
        sf_close(sfile);
        return NULL;
     }

   /* Verify it's own encoded output. This will slow the encoding process. */
   ok &= FLAC__stream_encoder_set_verify(encoder, 1);

   //Levels range from 0 (fastest, least compression) to 8 (slowest, most compression).
   //A value larger than 8 will be treated as 8.
   //5 is used for good compression and moderate compression/decompression speed.
   ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
   ok &= FLAC__stream_encoder_set_channels(encoder, sfinfo.channels);
   ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, 16);
   ok &= FLAC__stream_encoder_set_sample_rate(encoder, sfinfo.samplerate);
   ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples);

   /* now add some metadata; we'll add some tags and a padding block */
   if (ok)
     {
        if ((metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL
            || (metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL
            || !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "Encoder", "flac")
            || !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, 0))
          {
             ERR("ERROR: out of memory error or tag error\n");
             ok = 0;
          }
        metadata[1]->length = 16; /* set the padding length */
        ok = FLAC__stream_encoder_set_metadata(encoder, metadata, 2);
     }

   /* initialize encoder */
   if (ok)
     {
        init_status = FLAC__stream_encoder_init_file(encoder, snd_path, NULL,
                                                     (void *)(long)(total_samples));
        if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
          {
             ERR("ERROR: unable to initialize FLAC encoder: %s\n",
                 FLAC__StreamEncoderInitStatusString[init_status]);
             ok = 0;
          }
     }
   
   /* read blocks of samples from WAVE file and feed to encoder */
   while (ok)
     {
        FLAC__int32 readbuffer[READBUF * 2];
        sf_count_t count;
        int i;
        
        count = sf_readf_int(sfile, readbuffer, READBUF);
        if (count <= 0) break;
        for (i = 0; i < (count * sfinfo.channels); i++)
          readbuffer[i] = readbuffer[i] >> 16;
        ok = FLAC__stream_encoder_process_interleaved(encoder, readbuffer,
                                                      count);
     }

   FLAC__stream_encoder_finish(encoder);
   /* now that encoding is finished, the metadata can be freed */
   FLAC__metadata_object_delete(metadata[0]);
   FLAC__metadata_object_delete(metadata[1]);

   FLAC__stream_encoder_delete(encoder);
   sf_close(sfile);
   return (snd_path);
}
Пример #21
0
int WFLACEncoder::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;


	if((c_encoder = FLAC__stream_encoder_new()) == NULL)
	{
		err(ENCODER_INITIALIZATION_ERROR);
		return 0;
	}


	FLAC__bool ok = true;

	ok &= FLAC__stream_encoder_set_verify(c_encoder, false);
	ok &= FLAC__stream_encoder_set_compression_level(c_encoder, 5);
	ok &= FLAC__stream_encoder_set_channels(c_encoder, c_nNumberOfChannels);
	ok &= FLAC__stream_encoder_set_bits_per_sample(c_encoder, c_nBitBerSample);
	ok &= FLAC__stream_encoder_set_sample_rate(c_encoder, c_nSampleRate);
	ok &= FLAC__stream_encoder_set_total_samples_estimate(c_encoder, 0);

	if(!ok)
	{
		FLAC__stream_encoder_delete(c_encoder);
		c_encoder = NULL;
		err(ENCODER_INITIALIZATION_ERROR);
		return 0;
	}


	if(c_fOgg)
	{
		if(FLAC__stream_encoder_init_ogg_stream(c_encoder, f_read_callback, f_write_callback, f_seek_callback, f_tell_callback, NULL, this) != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
		{
			FLAC__stream_encoder_delete(c_encoder);
			c_encoder = NULL;
			err(ENCODER_FILEOPEN_ERROR);
			return 0;			
		}

	}
	else
	{
		if(FLAC__stream_encoder_init_stream(c_encoder, f_write_callback, f_seek_callback, f_tell_callback, NULL, this) != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
		{
			FLAC__stream_encoder_delete(c_encoder);
			c_encoder = NULL;
			err(ENCODER_FILEOPEN_ERROR);
			return 0;			
		}
	}

	c_fReady = 1;
	return 1;
}
Пример #22
0
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
}
Пример #23
0
static bool
flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
		     GError **error)
{
	struct flac_encoder *encoder = (struct flac_encoder *)_encoder;
	unsigned bits_per_sample;

	encoder->audio_format = *audio_format;

	/* FIXME: flac should support 32bit as well */
	switch (audio_format->format) {
	case SAMPLE_FORMAT_S8:
		bits_per_sample = 8;
		break;

	case SAMPLE_FORMAT_S16:
		bits_per_sample = 16;
		break;

	case SAMPLE_FORMAT_S24_P32:
		bits_per_sample = 24;
		break;

	default:
		bits_per_sample = 24;
		audio_format->format = SAMPLE_FORMAT_S24_P32;
	}

	/* allocate the encoder */
	encoder->fse = FLAC__stream_encoder_new();
	if (encoder->fse == NULL) {
		g_set_error(error, flac_encoder_quark(), 0,
			    "flac_new() failed");
		return false;
	}

	if (!flac_encoder_setup(encoder, bits_per_sample, error)) {
		FLAC__stream_encoder_delete(encoder->fse);
		return false;
	}

	encoder->buffer_length = 0;
	pcm_buffer_init(&encoder->buffer);
	pcm_buffer_init(&encoder->expand_buffer);

	/* this immediately outputs data through callback */

#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
	{
		FLAC__StreamEncoderState init_status;

		FLAC__stream_encoder_set_write_callback(encoder->fse,
					    flac_write_callback);

		init_status = FLAC__stream_encoder_init(encoder->fse);

		if (init_status != FLAC__STREAM_ENCODER_OK) {
			g_set_error(error, flac_encoder_quark(), 0,
			    "failed to initialize encoder: %s\n",
			    FLAC__StreamEncoderStateString[init_status]);
			flac_encoder_close(_encoder);
			return false;
		}
	}
#else
	{
		FLAC__StreamEncoderInitStatus init_status;

		init_status = FLAC__stream_encoder_init_stream(encoder->fse,
			    flac_write_callback,
			    NULL, NULL, NULL, encoder);

		if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
			g_set_error(error, flac_encoder_quark(), 0,
			    "failed to initialize encoder: %s\n",
			    FLAC__StreamEncoderInitStatusString[init_status]);
			flac_encoder_close(_encoder);
			return false;
		}
	}
#endif

	return true;
}