OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_encoder_get_verify_decoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
{
	FLAC__ASSERT(0 != encoder);
	FLAC__ASSERT(0 != encoder->private_);
	FLAC__ASSERT(0 != encoder->protected_);
	FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
	return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
}
Esempio n. 2
0
File: flac_a.c Progetto: ranvis/tina
static int output_data(char *buf, int32 nbytes)
{
  FLAC__int32 *oggbuf;
  FLAC__int16 *s;
  int i;
  int nch = (dpm.encoding & PE_MONO) ? 1 : 2;

  FLAC_ctx *ctx = flac_ctx;

  if (dpm.fd < 0)
    return 0;

  if (ctx == NULL) {
    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream is not initialized");
    return -1;
  }

  oggbuf = (FLAC__int32 *)safe_malloc(nbytes * sizeof(FLAC__int32) / nch);

  /*
    packing 16 -> 32 bit sample
  */
  s = (FLAC__int16 *)buf;
  for (i = 0; i < nbytes / nch; i++) {
    oggbuf[i] = *s++;
  }

#ifdef LEGACY_FLAC
#ifdef AU_OGGFLAC
  if (flac_options.isogg) {
    ctx->state.ogg = OggFLAC__stream_encoder_get_state(ctx->encoder.ogg.stream);
    if (ctx->state.ogg != OggFLAC__STREAM_ENCODER_OK) {
      if (ctx->state.ogg == OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR) {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)",
		  FLAC__StreamDecoderStateString[OggFLAC__stream_encoder_get_verify_decoder_state(ctx->encoder.ogg.stream)]);
      }
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode OggFLAC stream (%s)",
		OggFLAC__StreamEncoderStateString[ctx->state.ogg]);
      flac_session_close();
      return -1;
    }

    if (!OggFLAC__stream_encoder_process_interleaved(ctx->encoder.ogg.stream, oggbuf,
						     nbytes / nch / 2)) {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode OggFLAC stream");
      flac_session_close();
      return -1;
    }
  }
  else
#endif /* AU_OGGFLAC */
	if (flac_options.seekable) {
    ctx->state.s_flac = FLAC__seekable_stream_encoder_get_state(ctx->encoder.flac.s_stream);
    if (ctx->state.s_flac != FLAC__STREAM_ENCODER_OK) {
      if (ctx->state.s_flac == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR ||
	  ctx->state.s_flac == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)",
		  FLAC__SeekableStreamDecoderStateString[FLAC__seekable_stream_encoder_get_verify_decoder_state(ctx->encoder.flac.s_stream)]);
      }
      else {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream (%s)",
		  FLAC__SeekableStreamEncoderStateString[ctx->state.s_flac]);
      }
      flac_session_close();
      return -1;
    }

    if (!FLAC__seekable_stream_encoder_process_interleaved(ctx->encoder.flac.s_stream, oggbuf,
						  nbytes / nch / 2 )) {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream");
      flac_session_close();
      return -1;
    }
	}
  else
	{
    ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream);
    if (ctx->state.flac != FLAC__STREAM_ENCODER_OK) {
      if (ctx->state.flac == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR ||
	  ctx->state.flac == FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)",
		  FLAC__StreamDecoderStateString[FLAC__stream_encoder_get_verify_decoder_state(ctx->encoder.flac.stream)]);
      }
      else {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream (%s)",
		  FLAC__StreamEncoderStateString[ctx->state.flac]);
      }
      flac_session_close();
      return -1;
    }

    if (!FLAC__stream_encoder_process_interleaved(ctx->encoder.flac.stream, oggbuf,
						  nbytes / nch / 2 )) {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream");
      flac_session_close();
      return -1;
    }
  }
#else /* !LEGACY_FLAC */
  ctx->state.flac = FLAC__stream_encoder_get_state(ctx->encoder.flac.stream);
  if (ctx->state.flac != FLAC__STREAM_ENCODER_OK) {
    if (ctx->state.flac == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR |
	FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "FLAC stream verify error (%s)",
		FLAC__StreamDecoderStateString[FLAC__stream_encoder_get_verify_decoder_state(ctx->encoder.flac.stream)]);
    }
    else {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream (%s)",
		FLAC__StreamEncoderStateString[ctx->state.flac]);
    }
    flac_session_close();
    return -1;
  }

  if (!FLAC__stream_encoder_process_interleaved(ctx->encoder.flac.stream, oggbuf,
						nbytes / nch / 2 )) {
    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "cannot encode FLAC stream");
    flac_session_close();
    return -1;
  }
