Esempio n. 1
0
//--------------------------------------------------------------------------------------------------
BOOL CSoundStream::Decompress(unsigned char *dest)
{
    u32				dwSrcSize = dwSrcBufSize;
	BOOL				r = true;

	VERIFY				(hAcmStream);

	// check for EOF
    if (dwDecPos+dwSrcSize>dwTotalSize) {
		dwSrcSize=dwTotalSize-dwDecPos;
		r=false;
	}
	hf->r	(WaveSource,dwSrcSize);

    stream.cbStruct=sizeof(stream);
    stream.fdwStatus=0;
    stream.pbSrc=WaveSource;
    stream.cbSrcLength=dwSrcSize;
    stream.pbDst=dest;
    stream.cbDstLength=dwDestBufSize;

	CHK_DX(acmStreamPrepareHeader(hAcmStream,&stream,0));
    CHK_DX(acmStreamConvert(hAcmStream,&stream,0));
    CHK_DX(acmStreamUnprepareHeader(hAcmStream,&stream,0));
    dwDecPos+=stream.cbSrcLengthUsed;

	AppWriteDataToBuffer(writepos,WaveDest,stream.cbDstLengthUsed);

    return r;
}
Esempio n. 2
0
static	DWORD	wodWrite(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2)
{
    PACMSTREAMHEADER	ash;
    LPWAVEHDR		lpWaveHdrDst;

    TRACE("(%p %p %08x)\n", wom, lpWaveHdrSrc, dwParam2);

    if (!wom->hAcmStream) {
	return waveOutWrite(wom->u.out.hInnerWave, lpWaveHdrSrc, dwParam2);
    }

    lpWaveHdrSrc->dwFlags |= WHDR_INQUEUE;
    ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved;
    /* acmStreamConvert will actually check that the new size is less than initial size */
    ash->cbSrcLength = lpWaveHdrSrc->dwBufferLength;
    if (acmStreamConvert(wom->hAcmStream, ash, 0L) != MMSYSERR_NOERROR) {
        WARN("acmStreamConvert failed\n");
	return MMSYSERR_ERROR;
    }

    lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
    if (ash->cbSrcLength > ash->cbSrcLengthUsed)
        FIXME("Not all src buffer has been written, expect bogus sound\n");
    else if (ash->cbSrcLength < ash->cbSrcLengthUsed)
        ERR("Codec has read more data than it is allowed to\n");

    if (ash->cbDstLengthUsed == 0) {
        /* something went wrong in decoding */
        FIXME("Got 0 length\n");
        return MMSYSERR_ERROR;
    }
    lpWaveHdrDst->dwBufferLength = ash->cbDstLengthUsed;
    return waveOutWrite(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));
}
Esempio n. 3
0
void  CACMStream::Convert(LPVOID src, DWORD size)
{

	m_mmr = 0;

	if (m_hdr->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)
	{
		if (src != m_hdr->pbSrc || size > m_hdr->dwSrcUser)
		{
			Unprepare();
			Prepare(src, size);
		}
	}
	else
	{
		Prepare(src, size);
	}


	m_mmr = acmStreamConvert(m_strm, 
							 m_hdr, 
							 ACM_STREAMCONVERTF_END|
							 ACM_STREAMCONVERTF_START);

	if (m_mmr)
		raiseError(m_mmr, "Error during conversion");

}
Esempio n. 4
0
void 
audio_resampler_acm::audio_receive(unsigned char *data, unsigned int size)
{
    MMRESULT err;

    /* Checking for acm stream opened */
    if (stream_opened)
    {
        /* Copy audio data from extern to internal source buffer */
        memcpy(acm_header.pbSrc, data, size);

        acm_header.cbSrcLength = size;
        acm_header.cbDstLengthUsed = 0;

        err = acmStreamConvert(acm_stream, &acm_header, ACM_STREAMCONVERTF_BLOCKALIGN);

        if (err != MMSYSERR_NOERROR)
        {
            /* TODO: throw error */
            MessageBox(0, _T("acmStreamConvert error"), _T("ERROR"), MB_ICONERROR);
        }

        /* Wait for sound conversion */
        while ((ACMSTREAMHEADER_STATUSF_DONE & acm_header.fdwStatus) == 0);

        /* Copy resampled audio, to destination buffer */
        //memcpy(pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed);
    }
}
Esempio n. 5
0
int ToADPCM(short *Source, short *Dest, int Size)
{
    int Src_size;
    int Dest_Size;

    Wave_Format.wFormatTag = WAVE_FORMAT_PCM;
    Wave_Format.nChannels = 1;
    Wave_Format.cbSize = 0;
    Wave_Format.wBitsPerSample = 16;
    Wave_Format.nSamplesPerSec = 44100;
    Wave_Format.nBlockAlign = Wave_Format.nChannels * Wave_Format.wBitsPerSample / 8;
    Wave_Format.nAvgBytesPerSec = Wave_Format.nSamplesPerSec * Wave_Format.nBlockAlign;

    ADPCM_Format.wfx.wFormatTag = WAVE_FORMAT_IMA_ADPCM;
    acmFormatSuggest(NULL, (LPWAVEFORMATEX) &Wave_Format, (LPWAVEFORMATEX) &ADPCM_Format, sizeof(TrueSpeech_Format), ACM_FORMATSUGGESTF_WFORMATTAG);
    acmStreamOpen(&Pack_Stream, NULL, (LPWAVEFORMATEX) &Wave_Format, (LPWAVEFORMATEX) &ADPCM_Format, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);

    Src_size = Size;
    unsigned long rawbufsize = 0;
    acmStreamSize(Pack_Stream, Src_size, &rawbufsize, ACM_STREAMSIZEF_SOURCE);
    Uint8 *Pack_Buf = (Uint8 *) malloc(Src_size + 8);
    memset(Pack_Buf, 0, Src_size + 8);
    Uint8 *rawbuf = (Uint8 *) malloc(rawbufsize + 8);
    memset(rawbuf, 0, rawbufsize + 8);

    ACMSTREAMHEADER Pack_Stream_Head;
    ZeroMemory(&Pack_Stream_Head, sizeof(ACMSTREAMHEADER));
    Pack_Stream_Head.cbStruct = sizeof(ACMSTREAMHEADER);
    Pack_Stream_Head.pbSrc = (Uint8 *) Pack_Buf;
    Pack_Stream_Head.cbSrcLength = Src_size;
    Pack_Stream_Head.pbDst = rawbuf;
    Pack_Stream_Head.cbDstLength = rawbufsize;
    acmStreamPrepareHeader(Pack_Stream, &Pack_Stream_Head, 0);

    memcpy(Pack_Buf, Source, Src_size);

    acmStreamConvert(Pack_Stream, &Pack_Stream_Head, 0);
    Dest_Size = Pack_Stream_Head.cbDstLengthUsed;
    if(Dest_Size < Src_size)
    {
        memcpy(Dest, rawbuf, Dest_Size);
    }
    else
    {
        Dest_Size = 0;
    }

    acmStreamUnprepareHeader(Pack_Stream, &Pack_Stream_Head, 0);
    if(rawbuf) free(rawbuf);
    if(Pack_Buf) free(Pack_Buf);
    acmStreamClose(Pack_Stream, 0);

    return(Dest_Size);
}
Esempio n. 6
0
static GstFlowReturn
acmmp3dec_chain (GstPad * pad, GstBuffer * buf)
{
  MMRESULT res;
  ACMMP3Dec *dec = (ACMMP3Dec *) GST_PAD_PARENT (pad);
  guchar *data = GST_BUFFER_DATA (buf);
  gint len = GST_BUFFER_SIZE (buf);
  GstFlowReturn ret = GST_FLOW_OK;

  if (len > ACM_BUFFER_SIZE) {
    GST_WARNING_OBJECT (dec, "Impossibly large mp3 frame!");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE &&
      (dec->timestamp == GST_CLOCK_TIME_NONE ||
          GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) {
    dec->timestamp = GST_BUFFER_TIMESTAMP (buf);
  }

  memcpy (dec->header.pbSrc, data, len);
  dec->header.cbSrcLength = len;

  /* Now we have a buffer ready to go */
  res = acmStreamConvert (dec->stream, &dec->header,
      ACM_STREAMCONVERTF_BLOCKALIGN);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to decode data");
    ret = GST_FLOW_OK;          /* Maybe it was just a corrupt frame */
    goto done;
  }

  if (dec->header.cbSrcLengthUsed > 0) {
    if (dec->header.cbSrcLengthUsed != dec->header.cbSrcLength) {
      GST_WARNING_OBJECT (dec, "ACM decoder didn't consume all data!");
      /* We could handle this, but it shouldn't be possible, so don't try
       * for now */
      ret = GST_FLOW_ERROR;
      goto done;
    }

    /* Write out any data produced */
    acmmp3dec_push_output (dec);
  }

done:
  gst_buffer_unref (buf);

  return ret;
}
Esempio n. 7
0
static void CALLBACK widCallback(HWAVEIN hWave, UINT uMsg, DWORD_PTR dwInstance,
                                 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    WAVEMAPDATA* wim = (WAVEMAPDATA*)dwInstance;

    TRACE("(%p %u %lx %lx %lx);\n", hWave, uMsg, dwInstance, dwParam1, dwParam2);

    if (!WAVEMAP_IsData(wim)) {
	ERR("Bad data\n");
	return;
    }

    if (uMsg != WIM_OPEN && hWave != wim->u.in.hInnerWave)
	ERR("Shouldn't happen (%p %p)\n", hWave, wim->u.in.hInnerWave);

    switch (uMsg) {
    case WIM_OPEN:
    case WIM_CLOSE:
	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
	break;
    case WIM_DATA:
	if (wim->hAcmStream) {
	    LPWAVEHDR		lpWaveHdrSrc = (LPWAVEHDR)dwParam1;
	    PACMSTREAMHEADER	ash = (PACMSTREAMHEADER)((LPSTR)lpWaveHdrSrc - sizeof(ACMSTREAMHEADER));
	    LPWAVEHDR		lpWaveHdrDst = (LPWAVEHDR)ash->dwUser;

	    /* convert data just gotten from waveIn into requested format */
	    if (acmStreamConvert(wim->hAcmStream, ash, 0L) != MMSYSERR_NOERROR) {
		ERR("ACM conversion failed\n");
		return;
	    } else {
		TRACE("Converted %d bytes into %d\n", ash->cbSrcLengthUsed, ash->cbDstLengthUsed);
	    }
	    /* and setup the wavehdr to return accordingly */
	    lpWaveHdrDst->dwFlags &= ~WHDR_INQUEUE;
	    lpWaveHdrDst->dwFlags |= WHDR_DONE;
	    lpWaveHdrDst->dwBytesRecorded = ash->cbDstLengthUsed;
            dwParam1 = (DWORD_PTR)lpWaveHdrDst;
	}
	break;
    default:
	ERR("Unknown msg %u\n", uMsg);
    }

    DriverCallback(wim->dwCallback, HIWORD(wim->dwFlags), (HDRVR)wim->u.in.hOuterWave,
		   uMsg, wim->dwClientInstance, dwParam1, dwParam2);
}
Esempio n. 8
0
	void audioFeed(char *buf, int len)
	{
		int work = len;
		int chunk;

		if(!work)
			return;

		char *bufPtr = buf;

		for(;;)
		{
			if(lastDecodedSize != -1)
			{
				chunk = lastDecodedSize-audioDecodedCursor;
				if(chunk > work)
					chunk = work;
				memcpy(bufPtr,audioDecoded + audioDecodedCursor * sampleSize,chunk*sampleSize);
				bufPtr += chunk*sampleSize;
				work -= chunk;
				audioDecodedCursor += chunk;
			}

			if(!work)
				break;

			//if we are at the end of our audiostream, we can't read any more!
			if(encodeCursor == audioSampleCount)
			{
				//write silence
				memset(bufPtr,0,work*sampleSize);
				bAudioPaused = true;
				return;
			}

			audioReadChunk();
			acmStreamConvert(acmStream,&audioStreamHeader,0);
			lastDecodedSize = audioStreamHeader.cbDstLengthUsed / sampleSize;
			audioDecodedCursor = 0;
		}


	}
Esempio n. 9
0
static GstFlowReturn
acmmp3dec_finish_stream (ACMMP3Dec * dec)
{
  MMRESULT res;
  GstFlowReturn ret = GST_FLOW_OK;

  dec->header.cbSrcLength = 0;

  /* Flush out any remaining data internal to the decoder */
  res = acmStreamConvert (dec->stream, &dec->header,
      ACM_STREAMCONVERTF_BLOCKALIGN | ACM_STREAMCONVERTF_END);
  if (res) {
    GST_WARNING_OBJECT (dec, "Failed to decode data");
    return ret;
  }

  ret = acmmp3dec_push_output (dec);
  return ret;
}
Esempio n. 10
0
LRESULT CAcm::Convert(LPVOID lpDestBuf){
	//	ここでDirectSoundのLockしたメモリポインタを渡す

	if (!m_bOpen) {
		return 1;	//	Openできてへんのに呼ぶなっちゅーに!
	}
	m_acmheader.cbStruct		=	sizeof(m_acmheader);
	m_acmheader.pbSrc			=	(BYTE*)m_lpSrcBuf;
	m_acmheader.cbSrcLength		=	m_dwSrcLength;
	m_acmheader.pbDst			=	(BYTE*)lpDestBuf;		//	ここにコピーしたいねん!
	m_acmheader.cbDstLength		=	m_dwDestLength;
	if (acmStreamPrepareHeader(m_hAcm,&m_acmheader,NULL)!=0) {
		return 2;	//	勘弁して〜(笑)
	}

	if (acmStreamConvert(m_hAcm,&m_acmheader,NULL)!=0){
		return 3;	//	ダメじゃん(笑)
	}
	return 0;	//	任務終了
}
Esempio n. 11
0
void
acm_cv_convert (const converter_fmt_t *cfmt, u_char *state, sample *src_buf, int src_len, sample *dst_buf, int dst_len)
{
        ACMSTREAMHEADER ash;
        LPHACMSTREAM    lphs;

        UNUSED(cfmt);

        memset(&ash, 0, sizeof(ash));
        ash.cbStruct        = sizeof(ash);
        ash.pbSrc           = (LPBYTE)src_buf;
        ash.cbSrcLength     = src_len * sizeof(sample);
        ash.pbDst           = (LPBYTE)dst_buf;
        ash.cbDstLength     = dst_len * sizeof(sample);

        lphs = (LPHACMSTREAM)state;

        if (acmStreamPrepareHeader(*lphs, &ash, 0) ||
            acmStreamConvert(*lphs, &ash, ACM_STREAMCONVERTF_BLOCKALIGN)) {
                memset(dst_buf, 0, dst_len * sizeof(sample));
        }
        return;
}
Esempio n. 12
0
/// <summary>
/// <c>wACMStreamConvert</c> 
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="has"></param>
/// <param name="pash"></param>
/// <param name="fdwConvert"></param>
/// <returns>HRESULT __stdcall</returns>
HRESULT __stdcall 
wACMStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, ULONG fdwConvert)
{
	PSTR		pszErrorMessage;
	MMRESULT	hResult;

	InternalFunctionSpew("GameOS_DirectSound", "acmStreamConvert(0x%x, 0x%x, 0x%x)", has, pash, fdwConvert);
	hResult = acmStreamConvert(has, pash, fdwConvert);
	if (MMFAILED(hResult))
	{
		pszErrorMessage = ErrorNumberToMessage(hResult);
		//PAUSE(
		if ( InternalFunctionPause(
			"FAILED (0x%x - %s) - acmStreamConvert(0x%x, 0x%x, 0x%x)",
			hResult,
			pszErrorMessage,
			has,
			pash,
			fdwConvert) )
			ENTER_DEBUGGER;
	}
	return hResult;
}
Esempio n. 13
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
    ACMSTREAMHEADER ash;
    HRESULT hr;
    DWORD srcsize=0;
    DWORD len=minlen;
    acm_context_t *priv = sh_audio->context;

    acmStreamSize(priv->handle, len, &srcsize, ACM_STREAMSIZEF_DESTINATION);
    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm says: srcsize=%ld  (buffsize=%d)  out_size=%ld\n",srcsize,sh_audio->a_in_buffer_size,len);

    if(srcsize<sh_audio->wf->nBlockAlign){
       srcsize=sh_audio->wf->nBlockAlign;
       acmStreamSize(priv->handle, srcsize, &len, ACM_STREAMSIZEF_SOURCE);
       if(len>maxlen) len=maxlen;
    }

//    if(srcsize==0) srcsize=((WAVEFORMATEX *)&sh_audio->o_wf_ext)->nBlockAlign;
    if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!!
    if(sh_audio->a_in_buffer_len<srcsize){
      sh_audio->a_in_buffer_len+=
        demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len],
        srcsize-sh_audio->a_in_buffer_len);
    }
    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm convert %d -> %ld bytes\n",sh_audio->a_in_buffer_len,len);
    memset(&ash, 0, sizeof(ash));
    ash.cbStruct=sizeof(ash);
    ash.fdwStatus=0;
    ash.dwUser=0;
    ash.pbSrc=sh_audio->a_in_buffer;
    ash.cbSrcLength=sh_audio->a_in_buffer_len;
    ash.pbDst=buf;
    ash.cbDstLength=len;
    hr=acmStreamPrepareHeader(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamPrepareHeader error %d\n",(int)hr);
      return -1;
    }
    hr=acmStreamConvert(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_DBG2,"ACM_Decoder: acmStreamConvert error %d\n",(int)hr);
      switch(hr)
      {
	case ACMERR_NOTPOSSIBLE:
	case ACMERR_UNPREPARED:
	    mp_msg(MSGT_WIN32, MSGL_DBG2, "ACM_Decoder: acmStreamConvert error: probarly not initialized!\n");
      }