#endif
  ctx->in_bytes += nbytes;

  free(oggbuf);
  return 0;
}
Esempio n. 3
0
int __stdcall
WWFlacRW_EncodeRun(int id, const wchar_t *path)
{
    FILE *fp = NULL;
    errno_t ercd;
    int64_t left;
    int64_t readPos;
    int64_t writePos;
    FLAC__bool ok = true;
    FLAC__int32 *pcm = NULL;

    if (NULL == path || wcslen(path) == 0) {
        return FRT_BadParams;
    }

    FLAC__StreamEncoderInitStatus initStatus = FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;

    FlacEncodeInfo *fei = FlacTInfoFindById<FlacEncodeInfo>(g_flacEncodeInfoMap, id);
    if (NULL == fei) {
        return FRT_IdNotFound;
    }

    if (0 < fei->pictureBytes && fei->pictureData == NULL) {
        dprintf("%s picture data is not set yet.\n", __FUNCTION__);
        return FRT_DataNotReady;
    }

    assert(fei->buffPerChannel);

    ok = FLAC__stream_encoder_set_metadata(fei->encoder, &fei->flacMetaArray[0], fei->flacMetaCount);
    if(!ok) {
        dprintf("FLAC__stream_encoder_set_metadata failed\n");
        fei->errorCode = FRT_OtherError;
        goto end;
    }

    for (int ch=0; ch<fei->channels; ++ch) {
        if (fei->buffPerChannel[ch] == NULL){
            dprintf("%s pcm buffer is not set yet.\n", __FUNCTION__);
            return FRT_DataNotReady;
        }
    }

    if (fei->bitsPerSample != 16 && fei->bitsPerSample != 24) {
        return FRT_InvalidBitsPerSample;
    }

    pcm = new FLAC__int32[FLACENCODE_READFRAMES * fei->channels];
    if (pcm == NULL) {
        return FRT_MemoryExhausted;
    }

    // Windowsでは、この方法でファイルを開かなければならぬ。
    wcsncpy_s(fei->path, path, (sizeof fei->path)/2-1);
    ercd = _wfopen_s(&fp, fei->path, L"wb");
    if (ercd != 0 || NULL == fp) {
        fei->errorCode = FRT_FileOpenError;
        goto end;
    }

    initStatus = FLAC__stream_encoder_init_FILE(fei->encoder, fp, ProgressCallback, fei);
    if(initStatus != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
        dprintf("FLAC__stream_encoder_init_FILE failed %s\n", FLAC__StreamEncoderInitStatusString[initStatus]);
        switch (initStatus) {
        case FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR:
            {
                FLAC__StreamDecoderState state = FLAC__stream_encoder_get_verify_decoder_state(fei->encoder);
                dprintf("decoderState=%d\n", state);
            }
            fei->errorCode = FRT_EncoderError;
            goto end;
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS:
            fei->errorCode = FRT_InvalidNumberOfChannels;
            goto end;
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE:
            fei->errorCode = FRT_InvalidBitsPerSample;
            goto end;
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE:
            fei->errorCode = FRT_InvalidSampleRate;
            goto end;
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA:
            fei->errorCode = FRT_InvalidMetadata;
            goto end;
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS:
        case FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED:
        case FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER:
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE:
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER:
        case FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION:
        case FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER:
        case FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE:
        default:
            fei->errorCode = FRT_OtherError;
            goto end;
        }
    }
    fp = NULL;

    readPos = 0;
    left = fei->totalSamples;
    while(ok && left) {
        uint32_t need = left>FLACENCODE_READFRAMES ? FLACENCODE_READFRAMES : (unsigned int)left;

        // create interleaved PCM samples to pcm[]
        writePos = 0;
        switch (fei->bitsPerSample) {
        case 16:
            for (uint32_t i=0; i<need; ++i) {
                for (int ch=0; ch<fei->channels;++ch) {
                    uint8_t *p = &fei->buffPerChannel[ch][readPos];
                    int v = (p[0]<<16) + (p[1]<<24);
                    pcm[writePos] = v>>16;
                    ++writePos;
                }
                readPos += 2;
            }
            break;
        case 24:
            for (uint32_t i=0; i<need; ++i) {
                for (int ch=0; ch<fei->channels;++ch) {
                    uint8_t *p = &fei->buffPerChannel[ch][readPos];
                    int v = (p[0]<<8) + (p[1]<<16) + (p[2]<<24);
                    pcm[writePos] = v >> 8;
                    ++writePos;
                }
                readPos += 3;
            }
            break;
        default:
            assert(0);
            break;
        }

        ok = FLAC__stream_encoder_process_interleaved(fei->encoder, pcm, need);
        left -= need;
    }
    if (!ok) {
        dprintf("FLAC__stream_encoder_process_interleaved failed");
        fei->errorCode = FRT_EncoderProcessFailed;
    }

end:
    delete [] pcm;
    pcm = NULL;

    if (NULL != fp) {
        fclose(fp);
        fp = NULL;
    }

    if (NULL != fei->encoder) {
        if (initStatus == FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
            FLAC__stream_encoder_finish(fei->encoder);
        }

        DeleteFlacMetaArray(fei);

        FLAC__stream_encoder_delete(fei->encoder);
        fei->encoder = NULL;
    }

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

        return result;
    }

    return fei->id;
}