//      return -1;
    }
    mp_msg(MSGT_WIN32,MSGL_DBG2,"acm converted %ld -> %ld\n",ash.cbSrcLengthUsed,ash.cbDstLengthUsed);
    if(ash.cbSrcLengthUsed>=sh_audio->a_in_buffer_len){
      sh_audio->a_in_buffer_len=0;
    } else {
      sh_audio->a_in_buffer_len-=ash.cbSrcLengthUsed;
      memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[ash.cbSrcLengthUsed],sh_audio->a_in_buffer_len);
    }
    len=ash.cbDstLengthUsed;
    hr=acmStreamUnprepareHeader(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamUnprepareHeader error %d\n",(int)hr);
    }
    return len;
}
Esempio n. 14
0
void ConvertNode(HWND hwnd, AFile* node, const char* fname, WORD tag)
{
    FSHandle* file;
    HANDLE wavfile;
    RIFFHeader riffhdr;
	ChunkHeader chunkhdr;
    DWORD riffsize,factsize,datasize,written,rate,buffpos,pcmsize,dstsize,sizeToFill,sizeFilled;
	DWORD pos_riffsize,pos_factsize,pos_datasize;
    WORD  channels,bits;
    char  str[MAX_PATH+100],*pcmBuffer=NULL,*dstBuffer=NULL;
	LPWAVEFORMATEX pwfex;
	ACMFORMATTAGDETAILS aftd={0};
	MMRESULT mmr;
	WAVEFORMATEX wfexPCM;
	HACMSTREAM hACMStream;
	ACMSTREAMHEADER acmshdr;

    if ((file=FSOpenForPlayback(hwnd,node,&rate,&channels,&bits))==NULL)
		return;
	wfexPCM.wFormatTag=WAVE_FORMAT_PCM;
	wfexPCM.nChannels=channels;
	wfexPCM.nSamplesPerSec=rate;
	wfexPCM.wBitsPerSample=bits;
	wfexPCM.cbSize=0;
	wfexPCM.nBlockAlign=channels*(bits/8);
	wfexPCM.nAvgBytesPerSec=rate*wfexPCM.nBlockAlign;
	switch (tag)
	{
		case WAVE_FORMAT_PCM:
			pwfex=NULL; // ???
			hACMStream=NULL;
			dstBuffer=NULL; // ???
			pcmBuffer=(char*)GlobalAlloc(GPTR,BUFFERSIZE);
			break;
		default:
			aftd.cbStruct=sizeof(aftd);
			aftd.dwFormatTag=tag;
			mmr=acmFormatTagDetails(NULL,&aftd,ACM_FORMATTAGDETAILSF_LARGESTSIZE);
			if (mmr!=MMSYSERR_NOERROR)
			{
				AFPLUGIN(node)->ShutdownPlayback(file);
				FSCloseFile(file);
				wsprintf(str,"Failed to get details for wave format tag: 0x%X",tag);
				ReportMMError(hwnd,mmr,str);
				return;
			}
			pwfex=(LPWAVEFORMATEX)LocalAlloc(LPTR,aftd.cbFormatSize);
			pwfex->wFormatTag=tag;
			mmr=acmFormatSuggest(NULL,&wfexPCM,pwfex,aftd.cbFormatSize,ACM_FORMATSUGGESTF_WFORMATTAG);
			if (mmr!=MMSYSERR_NOERROR)
			{
				LocalFree(pwfex);
				AFPLUGIN(node)->ShutdownPlayback(file);
				FSCloseFile(file);
				wsprintf(str,"No format suggested for wave format tag: 0x%X",tag);
				ReportMMError(hwnd,mmr,str);
				return;
			}
			mmr=acmStreamOpen(&hACMStream,NULL,&wfexPCM,pwfex,NULL,0,0,ACM_STREAMOPENF_NONREALTIME);
			if (mmr!=MMSYSERR_NOERROR)
			{
				LocalFree(pwfex);
				AFPLUGIN(node)->ShutdownPlayback(file);
				FSCloseFile(file);
				wsprintf(str,"Failed to open conversion stream for wave format tag: 0x%X",tag);
				ReportMMError(hwnd,mmr,str);
				return;
			}
			if (acmStreamSize(hACMStream,BUFFERSIZE,&dstsize,ACM_STREAMSIZEF_SOURCE)!=MMSYSERR_NOERROR)
				dstsize=BUFFERSIZE;
			pcmBuffer=(char*)GlobalAlloc(GPTR,BUFFERSIZE);
			dstBuffer=(char*)GlobalAlloc(GPTR,dstsize);
			memset(&acmshdr,0x00,sizeof(acmshdr)); // ???
			acmshdr.cbStruct=sizeof(ACMSTREAMHEADER);
			acmshdr.fdwStatus=0;
			acmshdr.pbSrc=pcmBuffer;
			acmshdr.cbSrcLength=BUFFERSIZE;
			acmshdr.cbSrcLengthUsed=0;
			acmshdr.pbDst=dstBuffer;
			acmshdr.cbDstLength=dstsize;
			acmshdr.cbDstLengthUsed=0;
			mmr=acmStreamPrepareHeader(hACMStream,&acmshdr,0L);
			if (mmr!=MMSYSERR_NOERROR)
			{
				GlobalFree(dstBuffer);
				GlobalFree(pcmBuffer);
				acmStreamClose(hACMStream,0);
				LocalFree(pwfex);
				AFPLUGIN(node)->ShutdownPlayback(file);
				FSCloseFile(file);
				ReportMMError(hwnd,mmr,"Failed to prepare conversion stream header.");
				return;
			}
			acmshdr.cbSrcLength=0;
	}
	if (!EnsureDirPresence(fname))
	{
		if (hACMStream!=NULL)
		{
			acmStreamUnprepareHeader(hACMStream,&acmshdr,0L);
			acmStreamClose(hACMStream,0);
		}
		GlobalFree(dstBuffer);
		GlobalFree(pcmBuffer);
		LocalFree(pwfex);
		AFPLUGIN(node)->ShutdownPlayback(file);
		FSCloseFile(file);
		return;
	}
    wavfile=CreateFile(fname,
					   GENERIC_WRITE,
					   FILE_SHARE_READ,
					   NULL,
					   CREATE_ALWAYS,
					   FILE_ATTRIBUTE_NORMAL,
					   NULL
					  );
    if (wavfile==INVALID_HANDLE_VALUE)
    {
		if (hACMStream!=NULL)
		{
			acmStreamUnprepareHeader(hACMStream,&acmshdr,0L);
			acmStreamClose(hACMStream,0);
		}
		GlobalFree(dstBuffer);
		GlobalFree(pcmBuffer);
		LocalFree(pwfex);
		AFPLUGIN(node)->ShutdownPlayback(file);
		FSCloseFile(file);
		wsprintf(str,"Cannot open WAV file: %s",fname);
		ReportError(hwnd,str,NULL);
		return;
    }
    ShowProgressHeaderMsg(fname);
	datasize=0;
	factsize=0;
    ShowProgressStateMsg("Writing RIFF header...");
    SetFilePointer(wavfile,0,NULL,FILE_BEGIN);
    lstrcpy(riffhdr.riffid,IDSTR_RIFF);
    lstrcpy(riffhdr.rifftype,IDSTR_WAVE);
	riffhdr.riffsize=0;
	WriteFile(wavfile,&riffhdr,sizeof(RIFFHeader),&written,NULL);
	pos_riffsize=SetFilePointer(wavfile,0,NULL,FILE_CURRENT)-sizeof(riffhdr.rifftype)-sizeof(riffhdr.riffsize);
	CorrectOddPos(wavfile);
	ShowProgressStateMsg("Writing fmt chunk...");
    lstrcpy(chunkhdr.id,IDSTR_fmt);
	switch (tag)
	{
		case WAVE_FORMAT_PCM:
			chunkhdr.size=sizeof(wfexPCM);
			WriteFile(wavfile,&chunkhdr,sizeof(chunkhdr),&written,NULL);
			WriteFile(wavfile,&wfexPCM,chunkhdr.size,&written,NULL);
			CorrectOddPos(wavfile);
			break;
		default:
			chunkhdr.size=aftd.cbFormatSize;
			WriteFile(wavfile,&chunkhdr,sizeof(chunkhdr),&written,NULL);
			WriteFile(wavfile,pwfex,chunkhdr.size,&written,NULL);
			CorrectOddPos(wavfile);
			lstrcpy(chunkhdr.id,IDSTR_fact);
			chunkhdr.size=sizeof(factsize);
			WriteFile(wavfile,&chunkhdr,sizeof(chunkhdr),&written,NULL);
			pos_factsize=SetFilePointer(wavfile,0,NULL,FILE_CURRENT);
			WriteFile(wavfile,&factsize,sizeof(factsize),&written,NULL);
			CorrectOddPos(wavfile);
	}
    lstrcpy(chunkhdr.id,IDSTR_data);
	chunkhdr.size=datasize;
	WriteFile(wavfile,&chunkhdr,sizeof(chunkhdr),&written,NULL);
	pos_datasize=SetFilePointer(wavfile,0,NULL,FILE_CURRENT)-sizeof(datasize);
    while (1)
    {
		if (IsCancelled())
			break;
		switch (tag)
		{
			case WAVE_FORMAT_PCM:
				sizeToFill=BUFFERSIZE;
				sizeFilled=0;
				break;
			default:
				if (acmshdr.cbSrcLengthUsed!=0L)
				{
					memmove(pcmBuffer,pcmBuffer+acmshdr.cbSrcLengthUsed,acmshdr.cbSrcLength-acmshdr.cbSrcLengthUsed);
					acmshdr.cbSrcLength-=acmshdr.cbSrcLengthUsed;
				}
				if (acmshdr.cbSrcLength<BUFFERSIZE)
					sizeToFill=BUFFERSIZE-acmshdr.cbSrcLength;
				sizeFilled=acmshdr.cbSrcLength;
		}
		wsprintf(str,"Converting %s data block to PCM...",file->node->afID);
		ShowProgressStateMsg(str);
		pcmsize=0;
		if (sizeToFill>0)
			pcmsize=AFPLUGIN(node)->FillPCMBuffer(file,pcmBuffer+sizeFilled,sizeToFill,&buffpos);
		if (tag==WAVE_FORMAT_PCM)
		{
			if (pcmsize==0L)
				break;
			ShowProgressStateMsg("Writing WAV data block...");
			WriteFile(wavfile,pcmBuffer,pcmsize,&written,NULL);
			if (written!=pcmsize)
			{
				ReportError(hwnd,"Failure writing WAV file.",NULL);
				SetCancelFlag();
				break;
			}
			datasize+=written;
		}
		else
		{
			acmshdr.cbSrcLength+=pcmsize;
			if (acmshdr.cbSrcLength==0L)
				break;
			acmshdr.fdwStatus^=ACMSTREAMHEADER_STATUSF_DONE;
			acmshdr.cbSrcLengthUsed=0;
			acmshdr.cbDstLength=dstsize;
			acmshdr.cbDstLengthUsed=0;
			wsprintf(str,"Compressing PCM data block...");
			ShowProgressStateMsg(str);
			mmr=acmStreamConvert(hACMStream,&acmshdr,ACM_STREAMCONVERTF_BLOCKALIGN);
			if (mmr!=MMSYSERR_NOERROR)
			{
				CloseHandle(wavfile);
				DeleteFile(fname);
				acmStreamUnprepareHeader(hACMStream,&acmshdr,0L);
				acmStreamClose(hACMStream,0);
				GlobalFree(dstBuffer);
				GlobalFree(pcmBuffer);
				LocalFree(pwfex);
				AFPLUGIN(node)->ShutdownPlayback(file);
				FSCloseFile(file);
				ReportMMError(hwnd,mmr,"Error during compression.");
				return;
			}
			if (acmshdr.cbSrcLengthUsed==0L)
			{
				acmshdr.fdwStatus^=ACMSTREAMHEADER_STATUSF_DONE;
				acmStreamConvert(hACMStream,&acmshdr,0L);
			}
			factsize+=acmshdr.cbSrcLengthUsed/wfexPCM.nBlockAlign;
			ShowProgressStateMsg("Writing WAV data block...");
			WriteFile(wavfile,dstBuffer,acmshdr.cbDstLengthUsed,&written,NULL);
			if (written!=acmshdr.cbDstLengthUsed)
			{
				ReportError(hwnd,"Failure writing WAV file.",NULL);
				SetCancelFlag();
				break;
			}
			datasize+=written;
		}
		ShowProgress(FSGetFilePointer(file),FSGetFileSize(file)); // ???
    }
    if (IsCancelled())
    {
		ShowProgressStateMsg("Deleting WAV file...");
		CloseHandle(wavfile);
		DeleteFile(fname);
    }
    else
    {
		CorrectOddPos(wavfile);
		ShowProgressStateMsg("Rewriting WAV header...");
		riffsize=GetFileSize(wavfile,NULL)-8;
		SetFilePointer(wavfile,pos_riffsize,NULL,FILE_BEGIN);
		WriteFile(wavfile,&riffsize,sizeof(riffsize),&written,NULL);
		if (tag!=WAVE_FORMAT_PCM)
		{
			SetFilePointer(wavfile,pos_factsize,NULL,FILE_BEGIN);
			WriteFile(wavfile,&factsize,sizeof(factsize),&written,NULL);
		}
		SetFilePointer(wavfile,pos_datasize,NULL,FILE_BEGIN);
		WriteFile(wavfile,&datasize,sizeof(datasize),&written,NULL);
		CloseHandle(wavfile);
    }
	if (hACMStream!=NULL)
	{
		ShowProgressStateMsg("Closing conversion stream...");
		acmStreamUnprepareHeader(hACMStream,&acmshdr,0L);
		acmStreamClose(hACMStream,0);
	}
	ShowProgressStateMsg("Freeing conversion buffers...");
	GlobalFree(dstBuffer);
	GlobalFree(pcmBuffer);
	LocalFree(pwfex);
	wsprintf(str,"Shutting down %s decoder...",file->node->afID);
    ShowProgressStateMsg(str);
    AFPLUGIN(node)->ShutdownPlayback(file);
	FSCloseFile(file);
}
Esempio n. 15
0
int ToMP3(short *Source, short *Dest, int Size, int BitRate)
{
    int Src_size;
    int Dest_Size;

    Wave_Format.wFormatTag = WAVE_FORMAT_PCM;
    Wave_Format.nChannels = 1;
    Wave_Format.cbSize = 0;
    Wave_Format.wBitsPerSample = 16;
    Wave_Format.nSamplesPerSec = 44100;
    Wave_Format.nBlockAlign = Wave_Format.nChannels * Wave_Format.wBitsPerSample / 8;
    Wave_Format.nAvgBytesPerSec = Wave_Format.nSamplesPerSec * Wave_Format.nBlockAlign;

    MP3_Format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
    MP3_Format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
    MP3_Format.wfx.nChannels = 1;
    MP3_Format.wfx.nSamplesPerSec = 44100;
    MP3_Format.wfx.nAvgBytesPerSec = BitRate * (1000 / 8);
    MP3_Format.wfx.wBitsPerSample = 0;
    MP3_Format.wfx.nBlockAlign = 1;
    MP3_Format.wID = MPEGLAYER3_ID_MPEG;
    MP3_Format.fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
    MP3_Format.nBlockSize = 0;
    MP3_Format.nFramesPerBlock = 0;
    MP3_Format.nCodecDelay = 0;

    acmStreamOpen(&Pack_Stream, NULL, (LPWAVEFORMATEX) &Wave_Format, (LPWAVEFORMATEX) &MP3_Format, NULL, 0, 0, 0);

    Src_size = Size;
    unsigned long rawbufsize = 0;
    acmStreamSize(Pack_Stream, Src_size, &rawbufsize, ACM_STREAMSIZEF_SOURCE);
    rawbufsize += MP3_FRAMES_LAG * 2;
    Uint8 *Pack_Buf = (Uint8 *) malloc(Src_size + (MP3_FRAMES_LAG * 4) + 8);
    memset(Pack_Buf, 0, Src_size + (MP3_FRAMES_LAG * 4) + 8);
    Uint8 *rawbuf = (Uint8 *) malloc(rawbufsize + (MP3_FRAMES_LAG * 4) + 8);
    memset(rawbuf, 0, rawbufsize + (MP3_FRAMES_LAG * 4) + 8);

    ACMSTREAMHEADER Pack_Stream_Head;
    ZeroMemory(&Pack_Stream_Head, sizeof(ACMSTREAMHEADER));
    Pack_Stream_Head.cbStruct = sizeof(ACMSTREAMHEADER);
    Pack_Stream_Head.pbSrc = (Uint8 *) Pack_Buf;
    Pack_Stream_Head.cbSrcLength = Src_size + (MP3_FRAMES_LAG * 2);
    Pack_Stream_Head.pbDst = rawbuf;
    Pack_Stream_Head.cbDstLength = rawbufsize;
    acmStreamPrepareHeader(Pack_Stream, &Pack_Stream_Head, 0);

    memcpy(Pack_Buf, Source, Src_size);

    acmStreamConvert(Pack_Stream, &Pack_Stream_Head, 0);
    Dest_Size = Pack_Stream_Head.cbDstLengthUsed;
    if(Dest_Size < Src_size)
    {
        memcpy(Dest, rawbuf, Dest_Size);
    }
    else
    {
        Dest_Size = 0;
    }

    acmStreamUnprepareHeader(Pack_Stream, &Pack_Stream_Head, 0);
    acmStreamClose(Pack_Stream, 0);
    if(rawbuf) free(rawbuf);
    if(Pack_Buf) free(Pack_Buf);

    return(Dest_Size);
}
ConvertOutput AudioConverterStream::Convert(const BYTE* inBuffer, int inSize)
{
    if (isProxy)
    {
        // Source and destination formats are identical, so just pass the input through to the output
        ConvertOutput rv = { const_cast<BYTE*>(inBuffer), inSize };
        return rv;
    }

    outSize = 0;
    int prevSrcLength = header.cbSrcLength;
    int usedInSize = 0;

    while (inSize + startOffset)
    {
        int curInSize = std::min(inSize, static_cast<int>(sizeof(inWorkBuffer) - startOffset));
        memcpy(inWorkBuffer + startOffset, inBuffer + usedInSize, curInSize);
        usedInSize += curInSize;
        inSize -= curInSize;
        header.cbSrcLength = curInSize + startOffset;
        MMRESULT mm = acmStreamConvert(stream, &header, ACM_STREAMCONVERTF_BLOCKALIGN);

        if (mm != MMSYSERR_NOERROR)
        {
            m_failed = true;
            break;
        }

        // Append to output
        int prevOutSize = outSize;
        outSize += header.cbDstLengthUsed;
        ReserveOutBuffer(outSize);
        memcpy(outBuffer + prevOutSize, outWorkBuffer, header.cbDstLengthUsed);

        // Recycle unused input
        startOffset = header.cbSrcLength - header.cbSrcLengthUsed;

        // startOffset = number of leftover bytes
        if (startOffset > 0 && header.cbSrcLengthUsed)
        {
            memmove(inWorkBuffer, inWorkBuffer + header.cbSrcLengthUsed, startOffset);
        }

        if (header.cbDstLengthUsed == 0 && header.cbSrcLengthUsed == 0)
        {
            break;
        }
    }

    header.cbSrcLength = prevSrcLength;

    if (header.cbDstLengthUsed == 0 && header.cbSrcLengthUsed == 0 && startOffset == sizeof(inWorkBuffer))
    {
        m_failed = true;
    }

    if (subConverter)
    {
        return subConverter->Convert(outBuffer, outSize);
    }

    ConvertOutput rv = { outBuffer, outSize };
    return rv;
}
Esempio n. 17
0
static HRESULT WINAPI ACMWrapper_Receive(TransformFilter *tf, IMediaSample *pSample)
{
    ACMWrapperImpl* This = (ACMWrapperImpl*)tf;
    AM_MEDIA_TYPE amt;
    IMediaSample* pOutSample = NULL;
    DWORD cbDstStream, cbSrcStream;
    LPBYTE pbDstStream;
    LPBYTE pbSrcStream = NULL;
    ACMSTREAMHEADER ash;
    BOOL unprepare_header = FALSE, preroll;
    MMRESULT res;
    HRESULT hr;
    LONGLONG tStart = -1, tStop = -1, tMed;

    EnterCriticalSection(&This->tf.filter.csFilter);
    hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
    if (FAILED(hr))
    {
        ERR("Cannot get pointer to sample data (%x)\n", hr);
        LeaveCriticalSection(&This->tf.filter.csFilter);
        return hr;
    }

    preroll = (IMediaSample_IsPreroll(pSample) == S_OK);

    IMediaSample_GetTime(pSample, &tStart, &tStop);
    cbSrcStream = IMediaSample_GetActualDataLength(pSample);

    /* Prevent discontinuities when codecs 'absorb' data but not give anything back in return */
    if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
    {
        This->lasttime_real = tStart;
        This->lasttime_sent = tStart;
    }
    else if (This->lasttime_real == tStart)
        tStart = This->lasttime_sent;
    else
        WARN("Discontinuity\n");

    tMed = tStart;

    TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream);

    hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
    if (FAILED(hr))
    {
        ERR("Unable to retrieve media type\n");
        LeaveCriticalSection(&This->tf.filter.csFilter);
        return hr;
    }

    ash.pbSrc = pbSrcStream;
    ash.cbSrcLength = cbSrcStream;

    while(hr == S_OK && ash.cbSrcLength)
    {
        hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0);
        if (FAILED(hr))
        {
            ERR("Unable to get delivery buffer (%x)\n", hr);
            LeaveCriticalSection(&This->tf.filter.csFilter);
            return hr;
        }
        IMediaSample_SetPreroll(pOutSample, preroll);

	hr = IMediaSample_SetActualDataLength(pOutSample, 0);
	assert(hr == S_OK);

	hr = IMediaSample_GetPointer(pOutSample, &pbDstStream);
	if (FAILED(hr)) {
	    ERR("Unable to get pointer to buffer (%x)\n", hr);
	    goto error;
	}
	cbDstStream = IMediaSample_GetSize(pOutSample);

	ash.cbStruct = sizeof(ash);
	ash.fdwStatus = 0;
	ash.dwUser = 0;
	ash.pbDst = pbDstStream;
	ash.cbDstLength = cbDstStream;

	if ((res = acmStreamPrepareHeader(This->has, &ash, 0))) {
	    ERR("Cannot prepare header %d\n", res);
	    goto error;
	}
	unprepare_header = TRUE;

        if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
        {
            res = acmStreamConvert(This->has, &ash, ACM_STREAMCONVERTF_START);
            IMediaSample_SetDiscontinuity(pOutSample, TRUE);
            /* One sample could be converted to multiple packets */
            IMediaSample_SetDiscontinuity(pSample, FALSE);
        }
        else
        {
            res = acmStreamConvert(This->has, &ash, 0);
            IMediaSample_SetDiscontinuity(pOutSample, FALSE);
        }

        if (res)
        {
            if(res != MMSYSERR_MOREDATA)
                ERR("Cannot convert data header %d\n", res);
            goto error;
        }

        TRACE("used in %u/%u, used out %u/%u\n", ash.cbSrcLengthUsed, ash.cbSrcLength, ash.cbDstLengthUsed, ash.cbDstLength);

        hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed);
        assert(hr == S_OK);

        /* Bug in acm codecs? It apparantly uses the input, but doesn't necessarily output immediately kl*/
        if (!ash.cbSrcLengthUsed)
        {
            WARN("Sample was skipped? Outputted: %u\n", ash.cbDstLengthUsed);
            ash.cbSrcLength = 0;
            goto error;
        }

        TRACE("Sample start time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000));
        if (ash.cbSrcLengthUsed == cbSrcStream)
        {
            IMediaSample_SetTime(pOutSample, &tStart, &tStop);
            tStart = tMed = tStop;
        }
        else if (tStop != tStart)
        {
            tMed = tStop - tStart;
            tMed = tStart + tMed * ash.cbSrcLengthUsed / cbSrcStream;
            IMediaSample_SetTime(pOutSample, &tStart, &tMed);
            tStart = tMed;
        }
        else
        {
            ERR("No valid timestamp found\n");
            IMediaSample_SetTime(pOutSample, NULL, NULL);
        }
        TRACE("Sample stop time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000));

        LeaveCriticalSection(&This->tf.filter.csFilter);
        hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample);
        EnterCriticalSection(&This->tf.filter.csFilter);

        if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
            if (FAILED(hr))
                ERR("Error sending sample (%x)\n", hr);
            goto error;
        }

error:
        if (unprepare_header && (res = acmStreamUnprepareHeader(This->has, &ash, 0)))
            ERR("Cannot unprepare header %d\n", res);
        unprepare_header = FALSE;
        ash.pbSrc += ash.cbSrcLengthUsed;
        ash.cbSrcLength -= ash.cbSrcLengthUsed;

        if (pOutSample)
            IMediaSample_Release(pOutSample);
        pOutSample = NULL;

    }

    This->lasttime_real = tStop;
    This->lasttime_sent = tMed;

    LeaveCriticalSection(&This->tf.filter.csFilter);
    return hr;
}
Esempio n. 18
0
int ToAT3(short *Source, short *Dest, int Size, int BitRate)
{
    int Src_size;
    int Dest_Size;
    int i;

    Wave_Format.wFormatTag = WAVE_FORMAT_PCM;
    Wave_Format.nChannels = 2;
    Wave_Format.cbSize = 0;
    Wave_Format.wBitsPerSample = 16;
    Wave_Format.nSamplesPerSec = 44100;
    Wave_Format.nBlockAlign = Wave_Format.nChannels * Wave_Format.wBitsPerSample / 8;
    Wave_Format.nAvgBytesPerSec = Wave_Format.nSamplesPerSec * Wave_Format.nBlockAlign;

    At3_Format.wfx.wFormatTag = 0x270;
    At3_Format.wfx.nChannels = 2;
    At3_Format.wfx.nSamplesPerSec = 44100;
    At3_Format.wfx.nAvgBytesPerSec = BitRate * 125;
    switch(BitRate)
    {
        case 66:
            At3_Format.wfx.nBlockAlign = 192;
            break;

        case 105:
            At3_Format.wfx.nBlockAlign = 304;
            break;

        case 132:
            At3_Format.wfx.nBlockAlign = 384;
            break;
    }
    At3_Format.wfx.wBitsPerSample = 0;
    At3_Format.wfx.cbSize = 0xe;
    At3_Format.wRevision = 1;
    At3_Format.nSamplesPerBlock = 0x800;
    At3_Format.abReserved[2] = 1;
    At3_Format.abReserved[4] = 1;
    At3_Format.abReserved[6] = 1;
    acmStreamOpen(&Pack_Stream, NULL, (LPWAVEFORMATEX) &Wave_Format, (LPWAVEFORMATEX) &At3_Format, NULL, 0, 0, 0);

    short *dwSource = (short *) malloc(Size * 2 + 8);
    memset(dwSource, 0, Size * 2 + 8);
    for(i = 0; i < Size / 2; i++)
    {
        dwSource[(i * 2)] = Source[i];
        dwSource[(i * 2) + 1] = 0;
    }

    Source = dwSource;
    Size *= 2;

    Src_size = Size;
    unsigned long rawbufsize = 0;
    acmStreamSize(Pack_Stream, Src_size, &rawbufsize, ACM_STREAMSIZEF_SOURCE);
    Uint8 *Pack_Buf = (Uint8 *) malloc(Src_size + 8);
    memset(Pack_Buf, 0, Src_size + 8);
    Uint8 *rawbuf = (Uint8 *) malloc(rawbufsize + 8);
    memset(rawbuf, 0, rawbufsize + 8);

    ACMSTREAMHEADER Pack_Stream_Head;
    ZeroMemory(&Pack_Stream_Head, sizeof(ACMSTREAMHEADER));
    Pack_Stream_Head.cbStruct = sizeof(ACMSTREAMHEADER);
    Pack_Stream_Head.pbSrc = (Uint8 *) Pack_Buf;
    Pack_Stream_Head.cbSrcLength = Src_size;
    Pack_Stream_Head.pbDst = rawbuf;
    Pack_Stream_Head.cbDstLength = rawbufsize;
    acmStreamPrepareHeader(Pack_Stream, &Pack_Stream_Head, 0);

    memcpy(Pack_Buf, Source, Src_size);

    acmStreamConvert(Pack_Stream, &Pack_Stream_Head, 0);
    Dest_Size = Pack_Stream_Head.cbDstLengthUsed;
    if(Dest_Size < Src_size)
    {
        memcpy(Dest, rawbuf, Dest_Size);
    }
    else
    {
        Dest_Size = 0;
    }

    acmStreamUnprepareHeader(Pack_Stream, &Pack_Stream_Head, 0);
    if(rawbuf) free(rawbuf);
    if(Pack_Buf) free(Pack_Buf);
    if(dwSource) free(dwSource);
    acmStreamClose(Pack_Stream, 0);

    return(Dest_Size);
}
Esempio n. 19
0
static HRESULT WINAPI ACMStream_fnWrite(IAVIStream *iface, LONG start,
					 LONG samples, LPVOID buffer,
					 LONG buffersize, DWORD flags,
					 LPLONG sampwritten,
					 LPLONG byteswritten)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  HRESULT hr;
  ULONG   size;

  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
	buffer, buffersize, flags, sampwritten, byteswritten);

  /* clear return parameters if given */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  /* check parameters */
  if (buffer == NULL && (buffersize > 0 || samples > 0))
    return AVIERR_BADPARAM;

  /* Have we write capability? */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  /* also need a compressor */
  if (This->has == NULL)
    return AVIERR_NOCOMPRESSOR;

  /* map our sizes to pStream sizes */
  size = buffersize;
  CONVERT_THIS_to_STREAM(&size);
  CONVERT_THIS_to_STREAM(&start);

  /* no bytes to write? -- short circuit */
  if (size == 0) {
    return IAVIStream_Write(This->pStream, -1, samples, buffer, size,
			    flags, sampwritten, byteswritten);
  }

  /* Need to free source buffer used for reading? */
  if (This->acmStreamHdr.pbSrc != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc);
    This->acmStreamHdr.pbSrc     = NULL;
    This->acmStreamHdr.dwSrcUser = 0;
  }

  /* Need bigger destination buffer? */
  if (This->acmStreamHdr.pbDst == NULL ||
      This->acmStreamHdr.dwDstUser < size) {
    if (This->acmStreamHdr.pbDst == NULL)
      This->acmStreamHdr.pbDst = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbDst = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbDst, size);
    if (This->acmStreamHdr.pbDst == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwDstUser = size;
  }
  This->acmStreamHdr.cbStruct        = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbDstLength     = This->acmStreamHdr.dwDstUser;

  /* need to prepare stream? */
  This->acmStreamHdr.pbSrc       = buffer;
  This->acmStreamHdr.cbSrcLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbSrc       = NULL;
      This->acmStreamHdr.cbSrcLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;
  else
    hr = AVIERR_OK;

  This->acmStreamHdr.pbSrc       = NULL;
  This->acmStreamHdr.cbSrcLength = 0;

  if (FAILED(hr))
    return hr;

  return IAVIStream_Write(This->pStream,-1,This->acmStreamHdr.cbDstLengthUsed /
			  This->lpOutFormat->nBlockAlign,This->acmStreamHdr.pbDst,
			  This->acmStreamHdr.cbDstLengthUsed,flags,sampwritten,
			  byteswritten);
}
Esempio n. 20
0
static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
{
    ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
    AM_MEDIA_TYPE amt;
    HRESULT hr;
    IMediaSample* pSample = NULL;
    DWORD cbDstStream;
    LPBYTE pbDstStream;
    ACMSTREAMHEADER ash;
    DWORD offset = 0;
    BOOL stop = FALSE;
    BOOL unprepare_header = FALSE;
    MMRESULT res;

    TRACE("(%p)->(%p,%ld)\n", This, data, size);

    hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
    if (FAILED(hr)) {
	ERR("Unable to retrieve media type\n");
	goto error;
    }

    while(!stop)
    {
	DWORD rem_buf = This->max_size - This->current_size;
	DWORD rem_smp = size - offset;
	DWORD copy_size = min(rem_buf, rem_smp);

	memcpy(This->buffer + This->current_size, data + offset, copy_size);
	This->current_size += copy_size;
	offset += copy_size;

	if (offset == size)
	    stop = TRUE;
	if (This->current_size < This->max_size)
	    break;
  
	hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pSample, NULL, NULL, 0);
	if (FAILED(hr)) {
	    ERR("Unable to get delivery buffer (%lx)\n", hr);
	    goto error;
	}

	hr = IMediaSample_SetActualDataLength(pSample, 0);
	assert(hr == S_OK);

	hr = IMediaSample_GetPointer(pSample, &pbDstStream);
	if (FAILED(hr)) {
	    ERR("Unable to get pointer to buffer (%lx)\n", hr);
	    goto error;
	}
	cbDstStream = IMediaSample_GetSize(pSample);

	ash.cbStruct = sizeof(ash);
	ash.fdwStatus = 0;
	ash.dwUser = 0;
	ash.pbSrc = This->buffer;
	ash.cbSrcLength = This->current_size;
	ash.pbDst = pbDstStream;
	ash.cbDstLength = cbDstStream;

	if ((res = acmStreamPrepareHeader(This->has, &ash, 0))) {
	    ERR("Cannot prepare header %d\n", res);
	    goto error;
	}

	unprepare_header = TRUE;

	if ((res = acmStreamConvert(This->has, &ash, This->reinit_codec ? ACM_STREAMCONVERTF_START : 0))) {
	    ERR("Cannot convert data header %d\n", res);
	    goto error;
	}
	This->reinit_codec = FALSE;

	TRACE("used in %lu, used out %lu\n", ash.cbSrcLengthUsed, ash.cbDstLengthUsed);

	hr = IMediaSample_SetActualDataLength(pSample, ash.cbDstLengthUsed);
	assert(hr == S_OK);

	if (ash.cbSrcLengthUsed < ash.cbSrcLength) {
	    This->current_size = ash.cbSrcLength - ash.cbSrcLengthUsed;
	    memmove(This->buffer, This->buffer + ash.cbSrcLengthUsed, This->current_size);
	}
	else
	    This->current_size = 0;

	hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pSample);
	if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
	    ERR("Error sending sample (%lx)\n", hr);
	    goto error;
        }

error:
	if (unprepare_header && (res = acmStreamUnprepareHeader(This->has, &ash, 0)))
	    ERR("Cannot unprepare header %d\n", res);

	if (pSample)
	    IMediaSample_Release(pSample);
    }

    return hr;
}
Esempio n. 21
0
BOOL ClSoundDS::AddSoundBuffer(int handle,char *fileBuf,BOOL b3DSound)
{
	HRESULT			hr;
	RiffHead		riffHead;
	FmtHead			fmtHead;
	PCMWAVEFORMAT	pcmFormat;

	LPBYTE			lpBlockAdd1, lpBlockAdd2;
	DWORD			blockSize1, blockSize2;

	CopyMemory(&riffHead,fileBuf,sizeof(RiffHead));
	fileBuf += sizeof(RiffHead);
	if(strncmp(riffHead.riff,"RIFF",4) || strncmp(riffHead.type,"WAVE",4)){
		return FALSE;
	}
	if(NULL==lpDSBufferTop){
		lpDSBufferTop = lpDSBufferTail = new ClSoundBuffer;
	}else{
		lpDSBufferTail->lpNext = new ClSoundBuffer;
		lpDSBufferTail->lpNext->lpPrev = lpDSBufferTail;
		lpDSBufferTail = lpDSBufferTail->lpNext;
	}
	lpDSBufferTail->bufType = memory_sound;
	CopyMemory(&fmtHead,fileBuf,sizeof(FmtHead));
	fileBuf += sizeof(FmtHead);
	CopyMemory(&pcmFormat,fileBuf,sizeof(PCMWAVEFORMAT));
	if(pcmFormat.wf.wFormatTag == WAVE_FORMAT_PCM){
		fileBuf += fmtHead.size;
		CopyMemory(&fmtHead,fileBuf,sizeof(FmtHead));
		fileBuf += sizeof(FmtHead);
		while(0!=strncmp(fmtHead.fmt,"data",4)){
			fileBuf += fmtHead.size;
			CopyMemory(&fmtHead,fileBuf,sizeof(FmtHead));
			fileBuf += sizeof(FmtHead);
		}
		DSBUFFERDESC	dsbdesc;
		WAVEFORMATEX	audioFmt;
		ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
		dsbdesc.dwSize = sizeof(DSBUFFERDESC);
		dsbdesc.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS;
		if(b3DSound) dsbdesc.dwFlags |= (DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE);
		dsbdesc.dwBufferBytes = fmtHead.size;
		CopyMemory(&audioFmt,&pcmFormat,sizeof(WAVEFORMAT));
		audioFmt.wBitsPerSample = pcmFormat.wBitsPerSample;
		audioFmt.cbSize = 0;
		dsbdesc.lpwfxFormat = &audioFmt;
		hr = lpDSound->CreateSoundBuffer(&dsbdesc, &lpTmpBuffer, NULL);
		lpTmpBuffer->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID *)&lpDSBufferTail->lpDSBuffer);
		RELEASE(lpTmpBuffer);
		hr = lpDSBufferTail->lpDSBuffer->Lock(0,fmtHead.size, (LPVOID*)&lpBlockAdd1, &blockSize1,(LPVOID*)&lpBlockAdd2, &blockSize2, 0);
		if(DS_OK==hr){
			CopyMemory(lpBlockAdd1,fileBuf,blockSize1);
			if(fmtHead.size>blockSize1){
				CopyMemory(lpBlockAdd2,fileBuf+blockSize1,blockSize2);
			}
			lpDSBufferTail->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
		}
		lpDSBufferTail->handle = handle;
	}else{
		WAVEFORMATEX	dstWF;
		WAVEFORMATEX	*pwfxInfo;
		WORD			cbExtraAlloc;
		MMRESULT		mmResult;
		fileBuf += sizeof(PCMWAVEFORMAT);
		CopyMemory(&cbExtraAlloc,fileBuf,sizeof(WORD));
		fileBuf += sizeof(WORD);
		pwfxInfo = (WAVEFORMATEX *)cl_malloc(sizeof(WAVEFORMATEX) +cbExtraAlloc);
		CopyMemory(pwfxInfo,&pcmFormat,sizeof(PCMWAVEFORMAT));
		pwfxInfo->cbSize = cbExtraAlloc;
		CopyMemory((char *)pwfxInfo +sizeof(WAVEFORMATEX),fileBuf,cbExtraAlloc);
		fileBuf += (fmtHead.size -sizeof(WAVEFORMATEX));
		CopyMemory(&fmtHead,fileBuf,sizeof(FmtHead));
		fileBuf += sizeof(FmtHead);
		while(0!=strncmp(fmtHead.fmt,"data",4)){
			fileBuf += fmtHead.size;
			CopyMemory(&fmtHead,fileBuf,sizeof(FmtHead));
			fileBuf += sizeof(FmtHead);
		}
		ZeroMemory(&dstWF,sizeof(dstWF));
		dstWF.wFormatTag = WAVE_FORMAT_PCM;
		mmResult = acmFormatSuggest(
			NULL,
			pwfxInfo,
			&dstWF,
			sizeof(dstWF),
			ACM_FORMATSUGGESTF_WFORMATTAG);
		if(mmResult != 0){
			myOutputDebugString("オーディオ圧縮が無効です\n");
			return FALSE;
		}
		HACMSTREAM				hAcm = NULL;
		ACMSTREAMHEADER			ash;
		AcmBuffer				acmDst;
		AcmBuffer				acmSrc;

		acmStreamOpen(&hAcm, NULL,pwfxInfo,&dstWF, NULL, 0L, 0L, ACM_STREAMOPENF_NONREALTIME);
		acmSrc.dwStreamSize = fmtHead.size;
		acmStreamSize(hAcm, acmSrc.dwStreamSize, &acmDst.dwStreamSize, ACM_STREAMSIZEF_SOURCE);
		cl_free(pwfxInfo);
		acmSrc.lpStream = (LPBYTE)cl_malloc(acmSrc.dwStreamSize);
		acmDst.lpStream = (LPBYTE)cl_malloc(acmDst.dwStreamSize);
		ZeroMemory(&ash,sizeof(ash));
		ash.cbStruct		= sizeof(ash);
		ash.pbSrc			= acmSrc.lpStream;
		ash.cbSrcLength		= acmSrc.dwStreamSize;
		ash.dwSrcUser		= acmSrc.dwStreamSize;
		ash.pbDst			= acmDst.lpStream;
		ash.cbDstLength		= acmDst.dwStreamSize;
		ash.dwDstUser		= acmDst.dwStreamSize;
		acmStreamPrepareHeader(hAcm,&ash,0);
		CopyMemory(acmSrc.lpStream,fileBuf,acmSrc.dwStreamSize);
		MMRESULT nError = acmStreamConvert(hAcm,&ash, ACM_STREAMCONVERTF_BLOCKALIGN);
		DSBUFFERDESC	dsbdesc;
		ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
		dsbdesc.dwSize = sizeof(DSBUFFERDESC);
		dsbdesc.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE | DSBCAPS_GLOBALFOCUS;
		if(b3DSound) dsbdesc.dwFlags |= (DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE);
		dsbdesc.dwBufferBytes = ash.cbDstLengthUsed;
		dsbdesc.lpwfxFormat = &dstWF;
		hr = lpDSound->CreateSoundBuffer(&dsbdesc, &lpTmpBuffer, NULL);
		lpTmpBuffer->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID *)&lpDSBufferTail->lpDSBuffer);
		RELEASE(lpTmpBuffer);
		hr = lpDSBufferTail->lpDSBuffer->Lock(0,ash.cbDstLengthUsed, (LPVOID*)&lpBlockAdd1, &blockSize1,(LPVOID*)&lpBlockAdd2, &blockSize2, 0);
		if(DS_OK==hr){
			if(ash.cbDstLengthUsed < blockSize1){
				CopyMemory(lpBlockAdd1, acmDst.lpStream, ash.cbDstLengthUsed);
				ZeroMemory(lpBlockAdd1 +ash.cbDstLengthUsed, blockSize1 -ash.cbDstLengthUsed);
				if(blockSize2)ZeroMemory(lpBlockAdd2,blockSize2);
			}else{
				CopyMemory(lpBlockAdd1, acmDst.lpStream, blockSize1);
				if(blockSize2){
					CopyMemory(lpBlockAdd2, acmDst.lpStream+blockSize1, ash.cbDstLengthUsed -blockSize1);
				}
			}
			lpDSBufferTail->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
		}
		if(hAcm){
			acmStreamUnprepareHeader(hAcm,&ash,0);
			acmStreamClose(hAcm,0);
			cl_free(acmSrc.lpStream);
			cl_free(acmDst.lpStream);
		}
		lpDSBufferTail->handle = handle;
	}
	return TRUE;
} // ClSoundDS::AddSoundBuffer
Esempio n. 22
0
static void test_prepareheader(void)
{
    HACMSTREAM has;
    ADPCMWAVEFORMAT *src;
    WAVEFORMATEX dst;
    MMRESULT mr;
    ACMSTREAMHEADER hdr;
    BYTE buf[sizeof(WAVEFORMATEX) + 32], pcm[2048], input[512];
    ADPCMCOEFSET *coef;

    src = (ADPCMWAVEFORMAT*)buf;
    coef = src->aCoef;
    src->wfx.cbSize = 32;
    src->wfx.wFormatTag = WAVE_FORMAT_ADPCM;
    src->wfx.nSamplesPerSec = 22050;
    src->wfx.wBitsPerSample = 4;
    src->wfx.nChannels = 1;
    src->wfx.nBlockAlign = 512;
    src->wfx.nAvgBytesPerSec = 11025;
    src->wSamplesPerBlock = 0x3f4;
    src->wNumCoef = 7;
    coef[0].iCoef1 = 0x0100;
    coef[0].iCoef2 = 0x0000;
    coef[1].iCoef1 = 0x0200;
    coef[1].iCoef2 = 0xff00;
    coef[2].iCoef1 = 0x0000;
    coef[2].iCoef2 = 0x0000;
    coef[3].iCoef1 = 0x00c0;
    coef[3].iCoef2 = 0x0040;
    coef[4].iCoef1 = 0x00f0;
    coef[4].iCoef2 = 0x0000;
    coef[5].iCoef1 = 0x01cc;
    coef[5].iCoef2 = 0xff30;
    coef[6].iCoef1 = 0x0188;
    coef[6].iCoef2 = 0xff18;

    dst.cbSize = 0;
    dst.wFormatTag = WAVE_FORMAT_PCM;
    dst.nSamplesPerSec = 22050;
    dst.wBitsPerSample = 8;
    dst.nChannels = 1;
    dst.nBlockAlign = dst.wBitsPerSample * dst.nChannels / 8;
    dst.nAvgBytesPerSec = dst.nSamplesPerSec * dst.nBlockAlign;

    mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)src, &dst, NULL, 0, 0, 0);
    ok(mr == MMSYSERR_NOERROR, "open failed: 0x%x\n", mr);

    memset(input, 0, sizeof(input));
    memset(&hdr, 0, sizeof(hdr));
    hdr.cbStruct = sizeof(hdr);
    hdr.pbSrc = input;
    hdr.cbSrcLength = sizeof(input);
    hdr.pbDst = pcm;
    hdr.cbDstLength = sizeof(pcm);

    mr = acmStreamPrepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);

    mr = acmStreamUnprepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == 0, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);

    memset(&hdr, 0, sizeof(hdr));
    hdr.cbStruct = sizeof(hdr);
    hdr.pbSrc = input;
    hdr.cbSrcLength = sizeof(input);
    hdr.pbDst = pcm;
    hdr.cbDstLength = sizeof(pcm);
    hdr.fdwStatus = ACMSTREAMHEADER_STATUSF_DONE;

    mr = acmStreamPrepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == (ACMSTREAMHEADER_STATUSF_PREPARED | ACMSTREAMHEADER_STATUSF_DONE), "header wasn't prepared: 0x%x\n", hdr.fdwStatus);

    hdr.cbSrcLengthUsed = 12345;
    hdr.cbDstLengthUsed = 12345;
    hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
    mr = acmStreamConvert(has, &hdr, ACM_STREAMCONVERTF_BLOCKALIGN);
    ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
    ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
    ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
    todo_wine
    ok(hdr.cbDstLengthUsed == 1010, "expected 1010, got %d\n", hdr.cbDstLengthUsed);

    mr = acmStreamUnprepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);

    /* The 2 next tests are related to Lost Horizon (bug 24723) */
    memset(&hdr, 0, sizeof(hdr));
    hdr.cbStruct = sizeof(hdr);
    hdr.pbSrc = input;
    hdr.cbSrcLength = sizeof(input);
    hdr.pbDst = pcm;
    hdr.cbDstLength = -4;

    mr = acmStreamPrepareHeader(has, &hdr, 0);
    if (sizeof(void *) == 4) /* 64 bit fails on this test */
    {
        ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
        ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);

        hdr.cbSrcLengthUsed = 12345;
        hdr.cbDstLengthUsed = 12345;
        hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
        mr = acmStreamConvert(has, &hdr, ACM_STREAMCONVERTF_BLOCKALIGN);
        ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
        ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
        ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
        todo_wine
        ok(hdr.cbDstLengthUsed == 1010, "expected 1010, got %d\n", hdr.cbDstLengthUsed);

        mr = acmStreamUnprepareHeader(has, &hdr, 0);
        ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
        ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);
    }
    else
        ok(mr == MMSYSERR_INVALPARAM, "expected 11, got %d\n", mr);

    memset(&hdr, 0, sizeof(hdr));
    hdr.cbStruct = sizeof(hdr);
    hdr.pbSrc = input;
    hdr.cbSrcLength = 24;
    hdr.pbDst = pcm;
    hdr.cbDstLength = -4;
    mr = acmStreamPrepareHeader(has, &hdr, 0);
    todo_wine {
        ok(mr == ACMERR_NOTPOSSIBLE, "expected 0x200, got 0x%x\n", mr);
        ok(hdr.fdwStatus == 0, "expected 0, got 0x%x\n", hdr.fdwStatus);

        hdr.cbSrcLengthUsed = 12345;
        hdr.cbDstLengthUsed = 12345;
        mr = acmStreamConvert(has, &hdr, ACM_STREAMCONVERTF_BLOCKALIGN);
        ok(mr == ACMERR_UNPREPARED, "expected 0x202, got 0x%x\n", mr);
        ok(hdr.cbSrcLengthUsed == 12345, "expected 12345, got %d\n", hdr.cbSrcLengthUsed);
        ok(hdr.cbDstLengthUsed == 12345, "expected 12345, got %d\n", hdr.cbDstLengthUsed);

        mr = acmStreamUnprepareHeader(has, &hdr, 0);
        ok(mr == ACMERR_UNPREPARED, "expected 0x202, got 0x%x\n", mr);
    }
    /* Less output space than required */
    memset(&hdr, 0, sizeof(hdr));
    hdr.cbStruct = sizeof(hdr);
    hdr.pbSrc = input;
    hdr.cbSrcLength = sizeof(input);
    hdr.pbDst = pcm;
    hdr.cbDstLength = 32;

    mr = acmStreamPrepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);

    hdr.cbSrcLengthUsed = 12345;
    hdr.cbDstLengthUsed = 12345;
    hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
    mr = acmStreamConvert(has, &hdr, ACM_STREAMCONVERTF_BLOCKALIGN);
    ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
    ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
    todo_wine
    ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
    todo_wine
    ok(hdr.cbDstLengthUsed == hdr.cbDstLength, "expected %d, got %d\n", hdr.cbDstLength, hdr.cbDstLengthUsed);

    mr = acmStreamUnprepareHeader(has, &hdr, 0);
    ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
    ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);

    mr = acmStreamClose(has, 0);
    ok(mr == MMSYSERR_NOERROR, "close failed: 0x%x\n", mr);
}
Esempio n. 23
0
//
// FillBuffer
//
// Stuffs the buffer with data
HRESULT CSynthStream::FillBuffer(IMediaSample *pms) 
{
    CheckPointer(pms,E_POINTER);

    BYTE *pData;

    HRESULT hr = pms->GetPointer(&pData);
    if (FAILED(hr)) {
        return hr;
    }

    // This function must hold the state lock because it calls
    // FillPCMAudioBuffer().
    CAutoLock lStateLock(m_pParent->pStateLock());
    
    // This lock must be held because this function uses
    // m_dwTempPCMBufferSize, m_hPCMToMSADPCMConversionStream,
    // m_rtSampleTime, m_fFirstSampleDelivered and
    // m_llSampleMediaTimeStart.
    CAutoLock lShared(&m_cSharedState);

    WAVEFORMATEX* pwfexCurrent = (WAVEFORMATEX*)m_mt.Format();

    if (WAVE_FORMAT_PCM == pwfexCurrent->wFormatTag) 
    {
        m_Synth->FillPCMAudioBuffer(*pwfexCurrent, pData, pms->GetSize());

        hr = pms->SetActualDataLength(pms->GetSize());
        if (FAILED(hr))
            return hr;

    } 
    else 
    {
        // This filter only supports two audio formats: PCM and ADPCM. 
        ASSERT(WAVE_FORMAT_ADPCM == pwfexCurrent->wFormatTag);

        // Create PCM audio samples and then compress them.  We use the
        // Audio Compression Manager (ACM) API to convert the samples to 
        // the ADPCM format. 

        ACMSTREAMHEADER ACMStreamHeader;

        ACMStreamHeader.cbStruct = sizeof(ACMStreamHeader);
        ACMStreamHeader.fdwStatus = 0;
        ACMStreamHeader.dwUser = 0;
        ACMStreamHeader.cbSrcLength = m_dwTempPCMBufferSize;
        ACMStreamHeader.cbSrcLengthUsed = 0;
        ACMStreamHeader.dwSrcUser = 0; 
        ACMStreamHeader.pbDst = pData; 
        ACMStreamHeader.cbDstLength = pms->GetSize(); 
        ACMStreamHeader.cbDstLengthUsed = 0; 
        ACMStreamHeader.dwDstUser = 0; 
        ACMStreamHeader.pbSrc = new BYTE[m_dwTempPCMBufferSize];
        if (NULL == ACMStreamHeader.pbSrc) {
            return E_OUTOFMEMORY;
        }

        WAVEFORMATEX wfexPCMAudio;

        DerivePCMFormatFromADPCMFormatStructure(*pwfexCurrent, &wfexPCMAudio);

        m_Synth->FillPCMAudioBuffer(wfexPCMAudio,
                                    ACMStreamHeader.pbSrc,
                                    ACMStreamHeader.cbSrcLength);

        MMRESULT mmr = acmStreamPrepareHeader(m_hPCMToMSADPCMConversionStream,   
                                              &ACMStreamHeader,
                                              0);
  
        // acmStreamPrepareHeader() returns 0 if no errors occur.
        if (mmr != 0) {
            delete [] ACMStreamHeader.pbSrc;
            return E_FAIL;
        }

        mmr = acmStreamConvert(m_hPCMToMSADPCMConversionStream,
                               &ACMStreamHeader,
                               ACM_STREAMCONVERTF_BLOCKALIGN);

        MMRESULT mmrUnprepare = acmStreamUnprepareHeader(m_hPCMToMSADPCMConversionStream,   
                                                         &ACMStreamHeader,
                                                         0);

        delete [] ACMStreamHeader.pbSrc;

        // acmStreamConvert() andacmStreamUnprepareHeader() returns 0 if no errors occur.
        if ((mmr != 0) || (mmrUnprepare != 0)) {
            return E_FAIL;
        }

        hr = pms->SetActualDataLength(ACMStreamHeader.cbDstLengthUsed);
        if (FAILED(hr)) {
            return hr;
        }
    }

    // Set the sample's time stamps.  
    CRefTime rtStart = m_rtSampleTime;

    m_rtSampleTime = rtStart + (REFERENCE_TIME)(UNITS * pms->GetActualDataLength()) / 
                     (REFERENCE_TIME)pwfexCurrent->nAvgBytesPerSec;

    hr = pms->SetTime((REFERENCE_TIME*)&rtStart, (REFERENCE_TIME*)&m_rtSampleTime);

    if (FAILED(hr)) {
        return hr;
    }

    // Set the sample's properties.
    hr = pms->SetPreroll(FALSE);
    if (FAILED(hr)) {
        return hr;
    }

    hr = pms->SetMediaType(NULL);
    if (FAILED(hr)) {
        return hr;
    }
   
    hr = pms->SetDiscontinuity(!m_fFirstSampleDelivered);
    if (FAILED(hr)) {
        return hr;
    }
    
    hr = pms->SetSyncPoint(!m_fFirstSampleDelivered);
    if (FAILED(hr)) {
        return hr;
    }

    LONGLONG llMediaTimeStart = m_llSampleMediaTimeStart;
    
    DWORD dwNumAudioSamplesInPacket = (pms->GetActualDataLength() * BITS_PER_BYTE) /
                                      (pwfexCurrent->nChannels * pwfexCurrent->wBitsPerSample);

    LONGLONG llMediaTimeStop = m_llSampleMediaTimeStart + dwNumAudioSamplesInPacket;

    hr = pms->SetMediaTime(&llMediaTimeStart, &llMediaTimeStop);
    if (FAILED(hr)) {
        return hr;
    }

    m_llSampleMediaTimeStart = llMediaTimeStop;
    m_fFirstSampleDelivered = TRUE;

    return NOERROR;
}
Esempio n. 24
0
ClResult ClSoundDS::play(int handle,int repeat)
{
	ClSoundBuffer	*lpSoundBuffer;
	HRESULT			hr;

	lpSoundBuffer = SelectSoundBuffer(handle);
	if(NULL==lpSoundBuffer)return Cl_PCM_NOTFOUND;		
	lpSoundBuffer->endPt = -1;
	if(PCM_STOP!=lpSoundBuffer->status) Stop(handle);
	lpSoundBuffer->repeat = repeat;
	lpSoundBuffer->nextMusicNum = -1;
	if(memory_sound==lpSoundBuffer->bufType){
		switch(repeat){
		  case (1):	
			lpSoundBuffer->lpDSBuffer->Play(0,0,0);
			break;
		  case (0):	
			lpSoundBuffer->lpDSBuffer->Play(0,0,DSBPLAY_LOOPING);
			break;
		  default:
			{
				DWORD	dwThreadID;
				DSBPOSITIONNOTIFY  pn;
				lpSoundBuffer->lpDSBuffer->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&lpSoundBuffer->lpDSNotify);
				lpSoundBuffer->hEvent[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
				pn.dwOffset = DSBPN_OFFSETSTOP;	
				pn.hEventNotify = lpSoundBuffer->hEvent[0];
				lpSoundBuffer->lpDSNotify->SetNotificationPositions(1,&pn);
				lpSoundBuffer->hLoopThread = CreateThread(NULL,0,SoundLoop,lpSoundBuffer,0,&dwThreadID);
				lpSoundBuffer->lpDSBuffer->Play(0,0,0);
			}
			break;
		}
	}else{
		lpReadFile->StreamSeekFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpSoundBuffer->dataTopOffset,FILE_BEGIN);
		char		*lpBlockAdd1, *lpBlockAdd2;
		DWORD		blockSize1, blockSize2;

		hr = lpSoundBuffer->lpDSBuffer->Lock(0,lpSoundBuffer->streamBlockSize, (LPVOID*)&lpBlockAdd1, &blockSize1,(LPVOID*)&lpBlockAdd2, &blockSize2, 0);
		if(DS_OK==hr){
			if(WAVE_FORMAT_OGG==lpSoundBuffer->wFormatTag){
				char workBuf[4096];
				char outBuf[0x20000];
				int	 rsize,outsize,ret;
				rsize = lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,workBuf,4096);
				ret = lpSoundBuffer->o_dat->DecodeOGG(workBuf,rsize,outBuf,0x20000,&outsize);

				int remainSize = blockSize1;
				int writeSize = 0;

				while(remainSize>=outsize && remainSize>0){
					CopyMemory(lpBlockAdd1+writeSize,outBuf,outsize);
					remainSize -= outsize;
					writeSize += outsize;
					if(ret==OGG_DEC_END && lpSoundBuffer->nextStream>=0){
						int size;
						lpSoundBuffer->readFile->StreamCloseFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum);
						lpSoundBuffer->streamNum = lpSoundBuffer->readFile->StreamOpenFileNum(lpSoundBuffer->arcFileNum,lpSoundBuffer->nextStream,size);
						lpSoundBuffer->musicNum = lpSoundBuffer->nextStream;
						lpSoundBuffer->nextStream = -1;
						ret = OGG_DEC_CONTINUE;
					}
					if(ret!=OGG_DEC_CONTINUE){
						ZeroMemory(lpBlockAdd1+writeSize,remainSize);
						remainSize = 0;
						break;
					}
					if(remainSize > 0){
						rsize = lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,workBuf,4096);
						ret = lpSoundBuffer->o_dat->DecodeOGG(workBuf,rsize,outBuf,0x20000,&outsize);
					}
				}
				if(remainSize){
					CopyMemory(lpBlockAdd1+writeSize,outBuf,remainSize);
					lpSoundBuffer->leakSize = outsize -remainSize;
					lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
					CopyMemory(lpSoundBuffer->leakBuff,outBuf +remainSize,lpSoundBuffer->leakSize);
				}
			}else if(NULL==lpSoundBuffer->hAcm){
				lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd1,blockSize1);
				if(lpSoundBuffer->streamBlockSize>blockSize1){
					lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd2,blockSize2);
				}
			}else{
				lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,(char *)lpSoundBuffer->acmSrc.lpStream,lpSoundBuffer->acmSrc.dwStreamSize);
				MMRESULT nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash, ACM_STREAMCONVERTF_BLOCKALIGN);
				if(0==nError){
					int remainSize = blockSize1;
					int writeSize = 0;

					while(remainSize>=lpSoundBuffer->ash.cbDstLengthUsed && remainSize>0){
						CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,lpSoundBuffer->ash.cbDstLengthUsed);
						remainSize -= lpSoundBuffer->ash.cbDstLengthUsed;
						writeSize += lpSoundBuffer->ash.cbDstLengthUsed;
						if(remainSize > 0){
							lpReadFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,(char *)lpSoundBuffer->acmSrc.lpStream,lpSoundBuffer->acmSrc.dwStreamSize);
							nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash, ACM_STREAMCONVERTF_BLOCKALIGN);
						}
					}
					if(remainSize){
						CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,remainSize);
						lpSoundBuffer->leakSize = lpSoundBuffer->ash.cbDstLengthUsed -remainSize;
						lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
						CopyMemory(lpSoundBuffer->leakBuff,lpSoundBuffer->acmDst.lpStream +remainSize,lpSoundBuffer->leakSize);
					}
				}
			}
			lpSoundBuffer->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
		}
		DWORD	dwThreadID;
		DSBPOSITIONNOTIFY  pn[3];
		lpSoundBuffer->lpDSBuffer->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&lpSoundBuffer->lpDSNotify);
		lpSoundBuffer->hEvent[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
		lpSoundBuffer->hEvent[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
		lpSoundBuffer->hEvent[2] = CreateEvent(NULL, FALSE, FALSE, NULL);
		pn[0].dwOffset = DWORD(lpSoundBuffer->streamBlockSize*0.1f);
		pn[0].hEventNotify = lpSoundBuffer->hEvent[0];
		pn[1].dwOffset = DWORD(lpSoundBuffer->streamBlockSize*1.1f);
		pn[1].hEventNotify = lpSoundBuffer->hEvent[1];
		pn[2].dwOffset = DSBPN_OFFSETSTOP;
		pn[2].hEventNotify = lpSoundBuffer->hEvent[2];
		lpSoundBuffer->lpDSNotify->SetNotificationPositions(3,pn);
		lpSoundBuffer->hLoopThread = CreateThread(NULL,0,StreamLoop,lpSoundBuffer,0,&dwThreadID);
		lpSoundBuffer->lpDSBuffer->Play(0,0,DSBPLAY_LOOPING);
	}
	lpSoundBuffer->status = PCM_PLAY;
	return Cl_OK;
} // ClSoundDS::play
Esempio n. 25
0
DWORD CPlayer::WavPlayerThread()
{
	BOOL fFlush = FALSE;
	if (m_pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) {
		// PCM
		DWORD cbInBuf, cbRead;
		while (TRUE) {
			// 停止フラグのチェック
			if (m_fStop)
				return RET_STOP;

			if (!m_pOutHdr)
				m_pOutHdr = m_Output.GetBuffer();

			{
				// Critical Sectionのセット
				CAutoLock lock(&m_csecThread);
				if (m_fSeek) {
					if (m_Status == MAP_STATUS_PLAY)
						m_fPlay = TRUE;

					m_Reverb.Reset();
					m_Echo.Reset();
					m_BassBoost.Reset();
					m_3DChorus.Reset();
					m_Output.Reset();
					m_fSeek = FALSE;
					m_pOutHdr = NULL;
					continue;
				}

				// 読み込み
				cbRead = min(m_dwDataSize - m_dwCurrentSize, m_cbOutBuf);
				if (!m_Reader.Read((LPBYTE)m_pOutHdr->lpData, cbRead, &cbInBuf) || !cbInBuf) {
					if (GetLastError() != ERROR_SUCCESS)
						return RET_ERROR;
					fFlush = TRUE;
				}

				Preamp((LPBYTE)m_pOutHdr->lpData, cbInBuf);

				m_dwCurrentSize += cbInBuf;
			}
			if (fFlush)
				return RET_EOF;

			OutputBuffer(m_pOutHdr, cbInBuf);
			m_cbOutBufLeft = 0;
			m_pOutHdr = NULL;

			if (m_dwCurrentSize >= m_dwDataSize)
				return RET_EOF;
			if (m_fSuppress)
				return RET_EOF;
		}
	}
	else {
		// PCM 以外
		// デコード開始
		BYTE bRead[WAV_FILE_BUFF_LEN];
		DWORD cbInBuf, cbRead;
		while (TRUE) {
			// 停止フラグのチェック
			if (m_fStop)
				return RET_STOP;

			// 出力バッファの確保
			if (m_pOutHdr) {
				OutputBuffer(m_pOutHdr, m_cbOutBuf - m_cbOutBufLeft);
				m_cbOutBufLeft = 0;
				m_pOutHdr = NULL;
			}
			if (m_fSuppress)
				return RET_EOF;
			m_pOutHdr = m_Output.GetBuffer();
			m_cbOutBufLeft = m_cbOutBuf;

			{
				// Critical Sectionのセット
				CAutoLock lock(&m_csecThread);
				if (m_fSeek) {
					if (m_Status == MAP_STATUS_PLAY)
						m_fPlay = TRUE;

					m_Reverb.Reset();
					m_Echo.Reset();
					m_BassBoost.Reset();
					m_Output.Reset();
					m_fSeek = FALSE;
					m_pOutHdr = NULL;
					acmStreamReset(m_hAcm, 0);
					continue;
				}

				acmStreamSize(m_hAcm, m_cbOutBufLeft, &cbRead, 
								ACM_STREAMSIZEF_DESTINATION);

				// 読み込み
				cbRead = min(m_dwDataSize - m_dwCurrentSize, cbRead);
				cbRead = min(WAV_FILE_BUFF_LEN, cbRead);
				if (!m_Reader.Read(bRead, cbRead, &cbInBuf) || !cbInBuf) {
					if (GetLastError() != ERROR_SUCCESS)
						return RET_ERROR;

					fFlush = TRUE;
				}
				m_dwCurrentSize += cbInBuf;
			}
			if (fFlush)
				return RET_EOF;

			// ヘッダの確保
			ACMSTREAMHEADER ash;
			memset(&ash, 0, sizeof(ash));
			ash.cbStruct = sizeof(ash); //構造体のサイズ
			ash.pbSrc = bRead;
			ash.cbSrcLength = cbInBuf;
			ash.pbDst = (LPBYTE)m_pOutHdr->lpData + (m_cbOutBuf - m_cbOutBufLeft);
			ash.cbDstLength = m_cbOutBufLeft;
			if (acmStreamPrepareHeader(m_hAcm, &ash, 0))
				break;

			// 変換
			if (acmStreamConvert(m_hAcm, &ash, 0))
				break;

			Preamp((LPBYTE)m_pOutHdr->lpData + (m_cbOutBuf - m_cbOutBufLeft), ash.cbDstLengthUsed);
			m_cbOutBufLeft -= ash.cbDstLengthUsed;

			// 後処理
			if (acmStreamUnprepareHeader(m_hAcm, &ash, 0))
				break;

			if (m_dwCurrentSize >= m_dwDataSize)
				return RET_EOF;
		}

		return RET_ERROR;
	}
}
Esempio n. 26
0
static DWORD WINAPI StreamLoop(LPVOID param)
{
	DWORD			size,pt;
	HRESULT			hr;
	char			*lpBlockAdd1,*lpBlockAdd2;
	DWORD			blockSize1, blockSize2;
	ClSoundBuffer	*lpSoundBuffer = (ClSoundBuffer *)param;
	CRITICAL_SECTION	cr_section;
	InitializeCriticalSection(&cr_section);
	while(TRUE){
		pt = WaitForMultipleObjects(3,lpSoundBuffer->hEvent,FALSE,INFINITE);
		EnterCriticalSection(&cr_section);
		switch(pt){
		  case (WAIT_OBJECT_0):
		  case (WAIT_OBJECT_0+1):
			size = pt -WAIT_OBJECT_0 +1;
			if(size > 1)size = 0;
			hr = lpSoundBuffer->lpDSBuffer->Lock(lpSoundBuffer->streamBlockSize*size,lpSoundBuffer->streamBlockSize, (LPVOID*)&lpBlockAdd1, &blockSize1,(LPVOID*)&lpBlockAdd2, &blockSize2, 0);
			if(DS_OK==hr){
				if(WAVE_FORMAT_OGG==lpSoundBuffer->wFormatTag){
					char	workBuf[4096],outBuf[0x20000];
					int		rsize,outsize,ret;
					int		remainSize = blockSize1;
					int		writeSize = 0;
					if(lpSoundBuffer->leakSize){
						if(lpSoundBuffer->leakSize > blockSize1){
							CopyMemory(lpBlockAdd1,lpSoundBuffer->leakBuff,blockSize1);
							lpSoundBuffer->leakSize -= blockSize1;
							MoveMemory(lpSoundBuffer->leakBuff,lpSoundBuffer->leakBuff+blockSize1,lpSoundBuffer->leakSize);
							remainSize = 0;
							lpSoundBuffer->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
							break;
						}else{
							CopyMemory(lpBlockAdd1,lpSoundBuffer->leakBuff,lpSoundBuffer->leakSize);
							writeSize += lpSoundBuffer->leakSize;
							remainSize -= lpSoundBuffer->leakSize;
							lpSoundBuffer->leakSize = 0;
							my_deletes(lpSoundBuffer->leakBuff);
						}
					}
					if(lpSoundBuffer->endPt>=0){	
						ZeroMemory(lpBlockAdd1+writeSize, remainSize);
						ZeroMemory(lpBlockAdd2, blockSize2);
						lpSoundBuffer->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
						if(pt==lpSoundBuffer->endPt){
							lpSoundBuffer->lpDSBuffer->Stop();
							goto SoundStop;
						}
						break;
					}
					rsize = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,workBuf,4096);
					ret = lpSoundBuffer->o_dat->DecodeOGG(workBuf,rsize,outBuf,0x20000,&outsize);
					if(ret==OGG_DEC_END){	
oggFilEnd:
						if(1==lpSoundBuffer->repeat){	
							if(remainSize >= outsize){
								CopyMemory(lpBlockAdd1+writeSize, outBuf,outsize);
								writeSize  += outsize;
								remainSize -= outsize;
								ZeroMemory(lpBlockAdd1+writeSize, remainSize);
								if(blockSize2)ZeroMemory(lpBlockAdd2,blockSize2);
							}else{
								CopyMemory(lpBlockAdd1+writeSize, outBuf, remainSize);
							}
							lpSoundBuffer->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
							if((-1)==lpSoundBuffer->endPt){
								lpSoundBuffer->endPt = pt;
							}
							break;
						}else{
							if(lpSoundBuffer->repeat) lpSoundBuffer->repeat --;
							if(lpSoundBuffer->nextStream>=0){
								int size;
								lpSoundBuffer->readFile->StreamCloseFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum);
								lpSoundBuffer->streamNum = lpSoundBuffer->readFile->StreamOpenFileNum(lpSoundBuffer->arcFileNum,lpSoundBuffer->nextStream,size);
								lpSoundBuffer->musicNum = lpSoundBuffer->nextStream;
								lpSoundBuffer->nextStream = -1;
							}
							lpSoundBuffer->readFile->StreamSeekFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpSoundBuffer->dataTopOffset,FILE_BEGIN);
							while(remainSize>=outsize && remainSize>0){
								CopyMemory(lpBlockAdd1+writeSize,outBuf,outsize);
								remainSize -= outsize;
								writeSize += outsize;
								if(remainSize > 0){
									rsize = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,
										workBuf,4096);
									ret = lpSoundBuffer->o_dat->DecodeOGG(workBuf,rsize,outBuf,0x20000,&outsize);
									if(OGG_DEC_END==ret){
										goto oggFilEnd;
									}
								}
							}
							if(remainSize){
								CopyMemory(lpBlockAdd1+writeSize,outBuf,remainSize);
								lpSoundBuffer->leakSize = outsize -remainSize;
								lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
								CopyMemory(lpSoundBuffer->leakBuff,outBuf +remainSize,lpSoundBuffer->leakSize);
							}
						}
					}else{
						while(remainSize>=outsize && remainSize>0){
							CopyMemory(lpBlockAdd1+writeSize,outBuf,outsize);
							remainSize -= outsize;
							writeSize += outsize;
							if(remainSize > 0){
								rsize = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,workBuf,4096);
								ret = lpSoundBuffer->o_dat->DecodeOGG(workBuf,rsize,outBuf,0x20000,&outsize);
								if(OGG_DEC_END==ret){
									goto oggFilEnd;
								}
							}
						}
						if(remainSize){
							CopyMemory(lpBlockAdd1+writeSize,outBuf,remainSize);
							lpSoundBuffer->leakSize = outsize -remainSize;
							lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
							CopyMemory(lpSoundBuffer->leakBuff,outBuf +remainSize,lpSoundBuffer->leakSize);
						}
					}
				}else if(NULL==lpSoundBuffer->hAcm){
					size = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd1,blockSize1);
					if(size < blockSize1){	
						if(1==lpSoundBuffer->repeat){	
							ZeroMemory(lpBlockAdd1+size,blockSize1-size);
							lpSoundBuffer->repeat = 0;
							lpSoundBuffer->lpDSBuffer->Play(0,0,0);
						}else{
							if(lpSoundBuffer->repeat) lpSoundBuffer->repeat --;
							lpSoundBuffer->readFile->StreamSeekFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpSoundBuffer->dataTopOffset,FILE_BEGIN);
							lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd1+size,blockSize1-size);
						}
					}else{
						if(lpSoundBuffer->streamBlockSize>blockSize1){
							size = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd2,blockSize2);
							if(size < blockSize2){	
								if(1==lpSoundBuffer->repeat){	
									ZeroMemory(lpBlockAdd2+size,blockSize2-size);
									lpSoundBuffer->repeat = 0;
									lpSoundBuffer->lpDSBuffer->Play(0,0,0);
								}else{
									if(lpSoundBuffer->repeat) lpSoundBuffer->repeat --;
									lpSoundBuffer->readFile->StreamSeekFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpSoundBuffer->dataTopOffset,FILE_BEGIN);
									lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpBlockAdd2+size,blockSize2-size);
								}
							}
						}
					}
				}else{
					int		remainSize = blockSize1;
					int		writeSize = 0;
					if(lpSoundBuffer->leakSize){
						CopyMemory(lpBlockAdd1,lpSoundBuffer->leakBuff,lpSoundBuffer->leakSize);
						writeSize += lpSoundBuffer->leakSize;
						remainSize -= lpSoundBuffer->leakSize;
						lpSoundBuffer->leakSize = 0;
						my_deletes(lpSoundBuffer->leakBuff);
					}
					size = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,
						(char *)lpSoundBuffer->acmSrc.lpStream,lpSoundBuffer->acmSrc.dwStreamSize);
					if(size < lpSoundBuffer->acmSrc.dwStreamSize){	
						lpSoundBuffer->ash.cbSrcLength = lpSoundBuffer->ash.dwSrcUser = size;
						MMRESULT nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash,0);
						lpSoundBuffer->ash.cbSrcLength = lpSoundBuffer->ash.dwSrcUser = lpSoundBuffer->acmSrc.dwStreamSize;
						if(1==lpSoundBuffer->repeat){	
							if(0==nError){
								if(remainSize >= lpSoundBuffer->ash.cbDstLengthUsed){
									CopyMemory(lpBlockAdd1+writeSize, lpSoundBuffer->acmDst.lpStream, lpSoundBuffer->ash.cbDstLengthUsed);
									writeSize  += lpSoundBuffer->ash.cbDstLengthUsed;
									remainSize -= lpSoundBuffer->ash.cbDstLengthUsed;
									ZeroMemory(lpBlockAdd1+writeSize, remainSize);
									if(blockSize2)ZeroMemory(lpBlockAdd2,blockSize2);
								}else{
									CopyMemory(lpBlockAdd1+writeSize, lpSoundBuffer->acmDst.lpStream, remainSize);
									CopyMemory(lpBlockAdd2, lpSoundBuffer->acmDst.lpStream +remainSize,lpSoundBuffer->ash.cbDstLengthUsed -remainSize);
									if(blockSize2 > lpSoundBuffer->ash.cbDstLengthUsed -remainSize){
										ZeroMemory(lpBlockAdd2 +(lpSoundBuffer->ash.cbDstLengthUsed -remainSize),blockSize2-(lpSoundBuffer->ash.cbDstLengthUsed -remainSize));
									}
								}
								lpSoundBuffer->repeat = 0;
								lpSoundBuffer->lpDSBuffer->Play(0,0,0);
							}
						}else{
							if(lpSoundBuffer->repeat) lpSoundBuffer->repeat --;
							lpSoundBuffer->readFile->StreamSeekFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,lpSoundBuffer->dataTopOffset,FILE_BEGIN);
							if(0==nError){
								while(remainSize>=lpSoundBuffer->ash.cbDstLengthUsed && remainSize>0){
									CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,lpSoundBuffer->ash.cbDstLengthUsed);
									remainSize -= lpSoundBuffer->ash.cbDstLengthUsed;
									writeSize += lpSoundBuffer->ash.cbDstLengthUsed;
									if(remainSize > 0){
										size = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,
											(char *)lpSoundBuffer->acmSrc.lpStream,lpSoundBuffer->acmSrc.dwStreamSize);
										nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash,ACM_STREAMCONVERTF_BLOCKALIGN);
									}
								}
								if(remainSize){
									CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,remainSize);
									lpSoundBuffer->leakSize = lpSoundBuffer->ash.cbDstLengthUsed -remainSize;
									lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
									CopyMemory(lpSoundBuffer->leakBuff,lpSoundBuffer->acmDst.lpStream +remainSize,lpSoundBuffer->leakSize);
								}
							}
						}
					}else{
						MMRESULT nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash, ACM_STREAMCONVERTF_BLOCKALIGN);
						if(0==nError){
							while(remainSize>=lpSoundBuffer->ash.cbDstLengthUsed && remainSize>0){
								CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,lpSoundBuffer->ash.cbDstLengthUsed);
								remainSize -= lpSoundBuffer->ash.cbDstLengthUsed;
								writeSize += lpSoundBuffer->ash.cbDstLengthUsed;
								if(remainSize > 0){
									size = lpSoundBuffer->readFile->StreamReadFile(lpSoundBuffer->arcFileNum,lpSoundBuffer->streamNum,
										(char *)lpSoundBuffer->acmSrc.lpStream,lpSoundBuffer->acmSrc.dwStreamSize);
									nError = acmStreamConvert(lpSoundBuffer->hAcm,&lpSoundBuffer->ash, ACM_STREAMCONVERTF_BLOCKALIGN);
								}
							}
							if(remainSize){
								CopyMemory(lpBlockAdd1+writeSize,lpSoundBuffer->acmDst.lpStream,remainSize);
								lpSoundBuffer->leakSize = lpSoundBuffer->ash.cbDstLengthUsed -remainSize;
								lpSoundBuffer->leakBuff = new BYTE[lpSoundBuffer->leakSize];
								CopyMemory(lpSoundBuffer->leakBuff,lpSoundBuffer->acmDst.lpStream +remainSize,lpSoundBuffer->leakSize);
							}
						}
					}
				}
				lpSoundBuffer->lpDSBuffer->Unlock(lpBlockAdd1, blockSize1, lpBlockAdd2, blockSize2);
			}
			break;
		  default:
SoundStop:
			lpSoundBuffer->repeat = 0;
			lpSoundBuffer->lpDSNotify->Release();
			lpSoundBuffer->lpDSNotify = NULL;
			CloseHandle(lpSoundBuffer->hEvent[0]);
			CloseHandle(lpSoundBuffer->hEvent[1]);
			CloseHandle(lpSoundBuffer->hEvent[2]);
			lpSoundBuffer->hEvent[0] = lpSoundBuffer->hEvent[1] = lpSoundBuffer->hEvent[2] = NULL;
			lpSoundBuffer->status = PCM_STOP;
			LeaveCriticalSection(&cr_section);
			DeleteCriticalSection(&cr_section);
			CloseHandle(lpSoundBuffer->hLoopThread);
			lpSoundBuffer->hLoopThread = NULL;
			ExitThread(TRUE);
			return 0L;
		}
		LeaveCriticalSection(&cr_section);
	}
	DeleteCriticalSection(&cr_section);
	ExitThread(TRUE);
	return 0L;
} // StreamLoop
Esempio n. 27
0
static HRESULT WINAPI ACMStream_fnRead(IAVIStream *iface, LONG start,
					LONG samples, LPVOID buffer,
					LONG buffersize, LPLONG bytesread,
					LPLONG samplesread)
{
  IAVIStreamImpl *This = (IAVIStreamImpl *)iface;

  HRESULT hr;
  DWORD   size;

  TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
 	buffersize, bytesread, samplesread);

  /* clear return parameters if given */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;

  /* Do we have our compressor? */
  if (This->has == NULL) {
    hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  /* only need to pass through? */
  if (This->cbInFormat == This->cbOutFormat &&
      memcmp(This->lpInFormat, This->lpOutFormat, This->cbInFormat) == 0) {
    return IAVIStream_Read(This->pStream, start, samples, buffer, buffersize,
			   bytesread, samplesread);
  }

  /* read as much as fit? */
  if (samples == -1)
    samples = buffersize / This->lpOutFormat->nBlockAlign;
  /* limit to buffersize */
  if (samples * This->lpOutFormat->nBlockAlign > buffersize)
    samples = buffersize / This->lpOutFormat->nBlockAlign;

  /* only return needed size? */
  if (buffer == NULL || buffersize <= 0 || samples == 0) {
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->lpOutFormat->nBlockAlign;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* map our positions to pStream positions */
  CONVERT_THIS_to_STREAM(&start);

  /* our needed internal buffersize */
  size = samples * This->lpInFormat->nBlockAlign;

  /* Need to free destination buffer used for writing? */
  if (This->acmStreamHdr.pbDst != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst);
    This->acmStreamHdr.pbDst     = NULL;
    This->acmStreamHdr.dwDstUser = 0;
  }

  /* need bigger source buffer? */
  if (This->acmStreamHdr.pbSrc == NULL ||
      This->acmStreamHdr.dwSrcUser < size) {
    if (This->acmStreamHdr.pbSrc == NULL)
      This->acmStreamHdr.pbSrc = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbSrc = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc, size);
    if (This->acmStreamHdr.pbSrc == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwSrcUser = size;
  }

  This->acmStreamHdr.cbStruct = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbSrcLength     = size;

  /* read source data */
  hr = IAVIStream_Read(This->pStream, start, -1, This->acmStreamHdr.pbSrc,
		       This->acmStreamHdr.cbSrcLength,
		       (LONG *)&This->acmStreamHdr.cbSrcLength, NULL);
  if (FAILED(hr) || This->acmStreamHdr.cbSrcLength == 0)
    return hr;

  /* need to prepare stream? */
  This->acmStreamHdr.pbDst       = buffer;
  This->acmStreamHdr.cbDstLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbDst       = NULL;
      This->acmStreamHdr.cbDstLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;

  This->acmStreamHdr.pbDst       = NULL;
  This->acmStreamHdr.cbDstLength = 0;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = This->acmStreamHdr.cbDstLengthUsed;
  if (samplesread != NULL)
    *samplesread =
      This->acmStreamHdr.cbDstLengthUsed / This->lpOutFormat->nBlockAlign;

  return hr;
}