Exemplo n.º 1
0
static int plugin_run(struct playerHandles *ph, char *key, int *totaltime){
	size_t size;
	long ret;
	const ssize_t len=1600;
	char buf[len];  /* input buffer  */
	unsigned int total=0;
	int channels, enc, retval=DEC_RET_SUCCESS;
	unsigned int rate;
	vorbis_info *vi;
	OggVorbis_File *vf;
	struct outputdetail *details=ph->outdetail;
	int sizemod;
	char tail[OUTPUT_TAIL_SIZE];

	if(!(vf=malloc(sizeof(OggVorbis_File)))){
		fprintf(stderr,"Malloc failed (vf).");
		return DEC_RET_ERROR;
	}

	if(ov_open_callbacks(ph->ffd,vf,NULL,0,OV_CALLBACKS_NOCLOSE)<0){
		fprintf(stderr,"ov open failed\n");
		free(vf);
		return DEC_RET_ERROR;
	}
	details->totaltime=*totaltime;
	details->percent=-1;

	vi=ov_info(vf,-1);
	rate=(unsigned int)vi->rate;
	channels=(unsigned int)vi->channels;
	enc=16;

	sizemod=2*channels;

	snprintf(tail,OUTPUT_TAIL_SIZE,"New format: %dHz %dch %dbps",rate, channels, (int)vi->bitrate_nominal);
	addStatusTail(tail,ph->outdetail);
	snd_param_init(ph,&enc,&channels,&rate);

	h.vf=vf;
	h.total=&total;
	h.rate=rate;
	h.sizemod=sizemod;
	ph->dechandle=&h;

	details->percent=-1;

	do{ /* Read and write until everything is through. */
		if((ret=ov_read(vf,buf,len,0,2,1,&vf->current_link))<1){
			if((retval=vorbStatus(ret))==VORB_CONTINUE)
				continue;
			break;
		}
		size=ret;
		details->curtime=total/(rate*sizemod);
		if(details->totaltime>0)
			details->percent=(details->curtime*100)/details->totaltime;
		crOutput(ph->pflag,details);

#if WITH_ALSA==1
		if(writei_snd(ph,buf,size/sizemod)<0)break;
#else
		if(writei_snd(ph,buf,size)<0)break;
#endif
		total+=size;

		if(ph->pflag->exit!=DEC_RET_SUCCESS){
			retval=ph->pflag->exit;
			break;
		}
	}while(1);
	writei_snd(ph,NULL,0); // drain sound buffer

	/* Done decoding, now just clean up and leave. */
	ov_clear(vf);
	*totaltime=details->curtime;
	return retval;
}
Exemplo n.º 2
0
Arquivo: OGG.cpp Projeto: imclab/lime
	bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) {
		
		OggVorbis_File oggFile;
		
		if (resource->path) {
			
			FILE_HANDLE *file = lime::fopen (resource->path, "rb");
			
			if (!file) {
				
				return false;
				
			}
			
			if (file->isFile ()) {
				
				if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) {
					
					lime::fclose (file);
					return false;
					
				}
				
			} else {
				
				lime::fclose (file);
				Bytes data = Bytes (resource->path);
				
				OAL_OggMemoryFile fakeFile = { data.Data (), data.Length (), 0 };
				
				if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {
					
					return false;
					
				}
				
			}
			
		} else {
			
			OAL_OggMemoryFile fakeFile = { resource->data->Data (), resource->data->Length (), 0 };
			
			if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {
				
				return false;
				
			}
			
		}
		
		// 0 for Little-Endian, 1 for Big-Endian
		#ifdef HXCPP_BIG_ENDIAN
		#define BUFFER_READ_TYPE 1
		#else
		#define BUFFER_READ_TYPE 0
		#endif
		
		int bitStream;
		long bytes = 1;
		int totalBytes = 0;
		
		#define BUFFER_SIZE 4096
		
		vorbis_info *pInfo = ov_info (&oggFile, -1);            
		
		if (pInfo == NULL) {
			
			//LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n");
			ov_clear (&oggFile);
			return false;
			
		}
		
		audioBuffer->channels = pInfo->channels;
		audioBuffer->sampleRate = pInfo->rate;
		
		audioBuffer->bitsPerSample = 16;
		
		int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8;
		audioBuffer->data->Resize (dataLength);
		
		while (bytes > 0) {
				
				bytes = ov_read (&oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream);
				totalBytes += bytes;
				
		}
		
		if (dataLength != totalBytes) {
			
			audioBuffer->data->Resize (totalBytes);
			
		}
		
		ov_clear (&oggFile);
		
		#undef BUFFER_READ_TYPE
		
		return true;
		
	}
Exemplo n.º 3
0
static snd_stream_t *S_VORBIS_CodecOpenStream (const char *filename)
{
    snd_stream_t *stream;
    OggVorbis_File *ovFile;
    vorbis_info *ovf_info;
    long numstreams;
    int res;

    stream = S_CodecUtilOpen(filename, &vorbis_codec);
    if (!stream)
        return NULL;

    ovFile = (OggVorbis_File *) Z_Malloc(sizeof(OggVorbis_File));
    res = OV_OPEN_CALLBACKS(&stream->fh, ovFile, NULL, 0, ovc_qfs);
    if (res != 0)
    {
        Con_Printf("%s is not a valid Ogg Vorbis file (error %i).\n",
                   filename, res);
        goto _fail;
    }

    stream->priv = ovFile;

    if (!ov_seekable(ovFile))
    {
        Con_Printf("Stream %s not seekable.\n", filename);
        goto _fail;
    }

    ovf_info = ov_info(ovFile, 0);
    if (!ovf_info)
    {
        Con_Printf("Unable to get stream info for %s.\n", filename);
        goto _fail;
    }

    /* FIXME: handle section changes */
    numstreams = ov_streams(ovFile);
    if (numstreams != 1)
    {
        Con_Printf("More than one (%ld) stream in %s.\n",
                   numstreams, filename);
        goto _fail;
    }

    if (ovf_info->channels != 1 && ovf_info->channels != 2)
    {
        Con_Printf("Unsupported number of channels %d in %s\n",
                   ovf_info->channels, filename);
        goto _fail;
    }

    stream->info.rate = ovf_info->rate;
    stream->info.channels = ovf_info->channels;
    stream->info.width = VORBIS_SAMPLEWIDTH;

    return stream;
_fail:
    if (res == 0)
        ov_clear(ovFile);
    Z_Free(ovFile);
    S_CodecUtilClose(&stream);
    return NULL;
}
Exemplo n.º 4
0
/* public */
static void
vorbis_stream_decode(struct decoder *decoder,
		     struct input_stream *input_stream)
{
	GError *error = NULL;

	if (ogg_codec_detect(decoder, input_stream) != OGG_CODEC_VORBIS)
		return;

	/* rewind the stream, because ogg_codec_detect() has
	   moved it */
	input_stream_lock_seek(input_stream, 0, SEEK_SET, NULL);

	struct vorbis_input_stream vis;
	OggVorbis_File vf;
	if (!vorbis_is_open(&vis, &vf, decoder, input_stream))
		return;

	const vorbis_info *vi = ov_info(&vf, -1);
	if (vi == NULL) {
		g_warning("ov_info() has failed");
		return;
	}

	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, vi->rate,
#ifdef HAVE_TREMOR
				       SAMPLE_FORMAT_S16,
#else
				       SAMPLE_FORMAT_FLOAT,
#endif
				       vi->channels, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return;
	}

	float total_time = ov_time_total(&vf, -1);
	if (total_time < 0)
		total_time = 0;

	decoder_initialized(decoder, &audio_format, vis.seekable, total_time);

	enum decoder_command cmd = decoder_get_command(decoder);

#ifdef HAVE_TREMOR
	char buffer[4096];
#else
	float buffer[2048];
	const int frames_per_buffer =
		G_N_ELEMENTS(buffer) / audio_format.channels;
	const unsigned frame_size = sizeof(buffer[0]) * audio_format.channels;
#endif

	int prev_section = -1;
	unsigned kbit_rate = 0;

	do {
		if (cmd == DECODE_COMMAND_SEEK) {
			double seek_where = decoder_seek_where(decoder);
			if (0 == ov_time_seek_page(&vf, seek_where)) {
				decoder_command_finished(decoder);
			} else
				decoder_seek_error(decoder);
		}

		int current_section;

#ifdef HAVE_TREMOR
		long nbytes = ov_read(&vf, buffer, sizeof(buffer),
				      VORBIS_BIG_ENDIAN, 2, 1,
				      &current_section);
#else
		float **per_channel;
		long nframes = ov_read_float(&vf, &per_channel,
					     frames_per_buffer,
					     &current_section);
		long nbytes = nframes;
		if (nframes > 0) {
			vorbis_interleave(buffer,
					  (const float*const*)per_channel,
					  nframes, audio_format.channels);
			nbytes *= frame_size;
		}
#endif

		if (nbytes == OV_HOLE) /* bad packet */
			nbytes = 0;
		else if (nbytes <= 0)
			/* break on EOF or other error */
			break;

		if (current_section != prev_section) {
			vi = ov_info(&vf, -1);
			if (vi == NULL) {
				g_warning("ov_info() has failed");
				break;
			}

			if (vi->rate != (long)audio_format.sample_rate ||
			    vi->channels != (int)audio_format.channels) {
				/* we don't support audio format
				   change yet */
				g_warning("audio format change, stopping here");
				break;
			}

			char **comments = ov_comment(&vf, -1)->user_comments;
			vorbis_send_comments(decoder, input_stream, comments);

			struct replay_gain_info rgi;
			if (vorbis_comments_to_replay_gain(&rgi, comments))
				decoder_replay_gain(decoder, &rgi);

			prev_section = current_section;
		}

		long test = ov_bitrate_instant(&vf);
		if (test > 0)
			kbit_rate = test / 1000;

		cmd = decoder_data(decoder, input_stream,
				   buffer, nbytes,
				   kbit_rate);
	} while (cmd != DECODE_COMMAND_STOP);

	ov_clear(&vf);
}
Exemplo n.º 5
0
/**
 * @brief S_OGG_CodecOpenStream
 * @param[in] filename
 * @return
 */
snd_stream_t *S_OGG_CodecOpenStream(const char *filename)
{
	snd_stream_t *stream;

	// OGG codec control structure
	OggVorbis_File *vf;

	// some variables used to get informations about the OGG
	vorbis_info *OGGInfo;
	ogg_int64_t numSamples;

	// check if input is valid
	if (!filename)
	{
		return NULL;
	}

	// Open the stream
	stream = S_CodecUtilOpen(filename, &ogg_codec);
	if (!stream)
	{
		return NULL;
	}

	// alloctate the OggVorbis_File
	vf = Z_Malloc(sizeof(OggVorbis_File));
	if (!vf)
	{
		S_CodecUtilClose(&stream);

		return NULL;
	}

	// open the codec with our callbacks and stream as the generic pointer
	if (ov_open_callbacks(stream, vf, NULL, 0, S_OGG_Callbacks) != 0)
	{
		Z_Free(vf);

		S_CodecUtilClose(&stream);

		return NULL;
	}

	// the stream must be seekable
	if (!ov_seekable(vf))
	{
		ov_clear(vf);

		Z_Free(vf);

		S_CodecUtilClose(&stream);

		return NULL;
	}

	// we only support OGGs with one substream
	if (ov_streams(vf) != 1)
	{
		ov_clear(vf);

		Z_Free(vf);

		S_CodecUtilClose(&stream);

		return NULL;
	}

	// get the info about channels and rate
	OGGInfo = ov_info(vf, 0);
	if (!OGGInfo)
	{
		ov_clear(vf);

		Z_Free(vf);

		S_CodecUtilClose(&stream);

		return NULL;
	}

	// get the number of sample-frames in the OGG
	numSamples = ov_pcm_total(vf, 0);

	// fill in the info-structure in the stream
	stream->info.rate     = OGGInfo->rate;
	stream->info.width    = OGG_SAMPLEWIDTH;
	stream->info.channels = OGGInfo->channels;
	stream->info.samples  = numSamples;
	stream->info.size     = stream->info.samples * stream->info.channels * stream->info.width;
	stream->info.dataofs  = 0;

	// We use stream->pos for the file pointer in the compressed ogg file
	stream->pos = 0;

	// We use the generic pointer in stream for the OGG codec control structure
	stream->ptr = vf;

	return stream;
}
Exemplo n.º 6
0
bool LoadOggVorbisFromFileInMemory(const u8 *fileData, size_t numBytes, std::vector<u8> &dst, bool *isStereo, bool *is16Bit, int *frequency)
{
    if (!fileData || numBytes == 0)
    {
        LogError("Null input data passed in");
        return false;
    }

    if (!isStereo || !is16Bit || !frequency)
    {
        LogError("Outputs not set");
        return false;
    }
    
#ifndef TUNDRA_NO_AUDIO
    OggVorbis_File vf;
    OggMemDataSource src(fileData, numBytes);
    
    ov_callbacks cb;
    cb.read_func = &OggReadCallback;
    cb.seek_func = &OggSeekCallback;
    cb.tell_func = &OggTellCallback;
    cb.close_func = 0;
                   
    int ret = ov_open_callbacks(&src, &vf, 0, 0, cb);
    if (ret < 0)
    {
        LogError("Not ogg vorbis format");
        ov_clear(&vf);
        return false;
    }
    
    vorbis_info* vi = ov_info(&vf, -1);
    if (!vi)
    {
        LogError("No ogg vorbis stream info");
        ov_clear(&vf);
        return false;
    }

    std::ostringstream msg;
    msg << "Decoding ogg vorbis stream with " << vi->channels << " channels, frequency " << vi->rate; 
//    LogDebug(msg.str()); 

    *frequency = vi->rate;
    *isStereo = (vi->channels > 1);
    if (vi->channels != 1 && vi->channels != 2)
        LogWarning("Warning: Loaded Ogg Vorbis data contains an unsupported number of channels: " + QString::number(vi->channels));

    uint decoded_bytes = 0;
    dst.clear();
    for(;;)
    {
        static const int MAX_DECODE_SIZE = 16384;
        dst.resize(decoded_bytes + MAX_DECODE_SIZE);
        int bitstream;
        long ret = ov_read(&vf, (char*)&dst[decoded_bytes], MAX_DECODE_SIZE, 0, 2, 1, &bitstream);
        if (ret <= 0)
            break;
        decoded_bytes += ret;
    }
    
    dst.resize(decoded_bytes);

    {
        std::ostringstream msg;
        msg << "Decoded " << decoded_bytes << " bytes of ogg vorbis sound data";
//        LogDebug(msg.str());
    }
     
    ov_clear(&vf);
    return true;
#else
    return false;
#endif
}
Exemplo n.º 7
0
bool OggPlayer::OpenOgg( const char *filename )
{
    if (!bInitialized)
        return false;

    if (bFileOpened)
        Close();

    FILE    *f;

    f = fopen(filename, "rb");
    if (!f) return false;

	ov_open(f, &vf, NULL, 0);

    // ok now the tricky part

    // the vorbis_info struct keeps the most of the interesting format info
    vorbis_info *vi = ov_info(&vf,-1);
	vorbis_comment *vc = ov_comment(&vf, 0);
	nLoopStart = 0;
	nLoopEnd = 0;

	if (vc != NULL) {
		for (int i = 0; i < ARRAYLEN(loop_start_tags); i++) {
			char *value = vorbis_comment_query(vc, loop_start_tags[i], 0);
			if (value != NULL) {
				nLoopStart = atoi(value);
			}
		}
		for (int i = 0; i < ARRAYLEN(loop_end_tags); i++) {
			char *value = vorbis_comment_query(vc, loop_end_tags[i], 0);
			if (value != NULL) {
				nLoopEnd = atoi(value);
			}
		}
	}

	if (nLoopEnd <= nLoopStart) {
		nLoopEnd = ov_pcm_total(&vf, -1);
	}

    // set the wave format
	WAVEFORMATEX	    wfm;

    memset(&wfm, 0, sizeof(wfm));

    wfm.cbSize          = sizeof(wfm);
    wfm.nChannels       = vi->channels;
    wfm.wBitsPerSample  = 16;                    // ogg vorbis is always 16 bit
    wfm.nSamplesPerSec  = vi->rate;
    wfm.nAvgBytesPerSec = wfm.nSamplesPerSec*wfm.nChannels*2;
    wfm.nBlockAlign     = 2*wfm.nChannels;
    wfm.wFormatTag      = 1;


    // set up the buffer
	DSBUFFERDESC desc;

	desc.dwSize         = sizeof(desc);
	desc.dwFlags        = DSBCAPS_CTRLVOLUME;
	desc.lpwfxFormat    = &wfm;
	desc.dwReserved     = 0;

    desc.dwBufferBytes  = BUFSIZE*2;
    pDS->CreateSoundBuffer(&desc, &pDSB, NULL );

    // fill the buffer

    DWORD   pos = 0;
    int     sec = 0;
    int     ret = 1;
    DWORD   size = BUFSIZE*2;

    char    *buf;

    pDSB->Lock(0, size, (LPVOID*)&buf, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER);
    
    // now read in the bits
    while(ret && pos<size)
    {
        ret = ov_read(&vf, buf+pos, size-pos, 0, 2, 1, &sec);
        pos += ret;
    }

	pDSB->Unlock( buf, size, NULL, NULL );

    nCurSection         =
    nLastSection        = 0;

    return bFileOpened = true;
}
Exemplo n.º 8
0
int
quh_vorbis_in_open (st_quh_nfo_t * file)
{
  ogg_int64_t length = 0;
  int bits = 16;
  vorbis_comment *c = NULL;
  char buf[MAXBUFSIZE];
  vorbis_info *nfo = NULL;

  if (!(fp = fopen (file->fname, "rb")))
    return -1;

  if (ov_open (fp, &vf, NULL, 0) < 0)
    {
      fclose (fp);
      return -1;
    }
  opened = 1;

  // comments
  *buf = 0;
  c = vf.vc;
  if (c)
    {
      int x = 0;
      for (; x < c->comments && strlen (buf) < MAXBUFSIZE - 128; x++)
        {
          char *p = strchr (buf, 0);

          if (x)
            strcpy (p, "\n");
                
          p = strchr (buf, 0);
          quh_fix_vorbis_comment (p, c->user_comments[x]);
        }
      quh_set_object_s (quh.filter_chain, QUH_OUTPUT, buf);
    }

  if (ov_seekable (&vf))
    {
      length = ov_pcm_total (&vf, 0);
      file->seekable = QUH_SEEKABLE;
    }

  if ((nfo = ov_info (&vf, 0)))
    {
      file->rate = nfo->rate;
      file->channels = nfo->channels;
      file->min_bitrate = nfo->bitrate_lower ? nfo->bitrate_lower : nfo->bitrate_nominal;
      file->max_bitrate = nfo->bitrate_upper ? nfo->bitrate_upper : nfo->bitrate_nominal;
    }
  else
    {
      file->rate = 44100;
      file->channels = 2;
      file->min_bitrate =
      file->max_bitrate = 0;
    }
  file->is_signed = 1;
  file->size = bits / 8;

  if (length > 0)
    file->raw_size = length * bits / 8 * file->channels;
  file->raw_size = MIN (file->raw_size, 0x7fffffff);

  return 0;
}
Exemplo n.º 9
0
static playbackstatus MV_GetNextVorbisBlock
(
 VoiceNode *voice
 )

{
   vorbis_data * vd = (vorbis_data *) voice->extra;
   int32_t bytes, bytesread;
   int32_t bitstream, err;

   voice->Playing = TRUE;
   
   bytesread = 0;
   do {
       bytes = ov_read(&vd->vf, vd->block + bytesread, BLOCKSIZE - bytesread, 0, 2, 1, &bitstream);
       //fprintf(stderr, "ov_read = %d\n", bytes);
       if (bytes > 0) { bytesread += bytes; continue; }
       else if (bytes == OV_HOLE) continue;
       else if (bytes == 0) {
           if (voice->LoopStart) {
               err = ov_pcm_seek_page(&vd->vf, 0);
               if (err != 0) {
                   MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek_page_lap: err %d\n", err);
               } else {
                   continue;
               }
           } else {
               break;
           }
       } else if (bytes < 0) {
           MV_Printf("MV_GetNextVorbisBlock ov_read: err %d\n", bytes);
           voice->Playing = FALSE;
           return NoMoreData;
       }
   } while (bytesread < BLOCKSIZE);

   if (bytesread == 0) {
      voice->Playing = FALSE;
      return NoMoreData;
   }
      
   if (bitstream != vd->lastbitstream) {
      vorbis_info * vi = 0;
      
      vi = ov_info(&vd->vf, -1);
      if (!vi || (vi->channels != 1 && vi->channels != 2)) {
         voice->Playing = FALSE;
         return NoMoreData;
      }
      
      voice->channels = vi->channels;
      voice->SamplingRate = vi->rate;
      voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
      voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) - voice->RateScale;
      MV_SetVoiceMixMode( voice );
      vd->lastbitstream = bitstream;
   }

   bytesread /= 2 * voice->channels;
   
   voice->position    = 0;
   voice->sound       = vd->block;
   voice->BlockLength = 0;
   voice->length      = bytesread << 16;
   
   return( KeepPlaying );
}
Exemplo n.º 10
0
int WOggDecoder::_OpenFile(unsigned int fLite)
{

	bit_stream.start = c_pchStreamStart;
	bit_stream.end = c_pchStreamStart + c_nStreamSize - 1;
	bit_stream.pos = c_pchStreamStart;
	bit_stream.size = c_nStreamSize;

	if(c_fManagedStream)
	{
		if(ov_open_callbacks(this, &vf, NULL, 0, cb) < 0)
		{
			err(DECODER_NOT_VALID_OGG_STREAM);
			return 0;
		}
	}
	else
	{
		if(ov_open_callbacks(&bit_stream, &vf, NULL, 0, cb) < 0)
		{
			err(DECODER_NOT_VALID_OGG_STREAM);
			return 0;
		}
	}

		
	if(fLite)
		return 1;

	// get number of logical streams
	c_nNumberOfLogicalBitstreams = ov_streams(&vf);

	if(c_nNumberOfLogicalBitstreams == 0)
	{
		err(DECODER_NOT_VALID_OGG_STREAM);
		return 0;
	}


	c_nLogicalBitstreamIndex = 0;

	vi = ov_info(&vf, c_nLogicalBitstreamIndex);


	if(vi == NULL)
	{
		err(DECODER_NOT_VALID_OGG_STREAM);
		return 0;	
	}


	c_isInfo.nSampleRate = vi->rate;
	c_isInfo.nChannel = vi->channels;


	c_isInfo.fVbr = 1;
	if(vi->bitrate_upper == vi->bitrate_lower)
		c_isInfo.fVbr = 0;
		
	c_isInfo.nFileBitrate = ov_bitrate(&vf, c_nLogicalBitstreamIndex);
	ogg_int64_t len = ov_pcm_total(&vf, c_nLogicalBitstreamIndex);
	if(len == OV_EINVAL)
		c_isInfo.nLength = 0;
	else	
		c_isInfo.nLength = len;


	if(c_isInfo.nChannel > 2)
		c_isInfo.pchStreamDescription = "VORBIS OGG MULTI CHANNEL";
	else if(c_isInfo.nChannel == 2)
		c_isInfo.pchStreamDescription = "VORBIS OGG STEREO";
	else
		c_isInfo.pchStreamDescription = "VORBIS OGG MONO";

	// get informations of input stream
	// WE ALWAYS USE 16 bit per sample

	// save original bit per sample

	if(c_isInfo.nChannel >= 2)
		c_nBlockAlign = 4;	
	else
		c_nBlockAlign = 2;
	
	c_isInfo.nBlockAlign = 4;		
	c_isInfo.nBitPerSample = 16;
	c_nReversePos = 0;

	c_nCurrentPosition = 0;
	c_fReady = 1;

	return 1;


}
Exemplo n.º 11
0
void SoundPlayer::play(ArchiveFile& file) {
	// If we're not initialised yet, do it now
	if (!_initialised) {
		initialise();
    }

	// Stop any previous playback operations, that might be still active
	clearBuffer();

	// Retrieve the extension
	std::string ext = os::getExtension(file.getName());

	if (boost::algorithm::to_lower_copy(ext) == "ogg") {
		// Convert the file into a buffer, self-destructs at end of scope
		ScopedArchiveBuffer buffer(file);

		// This is an OGG Vorbis file, decode it
		vorbis_info* vorbisInfo;
  		OggVorbis_File oggFile;

  		// Initialise the wrapper class
  		OggFileStream stream(buffer);

  		// Setup the callbacks and point them to the helper class
  		ov_callbacks callbacks;
  		callbacks.read_func = OggFileStream::oggReadFunc;
  		callbacks.seek_func = OggFileStream::oggSeekFunc;
  		callbacks.close_func = OggFileStream::oggCloseFunc;
  		callbacks.tell_func = OggFileStream::oggTellFunc;

  		// Open the OGG data stream using the custom callbacks
  		int res = ov_open_callbacks(static_cast<void*>(&stream), &oggFile,
									NULL, 0, callbacks);

  		if (res == 0) {
  			// Open successful

  			// Get some information about the OGG file
			vorbisInfo = ov_info(&oggFile, -1);

			// Check the number of channels
			ALenum format = (vorbisInfo->channels == 1) ? AL_FORMAT_MONO16
														: AL_FORMAT_STEREO16;

			// Get the sample Rate
			ALsizei freq = (vorbisInfo->rate);
			//std::cout << "Sample rate is " << freq << "\n";

			long bytes;
			char smallBuffer[4096];
			DecodeBufferPtr largeBuffer(new DecodeBuffer());
			do {
				int bitStream;
				// Read a chunk of decoded data from the vorbis file
				bytes = ov_read(&oggFile, smallBuffer, sizeof(smallBuffer),
								0, 2, 1, &bitStream);

				if (bytes == OV_HOLE) {
					rError() << "SoundPlayer: Error decoding OGG: OV_HOLE.\n";
				}
				else if (bytes == OV_EBADLINK) {
					rError() << "SoundPlayer: Error decoding OGG: OV_EBADLINK.\n";
				}
				else {
					// Stuff this into the variable-sized buffer
					largeBuffer->insert(largeBuffer->end(), smallBuffer, smallBuffer + bytes);
				}
			} while (bytes > 0);

			// Allocate a new buffer
			alGenBuffers(1, &_buffer);

			DecodeBuffer& bufferRef = *largeBuffer;

			// Upload sound data to buffer
			alBufferData(_buffer,
						 format,
						 &bufferRef[0],
						 static_cast<ALsizei>(bufferRef.size()),
						 freq);

			// Clean up the OGG routines
  			ov_clear(&oggFile);
  		}
  		else {
  			rError() << "SoundPlayer: Error opening OGG file.\n";
  		}
	}
	else {
		// Must be a wave file
		try {
			// Create an AL sound buffer directly from the buffer in memory
			_buffer = WavFileLoader::LoadFromStream(file.getInputStream());
		}
		catch (std::runtime_error& e) {
			rError() << "SoundPlayer: Error opening WAV file: " << e.what() << std::endl;
			_buffer = 0;
		}
	}

	if (_buffer != 0) {
		alGenSources(1, &_source);
		// Assign the buffer to the source and play it
		alSourcei(_source, AL_BUFFER, _buffer);

		// greebo: Wait 10 msec. to fix a problem with buffers not being played
		// maybe the AL needs time to push the data?
		usleep(10000);

		alSourcePlay(_source);

		// Enable the periodic buffer check, this destructs the buffer
		// as soon as the playback has finished
		_timer.enable();
	}
}
Exemplo n.º 12
0
bool MkSoundBuffer::_CreateBufferFromOggFile(LPDIRECTSOUND directSound, const MkByteArray& srcData)
{
	OggVorbis_File vorbisFile;
	::ZeroMemory(&vorbisFile, sizeof(OggVorbis_File));

	do
	{
		MkInterfaceForDataReading drInterface;
		if (!drInterface.SetUp(srcData, 0))
			break;

		// vorbis file 오픈
		ov_callbacks ogg_callbacks = { _read_func, _seek_func, _close_func, _tell_func };
		if (ov_open_callbacks(reinterpret_cast<void*>(&drInterface), &vorbisFile, NULL, 0, ogg_callbacks) != 0)
			break;

		// 구조 정보
		vorbis_info* vorbisInfo = ov_info(&vorbisFile, -1);
		if (vorbisInfo == NULL)
			break;

		// 버퍼 확보
		int dataSize = vorbisInfo->channels * 16 / 8 * static_cast<int>(ov_pcm_total(&vorbisFile, -1));
		if (dataSize <= 0)
			break;

		MkByteArray dataBuffer;
		dataBuffer.Fill(static_cast<unsigned int>(dataSize));

		// PCM 블록 읽으며 디코딩
		int bitstream, readSize = 0, writeSize = 0;
		while (true)
		{
			writeSize = ov_read(&vorbisFile, reinterpret_cast<char*>(dataBuffer.GetPtr()) + readSize, dataSize - readSize, 0, 2, 1, &bitstream);

			if(writeSize == 0) // EOF
				break;

			if ((dataSize - readSize) >= 0) // continue
			{
				readSize += writeSize;
			}
			else // 디코딩 실패
			{
				writeSize = -1;
				break;
			}
		}

		if (writeSize < 0)
			break;

		// wave 정보 세팅
		WAVEFORMATEX waveFormatEx;
		waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
		waveFormatEx.nChannels = vorbisInfo->channels;
		waveFormatEx.nSamplesPerSec = vorbisInfo->rate;
		waveFormatEx.nAvgBytesPerSec = vorbisInfo->channels * vorbisInfo->rate * 16 / 8; // 채널 * 주파수 * 진폭 / 8(bit>byte)
		waveFormatEx.nBlockAlign = vorbisInfo->channels * 16 / 8;
		waveFormatEx.wBitsPerSample = 16;
		waveFormatEx.cbSize = 0;

		// 사운드 버퍼 생성 후 데이터 복사
		m_SoundBuffer = _CreateSoundBuffer(directSound, waveFormatEx, dataBuffer);
	}
	while (false);

	ov_clear(&vorbisFile);
	return (m_SoundBuffer != NULL);
}
Exemplo n.º 13
0
static void * ogg_player_thread(private_data_ogg * priv)
{
	int first_time = 1;
	long ret;

	//init
	LWP_InitQueue(&oggplayer_queue);

	priv[0].vi = ov_info(&priv[0].vf, -1);

	ASND_Pause(0);

	priv[0].pcm_indx = 0;
	priv[0].pcmout_pos = 0;
	priv[0].eof = 0;
	priv[0].flag = 0;
	priv[0].current_section = 0;

	ogg_thread_running = 1;

	while (!priv[0].eof && ogg_thread_running)
	{
		if (priv[0].flag)
			LWP_ThreadSleep(oggplayer_queue); // wait only when i have samples to send

		if (priv[0].flag == 0) // wait to all samples are sent
		{
			if (ASND_TestPointer(0, priv[0].pcmout[priv[0].pcmout_pos])
					&& ASND_StatusVoice(0) != SND_UNUSED)
			{
				priv[0].flag |= 64;
				continue;
			}
			if (priv[0].pcm_indx < READ_SAMPLES)
			{
				priv[0].flag = 3;

				if (priv[0].seek_time >= 0)
				{
					ov_time_seek(&priv[0].vf, priv[0].seek_time);
					priv[0].seek_time = -1;
				}

				ret
						= ov_read(
								&priv[0].vf,
								(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
								MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
				priv[0].flag &= 192;
				if (ret == 0)
				{
					/* EOF */
					if (priv[0].mode & 1)
						ov_time_seek(&priv[0].vf, 0); // repeat
					else
						priv[0].eof = 1; // stops
				}
				else if (ret < 0)
				{
					/* error in the stream.  Not a problem, just reporting it in
					 case we (the app) cares.  In this case, we don't. */
					if (ret != OV_HOLE)
					{
						if (priv[0].mode & 1)
							ov_time_seek(&priv[0].vf, 0); // repeat
						else
							priv[0].eof = 1; // stops
					}
				}
				else
				{
					/* we don't bother dealing with sample rate changes, etc, but
					 you'll have to*/
					priv[0].pcm_indx += ret >> 1; //get 16 bits samples
				}
			}
			else
				priv[0].flag = 1;
		}
Exemplo n.º 14
0
   bool open(const std::string &path, int startTime)
   {
        int result;
        mPath = std::string(path.c_str());
        mIsValid = true;
        
        #ifdef ANDROID
        
        mInfo = AndroidGetAssetFD(path.c_str());
        oggFile = fdopen(mInfo.fd, "rb");
        fseek(oggFile, mInfo.offset, 0);
        
        ov_callbacks callbacks;
        callbacks.read_func = &nme::AudioStream_Ogg::read_func;
        callbacks.seek_func = &nme::AudioStream_Ogg::seek_func;
        callbacks.close_func = &nme::AudioStream_Ogg::close_func;
        callbacks.tell_func = &nme::AudioStream_Ogg::tell_func;
        
        #else
        
        oggFile = fopen(path.c_str(), "rb");
        
        #endif
        
        if(!oggFile) {
            //throw std::string("Could not open Ogg file.");
            LOG_SOUND("Could not open Ogg file.");
            mIsValid = false;
            return false;
        }
        
        oggStream = new OggVorbis_File();
        
        #ifdef ANDROID
        result = ov_open_callbacks(this, oggStream, NULL, 0, callbacks);
        #else
        result = ov_open(oggFile, oggStream, NULL, 0);
        #endif
         
        if(result < 0) {
         
            fclose(oggFile);
            oggFile = 0;
         
            //throw std::string("Could not open Ogg stream. ") + errorString(result);
            LOG_SOUND("Could not open Ogg stream.");
            //LOG_SOUND(errorString(result).c_str());
            mIsValid = false;
            return false;
        }

        vorbisInfo = ov_info(oggStream, -1);
        vorbisComment = ov_comment(oggStream, -1);

        mChannels = vorbisInfo->channels;
        mRate = vorbisInfo->rate;

        if (startTime != 0)
        {
          double seek = startTime * 0.001;
          ov_time_seek(oggStream, seek);
        }

        return true;
   }
Exemplo n.º 15
0
void CreateVorbisStream(MFAudioStream *pStream, const char *pFilename)
{
	MFCALLSTACK;

	MFVorbisStream *pVS = (MFVorbisStream*)MFHeap_Alloc(sizeof(MFVorbisStream));
	pStream->pStreamData = pVS;

	// open vorbis file
	MFFile* hFile = MFFileSystem_Open(pFilename);
	if(!hFile)
		return;

	// attempt to cache the vorbis stream
	MFOpenDataCachedFile cachedOpen;
	cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
	cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
	cachedOpen.maxCacheSize = 256*1024; // 256k cache for vorbis stream should be heaps!!
	cachedOpen.pBaseFile = hFile;

	MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
	if(pCachedFile)
		hFile = pCachedFile;

	// setup vorbis read callbacks
	ov_callbacks callbacks;
	callbacks.read_func = MFFile_StdRead;
	callbacks.seek_func = MFSound_VorbisSeek;
	callbacks.close_func = MFFile_StdClose;
	callbacks.tell_func = MFFile_StdTell;

	// open vorbis file
	if(ov_test_callbacks(hFile, &pVS->vorbisFile, NULL, 0, callbacks))
	{
		MFDebug_Assert(false, "Not a vorbis file.");
		MFHeap_Free(pVS);
		return;
	}

	ov_test_open(&pVS->vorbisFile);

	// get vorbis file info
	pVS->pInfo = ov_info(&pVS->vorbisFile, -1);

#if defined(VORBIS_TREMOR)
//	pStream->trackLength = (float)ov_pcm_total(&pVS->vorbisFile, -1) / (float)pVS->pInfo->rate;
	pStream->trackLength = 1000.0f;
#else
	pStream->trackLength = (float)ov_time_total(&pVS->vorbisFile, -1);
#endif

	// fill out the stream info
	pStream->streamInfo.sampleRate = pVS->pInfo->rate;
	pStream->streamInfo.channels = pVS->pInfo->channels;
	pStream->streamInfo.bitsPerSample = 16;
	pStream->streamInfo.bufferLength = pVS->pInfo->rate;

	// read the vorbis comment data
	pVS->pComment = ov_comment(&pVS->vorbisFile, -1);
	if(pVS->pComment)
	{
		const char *pTitle = vorbis_comment_query(pVS->pComment, "TITLE", 0);
		const char *pArtist = vorbis_comment_query(pVS->pComment, "ALBUM", 0);
		const char *pAlbum = vorbis_comment_query(pVS->pComment, "ARTIST", 0);
		const char *pGenre = vorbis_comment_query(pVS->pComment, "GENRE", 0);

		if(pTitle)
			MFString_CopyN(pStream->streamInfo.songName, pTitle, sizeof(pStream->streamInfo.songName)-1);
		if(pArtist)
			MFString_CopyN(pStream->streamInfo.artistName, pArtist, sizeof(pStream->streamInfo.artistName)-1);
		if(pAlbum)
			MFString_CopyN(pStream->streamInfo.albumName, pAlbum, sizeof(pStream->streamInfo.albumName)-1);
		if(pGenre)
			MFString_CopyN(pStream->streamInfo.genre, pGenre, sizeof(pStream->streamInfo.genre)-1);
	}
}
Exemplo n.º 16
0
int32_t MV_PlayLoopedVorbis
(
 char *ptr,
 uint32_t ptrlength,
 int32_t   loopstart,
 int32_t   loopend,
 int32_t   pitchoffset,
 int32_t   vol,
 int32_t   left,
 int32_t   right,
 int32_t   priority,
 uint32_t callbackval
 )

{
   VoiceNode   *voice;
   int32_t          status;
   vorbis_data * vd = 0;
   vorbis_info * vi = 0;
 
   UNREFERENCED_PARAMETER(loopend);

   if ( !MV_Installed )
   {
      MV_SetErrorCode( MV_NotInstalled );
      return( MV_Error );
   }
   
   vd = (vorbis_data *) malloc( sizeof(vorbis_data) );
   if (!vd) {
      MV_SetErrorCode( MV_InvalidVorbisFile );
      return MV_Error;
   }
   
   memset(vd, 0, sizeof(vorbis_data));
   vd->ptr = ptr;
   vd->pos = 0;
   vd->length = ptrlength;
   vd->lastbitstream = -1;
   
   status = ov_open_callbacks((void *) vd, &vd->vf, 0, 0, vorbis_callbacks);
   if (status < 0) {
      MV_Printf("MV_PlayLoopedVorbis: err %d\n", status);
      MV_SetErrorCode( MV_InvalidVorbisFile );
      return MV_Error;
   }
   
   vi = ov_info(&vd->vf, 0);
   if (!vi) {
      ov_clear(&vd->vf);
      free(vd);
      MV_SetErrorCode( MV_InvalidVorbisFile );
      return MV_Error;
   }
   
   if (vi->channels != 1 && vi->channels != 2) {
      ov_clear(&vd->vf);
      free(vd);
      MV_SetErrorCode( MV_InvalidVorbisFile );
      return MV_Error;
   }
   
   // Request a voice from the voice pool
   voice = MV_AllocVoice( priority );
   if ( voice == NULL )
   {
      ov_clear(&vd->vf);
      free(vd);
      MV_SetErrorCode( MV_NoVoices );
      return( MV_Error );
   }
   
   voice->wavetype    = Vorbis;
   voice->bits        = 16;
   voice->channels    = vi->channels;
   voice->extra       = (void *) vd;
   voice->GetSound    = MV_GetNextVorbisBlock;
   voice->NextBlock   = vd->block;
   voice->DemandFeed  = NULL;
   voice->LoopCount   = 0;
   voice->BlockLength = 0;
   voice->PitchScale  = PITCH_GetScale( pitchoffset );
   voice->length      = 0;
   voice->next        = NULL;
   voice->prev        = NULL;
   voice->priority    = priority;
   voice->callbackval = callbackval;
   voice->LoopStart   = (char *) (loopstart >= 0 ? TRUE : FALSE);
   voice->LoopEnd     = 0;
   voice->LoopSize    = 0;
   voice->Playing     = TRUE;
   voice->Paused      = FALSE;
   
   voice->SamplingRate = vi->rate;
   voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
   voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
      voice->RateScale;
   MV_SetVoiceMixMode( voice );

   MV_SetVoiceVolume( voice, vol, left, right );
   MV_PlayVoice( voice );
   
   return( voice->handle );
}
Exemplo n.º 17
0
    /* open ogg/vorbis file */                 
static void oggread_open(t_oggread *x, t_symbol *filename)
{
	int i;

	x->x_stream = 0;
		/* first close previous file */
	if(x->x_fd > 0)
	{
		ov_clear(&x->x_ov);
		post("oggread~: previous file closed");
	}
		/* open file for reading */
#ifdef WIN32
	if((x->x_file = fopen(filename->s_name, "rb")) < 0)
#else
   if((x->x_file = fopen(filename->s_name, "r")) < 0)
#endif
    {
		post("oggread~: could not open file \"%s\"", filename->s_name);
		x->x_eos = 1;
		x->x_fd = -1;
    }
    else
    {
		x->x_stream = 0;
		x->x_eos = 0;
		x->x_fd = 1;
		x->x_outreadposition = 0;
		x->x_outwriteposition = 0;
		x->x_outunread = 0;
		post("oggread~: file \"%s\" opened", filename->s_name);
		outlet_float( x->x_out_position, 0);

			/* try to open as ogg vorbis file */
		if(ov_open(x->x_file, &x->x_ov, NULL, -1) < 0)
		{		/* an error occured (no ogg vorbis file ?) */
			post("oggread~: error: could not open \"%s\" as an OggVorbis file", filename->s_name);
			ov_clear(&x->x_ov);
			post("oggread~: file closed due to error");
      x->x_fd=-1;
      x->x_eos=1;
      return;
		}

			/* print details about each logical bitstream in the input */
		if(ov_seekable(&x->x_ov))
		{
			post("oggread~: input bitstream contained %ld logical bitstream section(s)", ov_streams(&x->x_ov));
			post("oggread~: total bitstream playing time: %ld seconds", (long)ov_time_total(&x->x_ov,-1));
			post("oggread~: encoded by: %s\n",ov_comment(&x->x_ov,-1)->vendor);
		}
		else
		{
			post("oggread~: file \"%s\" was not seekable\n"
			"oggread~: first logical bitstream information:", filename->s_name);
		}

		for(i = 0; i < ov_streams(&x->x_ov); i++)
		{
			x->x_vi = ov_info(&x->x_ov,i);
			post("\tlogical bitstream section %d information:",i+1);
			post("\t\t%ldHz %d channels bitrate %ldkbps serial number=%ld",
				x->x_vi->rate,x->x_vi->channels,ov_bitrate(&x->x_ov,i)/1000, ov_serialnumber(&x->x_ov,i));
			post("\t\theader length: %ld bytes",(long)
			(x->x_ov.dataoffsets[i] - x->x_ov.offsets[i]));
			post("\t\tcompressed length: %ld bytes",(long)(ov_raw_total(&x->x_ov,i)));
			post("\t\tplay time: %ld seconds\n",(long)ov_time_total(&x->x_ov,i));
		}

    } 
}
Exemplo n.º 18
0
ALOGG_OGGSTREAM *alogg_create_oggstream(void *first_data_buffer, int data_buffer_len, int last_block) {
  ALOGG_OGGSTREAM *ogg;
  vorbis_info *vi;
  int ret;
  void *databuf1, *databuf2, *full_databuf;

  /* create a new ogg struct */
  ogg = (ALOGG_OGGSTREAM *)malloc(sizeof(ALOGG_OGGSTREAM));
  if (ogg == NULL)
    return NULL;

  /* allocate the buffers */
  databuf1 = malloc(data_buffer_len);
  if (databuf1 == NULL) {
    free((void *)ogg);
    return NULL;
  }
  databuf2 = malloc(data_buffer_len);
  if (databuf2 == NULL) {
    free((void *)ogg);
    free(databuf1);
    return NULL;
  }
  full_databuf = malloc(data_buffer_len * 2);
  if (full_databuf == NULL) {
    free((void *)ogg);
    free(databuf1);
    free(databuf2);
    return NULL;
  }

  /* copy the first data */
  memcpy(databuf1, first_data_buffer, data_buffer_len);

  /* fill in the ogg struct */
  ogg->databuf1 = databuf1;
  ogg->databuf2 = databuf2;
  ogg->full_databuf = (char *)full_databuf;
  ogg->data_cursor = 0;
  ogg->databuf_selector = 1;
  ogg->databuf_len = data_buffer_len;
  ogg->unsel_databuf_free = TRUE;
  if (last_block)
    ogg->bytes_used = data_buffer_len;
  else
    ogg->bytes_used = -1;
  ogg->audiostream = NULL;
  ogg->auto_polling = FALSE;

  /* use vorbisfile to open it */
  ret = ov_open_callbacks((void *)ogg, &(ogg->vf), NULL, 0, _alogg_oggstream_callbacks);

  /* if error */
  if (ret < 0) {
    free((void *)ogg);
    free((void *)databuf1);
    free((void *)databuf2);
    free((void *)full_databuf);
    return NULL;
  }

  /* get audio info */
  vi = ov_info(&(ogg->vf), -1);
  if (vi->channels > 1)
    ogg->stereo = TRUE;
  else
    ogg->stereo = FALSE;
  ogg->freq = vi->rate;

  return ogg;
}
Exemplo n.º 19
0
Arquivo: sfx.cpp Projeto: ACefalu/tzod
static void ogg_load_vorbis(const char *filename, WAVEFORMATEX *pwf, std::vector<char> *data)
{
	SafePtr<FS::Stream> s = g_fs->Open(filename)->QueryStream();

	ov_callbacks cb;
	cb.read_func  = read_func;
	cb.seek_func  = seek_func;
	cb.close_func = NULL;
	cb.tell_func  = tell_func;

	OggVorbis_File vf;
	if( int result = ov_open_callbacks(s, &vf, NULL, 0, cb) )
	{
		switch( result )
		{
		case OV_EREAD: throw std::runtime_error("A read from media returned an error");
		case OV_ENOTVORBIS: throw std::runtime_error("Bitstream does not contain any Vorbis data");
		case OV_EVERSION: throw std::runtime_error("Vorbis version mismatch");
		case OV_EBADHEADER: throw std::runtime_error("Invalid Vorbis bitstream header");
		case OV_EFAULT: throw std::runtime_error("Internal logic fault; indicates a bug or heap/stack corruption");
		}
		throw std::runtime_error("unknown error opening ov stream");
	}

	try
	{
		vorbis_info *pinfo = ov_info(&vf, -1);
		if( NULL == pinfo )
		{
			throw std::runtime_error("could not get info from ov stream");
		}


		pwf->wFormatTag       = WAVE_FORMAT_PCM;
		pwf->nChannels        = pinfo->channels;
		pwf->nSamplesPerSec   = pinfo->rate;
		pwf->nAvgBytesPerSec  = pinfo->rate * pinfo->channels * 2;
		pwf->nBlockAlign      = pinfo->channels * 2;
		pwf->wBitsPerSample   = 16;
		pwf->cbSize           = 0;

		size_t size = static_cast<size_t>(ov_pcm_total(&vf, -1) * pwf->nBlockAlign);
		data->resize(size);

		int    bitstream = 0;
		size_t total = 0;

		while( total < size )
		{
			long ret = ov_read(&vf, &data->at(total), size - total, 0, 2, 1, &bitstream);
			if( 0 == ret )
			{
				break; // eof
			}
			if( ret < 0 )
			{
				// error in stream
				switch( ret )
				{
				case OV_HOLE:
					throw std::runtime_error("garbage between pages, loss of sync followed by recapture, or a corrupt page");
				case OV_EBADLINK:
					throw std::runtime_error("invalid stream section or the requested link is corrupt");
				case OV_EINVAL:
					throw std::runtime_error("initial file headers couldn't be read or are corrupt");
				}
				throw std::runtime_error("unknown error in ov stream");
			}
			else
			{
				total += ret;
			}
		}
	}
	catch( const std::exception& )
	{
		ov_clear(&vf);
		throw;
	}
	ov_clear(&vf);
}
Exemplo n.º 20
0
Arquivo: oggwav.c Projeto: Hkau/kth
int main(int argc, char *argv[])
{
	printf("\nOgg to WAV decoder/converter.\n\n");
	if(argc > 2)
	{
		printf("No input file.\n\n");
		
		return 1;
	}

	OggVorbis_File vf;

	if(ov_fopen(argv[1], &vf) < 0)
	{
		printf("Unable to open file: \"%s\".\n\n");
		return 1;
	}
	
	vorbis_info *vi = ov_info(&vf, -1);

	printf("Vorbis file info:\n\n");
	printf("Channels: %d\n", vi->channels);
	printf("Samples: %ld\n", ov_pcm_total(&vf, -1));
	printf("Samplerate: %d.\n", vi->rate);
	printf("\nLength: ~%ld s.\n", ov_pcm_total(&vf, -1)/vi->rate);


	uint32_t pcm_size = ov_pcm_total(&vf, -1) * vi->channels * 2;
	printf("\nPCM size: %ld bytes.\n", pcm_size);
	printf("\nWAV size: %ld bytes.\n", pcm_size+44);

	char buffer[4096];

	FILE *out = fopen("out.wav", "wb");

	if(out == NULL)
	{
		printf("Unable to open outfile for writing.\n\n");
		return 1;
	}

	uint32_t temp32;
	uint16_t temp16;

	// Chunk header
	memcpy(buffer, "RIFF", 4);
	temp32 = 36+pcm_size;
	memcpy(&temp32, &buffer[4], 4);
	memcpy(&buffer[8], "WAVE", 4);

	// SubChunk1
	memcpy(&buffer[12], "fmt ", 4);
	temp32 = 16;
	memcpy(&buffer[16], &temp32, 4);
	temp16 = 1;
	memcpy(&buffer[20], &temp16, 2);
	temp16 = vi->channels;
	memcpy(&buffer[22], &temp16, 2);
	temp32 = vi->rate;
	memcpy(&buffer[24], &temp32, 4);
	temp32 = vi->rate * vi->channels * 2;
	memcpy(&buffer[28], &temp32, 4);
	temp16 = vi->channels * 2;
	memcpy(&buffer[32], &temp16, 2);
	temp16 = 16;
	memcpy(&buffer[34], &temp16, 2);
	
	// SubChunk2
	memcpy(&buffer[36], "data", 4);
	memcpy(&buffer[40], &pcm_size, 4);
	
	// Write WAV header
	fwrite(buffer, 1, 44, out);

	printf("\nDecoding:\n\n");
	int current_section;

	while(1)
	{
		long ret = ov_read(&vf, buffer,sizeof(buffer), 0, 2, 1, &current_section);
		if(ret == 0)
			break;

		if(ret < 0)
		{
			printf("Error while reading.\n");
			break;
		}
		
		fwrite(buffer, 1, ret, out);
	}

	printf("Done.\n");
	fclose(out);	

	ov_clear(&vf);

	return 0;
}
//-----------------------------------------------------------------------------
bool MusicOggStream::load(const std::string& filename)
{
    if (isPlaying()) stopMusic();
    
    m_error = true;
    m_fileName = filename;
    if(m_fileName=="") return false;  

    m_oggFile = fopen(m_fileName.c_str(), "rb");

    if(!m_oggFile)
    {
        printf("Loading Music: %s failed (fopen returned NULL)\n", m_fileName.c_str());
        return false;
    }
    
#if defined( WIN32 ) || defined( WIN64 )
    const int result = ov_open_callbacks((void *)m_oggFile, &m_oggStream, NULL, 0, OV_CALLBACKS_DEFAULT);
#else
    const int result = ov_open(m_oggFile, &m_oggStream, NULL, 0);
#endif
    
    if (result < 0)
    {
        fclose(m_oggFile);
        
        
        const char* errorMessage;
        switch (result)
        {
            case OV_EREAD:
                errorMessage = "OV_EREAD";
                break;
            case OV_ENOTVORBIS:
                errorMessage = "OV_ENOTVORBIS";
                break;
            case OV_EVERSION:
                errorMessage = "OV_EVERSION";
                break;
            case OV_EBADHEADER:
                errorMessage = "OV_EBADHEADER";
                break;
            case OV_EFAULT:
                errorMessage = "OV_EFAULT";
                break;
            default:
                errorMessage = "Unknown Error";
        }
        
        printf("Loading Music: %s failed : ov_open returned error code %i (%s)\n",
               m_fileName.c_str(), result, errorMessage);
        return false;
    }
    
    m_vorbisInfo = ov_info(&m_oggStream, -1);

    if (m_vorbisInfo->channels == 1) nb_channels = AL_FORMAT_MONO16;
    else                             nb_channels = AL_FORMAT_STEREO16;

    alGenBuffers(2, m_soundBuffers);
    if (check("alGenBuffers") == false) return false;

    alGenSources(1, &m_soundSource);
    if (check("alGenSources") == false) return false;

    alSource3f(m_soundSource, AL_POSITION,        0.0, 0.0, 0.0);
    alSource3f(m_soundSource, AL_VELOCITY,        0.0, 0.0, 0.0);
    alSource3f(m_soundSource, AL_DIRECTION,       0.0, 0.0, 0.0);
    alSourcef (m_soundSource, AL_ROLLOFF_FACTOR,  0.0          );
    alSourcef (m_soundSource, AL_GAIN,            1.0          );
    alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE      );

    m_error=false;
    return true;
}   // load
	Buffer* LoadOGG(const char* name, const void* data, size_t size)
	{
		Buffer* b = new Buffer(name);
		OggStaticFile fp(data,size);

		long bytes;
		std::vector<char> buffer;
		int bitStream;
		char arr[OGG_STATIC_BUFFER_SIZE] = {0};
		OggVorbis_File oggStream;
		vorbis_info* vorbisInfo;
		ALenum format;
		ALsizei freq;
		ALint isize;
		ALint d = 1;

		if (ov_open_callbacks(&fp,&oggStream,NULL,0,OggStaticGetCallback()) != 0)
		{
			freeslw::ErrorPrintf("Failed to load \"%s\"",name);
			delete b; return 0;
		}

		alGenBuffers(1,&b->bufferId[0]);
		if (b->bufferId[0] == NO_BUFFER)
		{
			freeslw::ErrorPrintf("Failed to create buffer for \"%s\"",name);
			delete b; return 0;
		}

		vorbisInfo = ov_info(&oggStream,-1);
		format = (vorbisInfo->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
		freq = vorbisInfo->rate;

		do
		{
			bytes = ov_read(&oggStream,arr,OGG_STATIC_BUFFER_SIZE, 0, 2, 1, &bitStream);
			buffer.insert(buffer.end(),arr,arr + bytes);
		} while (bytes > 0);

		ov_clear(&oggStream);

		alBufferData(b->bufferId[0],format,&buffer[0],(ALsizei)buffer.size(),freq);
		alGetBufferi(b->bufferId[0],AL_SIZE,&isize);

			 if (format == AL_FORMAT_MONO8) b->format = freeslw::TA_MONO8;
		else if (format == AL_FORMAT_MONO16) b->format = freeslw::TA_MONO16;
		else if (format == AL_FORMAT_STEREO8) b->format = freeslw::TA_STEREO8;
		else if (format == AL_FORMAT_STEREO16) b->format = freeslw::TA_STEREO16;
		else freeslw::ErrorPrintf("Failed to retrieve a valid sound format (format = %d)",format);

		if (b->format == freeslw::TA_MONO16 || b->format == freeslw::TA_STEREO8) d = 2; else if (format == freeslw::TA_STEREO16) d = 4;

		if (freq == 0)
		{
			freeslw::ErrorPrintf("\"%s\": Frequency = 0",name);
			freq = 1;
		}

		b->frequency = (int)freq;
		b->length = (isize * 1000) / (freq * d);
		b->activeBuffer = 0;
		b->numBuffers = 1;

		return b;
	}
Exemplo n.º 23
0
void CSoundRender_Source::LoadWave	(LPCSTR pName)
{
	pname					= pName;

	// Load file into memory and parse WAV-format
	OggVorbis_File			ovf;
	ov_callbacks ovc		= {ov_read_func,ov_seek_func,ov_close_func,ov_tell_func};
	IReader* wave			= FS.r_open		(pname.c_str()); 
	R_ASSERT3				(wave&&wave->length(),"Can't open wave file:",pname.c_str());
	ov_open_callbacks		(wave,&ovf,NULL,0,ovc);

	vorbis_info* ovi		= ov_info(&ovf,-1);
	// verify
	R_ASSERT3				(ovi,"Invalid source info:",pName);
	R_ASSERT3				(ovi->channels==1,"Invalid source num channels:",pName);
	R_ASSERT3				(ovi->rate==44100,"Invalid source rate:",pName);

	WAVEFORMATEX wfxdest 	= SoundRender->wfm;
	wfxdest.nChannels		= u16(ovi->channels); 
	wfxdest.nBlockAlign		= wfxdest.nChannels * wfxdest.wBitsPerSample / 8;
	wfxdest.nAvgBytesPerSec = wfxdest.nSamplesPerSec * wfxdest.nBlockAlign;

	s64 pcm_total			= ov_pcm_total(&ovf,-1);
	if (psSoundFreq==sf_22K) pcm_total/=2;
	dwBytesTotal			= u32(pcm_total*wfxdest.nBlockAlign); 
	dwBytesPerMS			= wfxdest.nAvgBytesPerSec/1000;
//	dwBytesPerSec			= wfxdest.nAvgBytesPerSec;
	dwTimeTotal				= u32 ( sdef_source_footer + u64( (u64(dwBytesTotal)*u64(1000))/u64(wfxdest.nAvgBytesPerSec) ) );

	vorbis_comment*	ovm		= ov_comment(&ovf,-1);
	if (ovm->comments){
		IReader F			(ovm->user_comments[0],ovm->comment_lengths[0]);
		u32 vers			= F.r_u32	();
        if (vers==0x0001){
			m_fMinDist		= F.r_float	();
			m_fMaxDist		= F.r_float	();
	        m_fBaseVolume	= 1.f;
			m_uGameType		= F.r_u32	();
			m_fMaxAIDist	= m_fMaxDist;
		}else if (vers==0x0002){
			m_fMinDist		= F.r_float	();
			m_fMaxDist		= F.r_float	();
			m_fBaseVolume	= F.r_float	();
			m_uGameType		= F.r_u32	();
			m_fMaxAIDist	= m_fMaxDist;
		}else if (vers==OGG_COMMENT_VERSION){
			m_fMinDist		= F.r_float	();
			m_fMaxDist		= F.r_float	();
            m_fBaseVolume	= F.r_float	();
			m_uGameType		= F.r_u32	();
			m_fMaxAIDist	= F.r_float	();
		}else{
			Log				("! Invalid ogg-comment version, file: ",pName);
		}
	}else{
		Log					("! Missing ogg-comment, file: ",pName);
	}
	R_ASSERT3((m_fMaxAIDist>=0.1f)&&(m_fMaxDist>=0.1f),"Invalid max distance.",pName);

	ov_clear				(&ovf);
	FS.r_close				(wave);
}
Exemplo n.º 24
0
VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const char * filename, ov_callbacks *callbacks_p, off_t other_header_bytes, const vgm_vorbis_info_t *vgm_inf) {
    VGMSTREAM * vgmstream = NULL;

    OggVorbis_File temp_ovf;
    ogg_vorbis_streamfile temp_streamfile;

    ogg_vorbis_codec_data * data = NULL;
    OggVorbis_File *ovf;
    int inited_ovf = 0;
    vorbis_info *info;

    int loop_flag = vgm_inf->loop_flag;
    int32_t loop_start = vgm_inf->loop_start;
    int loop_length_found = vgm_inf->loop_length_found;
    int32_t loop_length = vgm_inf->loop_length;
    int loop_end_found = vgm_inf->loop_end_found;
    int32_t loop_end = vgm_inf->loop_end;

    ov_callbacks default_callbacks;

    if (!callbacks_p) {
        default_callbacks.read_func = read_func;
        default_callbacks.seek_func = seek_func;
        default_callbacks.close_func = close_func;
        default_callbacks.tell_func = tell_func;

        if (vgm_inf->scd_xor != 0) {
            default_callbacks.read_func = read_func_scd;
        }

        callbacks_p = &default_callbacks;
    }

    temp_streamfile.streamfile = streamFile;
    temp_streamfile.offset = 0;
    temp_streamfile.size = get_streamfile_size(temp_streamfile.streamfile);
    temp_streamfile.other_header_bytes = other_header_bytes;
    temp_streamfile.scd_xor  = vgm_inf->scd_xor;
    temp_streamfile.scd_xor_len = vgm_inf->scd_xor_len;

    /* can we open this as a proper ogg vorbis file? */
    memset(&temp_ovf, 0, sizeof(temp_ovf));
    if (ov_test_callbacks(&temp_streamfile, &temp_ovf, NULL,
            0, *callbacks_p)) goto fail;

    /* we have to close this as it has the init_vgmstream meta-reading
       STREAMFILE */
    ov_clear(&temp_ovf);

    /* proceed to open a STREAMFILE just for this stream */
    data = calloc(1,sizeof(ogg_vorbis_codec_data));
    if (!data) goto fail;

    data->ov_streamfile.streamfile = streamFile->open(streamFile,filename,
            STREAMFILE_DEFAULT_BUFFER_SIZE);
    if (!data->ov_streamfile.streamfile) goto fail;
    data->ov_streamfile.offset = 0;
    data->ov_streamfile.size = get_streamfile_size(data->ov_streamfile.streamfile);
    data->ov_streamfile.other_header_bytes = other_header_bytes;
    data->ov_streamfile.scd_xor  = vgm_inf->scd_xor;
    data->ov_streamfile.scd_xor_len = vgm_inf->scd_xor_len;

    /* open the ogg vorbis file for real */
    if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL,
                0, *callbacks_p)) goto fail;
    ovf = &data->ogg_vorbis_file;
    inited_ovf = 1;

    data->bitstream = DEFAULT_BITSTREAM;

    info = ov_info(ovf,DEFAULT_BITSTREAM);

    /* grab the comments */
    {
        int i;
        vorbis_comment *comment;

        comment = ov_comment(ovf,DEFAULT_BITSTREAM);

        /* search for a "loop_start" comment */
        for (i=0;i<comment->comments;i++) {
            if (strstr(comment->user_comments[i],"loop_start=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOP_START=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"COMMENT=LOOPPOINT=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOPSTART=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"um3.stream.looppoint.start=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LOOP_BEGIN=")==
                    comment->user_comments[i] ||
                strstr(comment->user_comments[i],"LoopStart=")==
                    comment->user_comments[i]
                    ) {
                loop_start=atol(strrchr(comment->user_comments[i],'=')+1);
                if (loop_start >= 0)
                    loop_flag=1;
            }
            else if (strstr(comment->user_comments[i],"LOOPLENGTH=")==
                    comment->user_comments[i]) {
                loop_length=atol(strrchr(comment->user_comments[i],'=')+1);
                loop_length_found=1;
            }
            else if (strstr(comment->user_comments[i],"title=-lps")==
                    comment->user_comments[i]) {
                loop_start=atol(comment->user_comments[i]+10);
                if (loop_start >= 0)
                    loop_flag=1;
            }
            else if (strstr(comment->user_comments[i],"album=-lpe")==
                    comment->user_comments[i]) {
                loop_end=atol(comment->user_comments[i]+10);
                loop_flag=1;
                loop_end_found=1;
            }
            else if (strstr(comment->user_comments[i],"LoopEnd=")==
                    comment->user_comments[i]) {
						if(loop_flag) {
							loop_length=atol(strrchr(comment->user_comments[i],'=')+1)-loop_start;
							loop_length_found=1;
						}
            }
            else if (strstr(comment->user_comments[i],"LOOP_END=")==
                    comment->user_comments[i]) {
						if(loop_flag) {
							loop_length=atol(strrchr(comment->user_comments[i],'=')+1)-loop_start;
							loop_length_found=1;
						}
            }
            else if (strstr(comment->user_comments[i],"lp=")==
                    comment->user_comments[i]) {
                sscanf(strrchr(comment->user_comments[i],'=')+1,"%d,%d",
                        &loop_start,&loop_end);
                loop_flag=1;
                loop_end_found=1;
            }
            else if (strstr(comment->user_comments[i],"COMMENT=loop(")==
                    comment->user_comments[i]) {
                sscanf(strrchr(comment->user_comments[i],'(')+1,"%d,%d",
                        &loop_start,&loop_end);
                loop_flag=1;
                loop_end_found=1;
            }
        }
    }

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(info->channels,loop_flag);
    if (!vgmstream) goto fail;

    /* store our fun extra datas */
    vgmstream->codec_data = data;

    /* fill in the vital statistics */
    vgmstream->channels = info->channels;
    vgmstream->sample_rate = info->rate;

    /* let's play the whole file */
    vgmstream->num_samples = ov_pcm_total(ovf,-1);

    if (loop_flag) {
        vgmstream->loop_start_sample = loop_start;
        if (loop_length_found)
            vgmstream->loop_end_sample = loop_start+loop_length;
        else if (loop_end_found)
            vgmstream->loop_end_sample = loop_end;
        else
            vgmstream->loop_end_sample = vgmstream->num_samples;
        vgmstream->loop_flag = loop_flag;

        if (vgmstream->loop_end_sample > vgmstream->num_samples)
            vgmstream->loop_end_sample = vgmstream->num_samples;
    }
    vgmstream->coding_type = coding_ogg_vorbis;
    vgmstream->layout_type = vgm_inf->layout_type;
    vgmstream->meta_type = vgm_inf->meta_type;

    return vgmstream;

    /* clean up anything we may have opened */
fail:
    if (data) {
        if (inited_ovf)
            ov_clear(&data->ogg_vorbis_file);
        if (data->ov_streamfile.streamfile)
            close_streamfile(data->ov_streamfile.streamfile);
        free(data);
    }
    if (vgmstream) {
        vgmstream->codec_data = NULL;
        close_vgmstream(vgmstream);
    }
    return NULL;
}
Sound* AudioStreamer::LoadSound(IXAudio2* xaudio2, const std::string& file)
{
	if( !xaudio2 )
	{
		SND_ERROR("AudioStreamer::LoadSound(): NULL == xaudio2");
		return false;
	}

	FILE* infile = NULL;
	fopen_s(&infile, file.c_str(), "rb");

	if( !infile )
	{
		SND_ERROR("AudioStreamer::LoadSound(): Could not open file");
		return NULL;
	}

	OggVorbis_File oggfile;
	int stream;
	long readbytes = 0;
	long totalread = 0;

	ov_open(infile, &oggfile, NULL, 0);
	vorbis_info* info = ov_info(&oggfile, -1);

	Sound* s = new Sound();

	s->format.nChannels = info->channels;
	s->format.cbSize = sizeof(WAVEFORMATEX);
	s->format.wBitsPerSample = 16;
	s->format.nSamplesPerSec = info->rate;
	s->format.nAvgBytesPerSec = info->rate * 2 * info->channels;
	s->format.nBlockAlign = 2 * info->channels;
	s->format.wFormatTag = 1;
	
	s->totalsize = (unsigned int)ov_pcm_total(&oggfile, -1) * 2 * info->channels;
	s->data[0] = new char[s->totalsize];

	do
	{
		readbytes = ov_read(&oggfile, s->data[0] + totalread, s->totalsize - totalread, 0, 2, 1, &stream);
		totalread += readbytes;
	}
	while( readbytes > 0 && (unsigned int)totalread < s->totalsize );

	ov_clear(&oggfile);
	
	// create xaudio voice object
	if( FAILED(xaudio2->CreateSourceVoice(&s->voice, &s->format, 0, 2.0f, s)) )
	{
		SND_ERROR("AudioStreamer::LoadSound(): Could not create source voice");

		delete s;
		return NULL;
	}

	XAUDIO2_BUFFER audbuff;
	memset(&audbuff, 0, sizeof(XAUDIO2_BUFFER));

	audbuff.pAudioData = (const BYTE*)s->data[0];
	audbuff.Flags = XAUDIO2_END_OF_STREAM;
	audbuff.AudioBytes = s->totalsize;
	audbuff.LoopCount = XAUDIO2_LOOP_INFINITE;

	if( FAILED(s->voice->SubmitSourceBuffer(&audbuff)) )
	{
		SND_ERROR("AudioStreamer::LoadSound(): Could not submit buffer");

		delete s;
		return NULL;
	}

	s->canplay = true;

	// called from main thread
	soundguard.Lock();
	sound.push_back(s);
	soundguard.Unlock();

	return s;
}
Exemplo n.º 26
0
int FileVorbis::open_file(int rd, int wr)
{

	int result = 0;

//printf("FileVorbis::open_file 1\n");
	if(rd)
	{
//printf("FileVorbis::open_file 1\n");
		if(!(fd = fopen(asset->path, "rb")))
		{
			eprintf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
			result = 1;
		}
		else
		{
//printf("FileVorbis::open_file 2 %p %p\n", fd, vf);
			if(ov_open(fd, &vf, NULL, 0) < 0)
			{
				eprintf(_("FileVorbis::open_file %s: invalid bitstream.\n"), asset->path);
				result = 1;
			}
			else
			{
//printf("FileVorbis::open_file 1\n");
				vorbis_info *vi = ov_info(&vf, -1);
				asset->channels = vi->channels;
				if(!asset->sample_rate)
					asset->sample_rate = vi->rate;
//printf("FileVorbis::open_file 1\n");
				asset->audio_length = ov_pcm_total(&vf,-1);
//printf("FileVorbis::open_file 1\n");
				asset->audio_data = 1;
// printf("FileVorbis::open_file 1 %d %d %d\n", 
// asset->channels, 
// asset->sample_rate, 
// asset->audio_length);
			}
		}
	}

	if(wr)
	{
		if(!(fd = fopen(asset->path, "wb")))
		{
			eprintf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
			result = 1;
		}
		else
		{
			vorbis_info_init(&vi);
			if(!asset->vorbis_vbr)
				result = vorbis_encode_init(&vi, 
					asset->channels, 
					asset->sample_rate, 
					asset->vorbis_max_bitrate, 
					asset->vorbis_bitrate, 
					asset->vorbis_min_bitrate);
			else
			{
				result = vorbis_encode_setup_managed(&vi,
					asset->channels, 
					asset->sample_rate, 
					asset->vorbis_max_bitrate, 
					asset->vorbis_bitrate, 
					asset->vorbis_min_bitrate);
				result |= vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_AVG, NULL);
				result |= vorbis_encode_setup_init(&vi);
			}

			if(!result)
			{
				vorbis_analysis_init(&vd, &vi);
				vorbis_block_init(&vd, &vb);
				vorbis_comment_init(&vc);
				srand(time(NULL));
				ogg_stream_init(&os, rand());

				ogg_packet header;
				ogg_packet header_comm;
				ogg_packet header_code;
				vorbis_analysis_headerout(&vd, 
					&vc,
					&header,
					&header_comm,
					&header_code);
				ogg_stream_packetin(&os,
					&header);
				ogg_stream_packetin(&os, 
					&header_comm);
				ogg_stream_packetin(&os,
					&header_code);

				while(1)
				{
					int result = ogg_stream_flush(&os, &og);
					if(result == 0) break;
					fwrite(og.header, 1, og.header_len, fd);
					fwrite(og.body, 1, og.body_len, fd);
				}
			}
		}
	}

//printf("FileVorbis::open_file 2\n");
	return result;
}
Exemplo n.º 27
0
Arquivo: OGG.cpp Projeto: hcwdikk/lime
	bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) {
		
		OggVorbis_File oggFile;
		
		if (resource->path) {
			
			FILE_HANDLE *file = lime::fopen (resource->path, "rb");
			
			if (!file) {
				
				return false;
				
			}
			
			if (file->isFile ()) {
				
				ov_open (file->getFile (), &oggFile, NULL, file->getLength ());
				
			} else {
				
				ByteArray data = ByteArray (resource->path);
				
				OAL_OggMemoryFile fakeFile = { data.Bytes (), data.Size (), 0 };
				
				if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {
					
					return false;
					
				}
				
			}
			
		} else {
			
			OAL_OggMemoryFile fakeFile = { resource->data->Bytes (), resource->data->Size (), 0 };
			
			if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {
				
				return false;
				
			}
			
		}
		
		// 0 for Little-Endian, 1 for Big-Endian
		#ifdef HXCPP_BIG_ENDIAN
		#define BUFFER_READ_TYPE 1
		#else
		#define BUFFER_READ_TYPE 0
		#endif
		
		int bitStream;
		long bytes = 1;
		int totalBytes = 0;
		
		#define BUFFER_SIZE 32768
		
		vorbis_info *pInfo = ov_info (&oggFile, -1);            
		
		if (pInfo == NULL) {
			
			//LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n");
			return false;
			
		}
		
		audioBuffer->channels = pInfo->channels;
		audioBuffer->sampleRate = pInfo->rate;
		
		//default to 16? todo 
		audioBuffer->bitsPerSample = 16;
		
		// Seem to need four times the read PCM total
		audioBuffer->data->Resize (ov_pcm_total (&oggFile, -1) * 4);
		
		while (bytes > 0) {
			
			if (audioBuffer->data->Size () < totalBytes + BUFFER_SIZE) {
				
				audioBuffer->data->Resize (totalBytes + BUFFER_SIZE);
				
			}
			
			bytes = ov_read (&oggFile, (char *)audioBuffer->data->Bytes () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream);
			totalBytes += bytes;
			
		}
		
		audioBuffer->data->Resize (totalBytes);
		ov_clear (&oggFile);
		
		#undef BUFFER_SIZE
		#undef BUFFER_READ_TYPE
		
		return true;
		
	}
Exemplo n.º 28
0
int main(){
  OggVorbis_File ov;
  int i,ret;
  ogg_int64_t pcmlength;
  double timelength;
  char *bigassbuffer;
  int dummy;
  int hs=0;

#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
  _setmode( _fileno( stdin ), _O_BINARY );
#endif


  /* open the file/pipe on stdin */
  if(ov_open_callbacks(stdin,&ov,NULL,-1,OV_CALLBACKS_NOCLOSE)<0){
    fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
    exit(1);
  }

#if 0 /*enable this code to test seeking with halfrate decode */
  if(ov_halfrate(&ov,1)){
    fprintf(stderr,"Sorry; unable to set half-rate decode.\n\n");
    exit(1);
  }else
    hs=1;
#endif

  if(ov_seekable(&ov)){

    /* to simplify our own lives, we want to assume the whole file is
       stereo.  Verify this to avoid potentially mystifying users
       (pissing them off is OK, just don't confuse them) */
    for(i=0;i<ov.links;i++){
      vorbis_info *vi=ov_info(&ov,i);
      if(vi->channels!=2){
        fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
               "that are entirely stereo.\n\n");
        exit(1);
      }
    }

    /* because we want to do sample-level verification that the seek
       does what it claimed, decode the entire file into memory */
    pcmlength=ov_pcm_total(&ov,-1);
    timelength=ov_time_total(&ov,-1);
    bigassbuffer=malloc((pcmlength>>hs)*2); /* w00t */
    i=0;
    while(i<(pcmlength>>hs)*2){
      int ret=ov_read(&ov,bigassbuffer+i,((pcmlength>>hs)*2)-i,1,1,1,&dummy);
      if(ret<0){
        fprintf(stderr,"Error reading file.\n");
        exit(1);
      }
      if(ret){
        i+=ret;
      }else{
        pcmlength=(i/2)<<hs;
      }
      fprintf(stderr,"\rloading.... [%ld left]              ",
              (long)((pcmlength>>hs)*2-i));
    }

    {
      ogg_int64_t length=ov.end;
      fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
             (long)length);

      for(i=0;i<1000;i++){
        ogg_int64_t val=(double)rand()/RAND_MAX*length;
        fprintf(stderr,"\r\t%d [raw position %ld]...     ",i,(long)val);
        ret=ov_raw_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
             (long)pcmlength);

      for(i=0;i<1000;i++){
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
        ret=ov_pcm_seek_page(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing pcm exact seeking to random places in %f seconds....\n",
             timelength);
      for(i=0;i<1000;i++){
        ogg_int64_t val= i==0?(ogg_int64_t)0:(double)rand()/RAND_MAX*pcmlength;
        fprintf(stderr,"\r\t%d [pcm position %ld]...     ",i,(long)val);
        ret=ov_pcm_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }
        if(ov_pcm_tell(&ov)!=((val>>hs)<<hs)){
          fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
                 (long)val,(long)ov_pcm_tell(&ov));
          exit(1);
        }

        _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time page seeking to random places in %f seconds....\n",
             timelength);

      for(i=0;i<1000;i++){
        double val=(double)rand()/RAND_MAX*timelength;
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
        ret=ov_time_seek_page(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }

        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r");
    {
      fprintf(stderr,"testing time exact seeking to random places in %f seconds....\n",
             timelength);

      for(i=0;i<1000;i++){
        double val=(double)rand()/RAND_MAX*timelength;
        fprintf(stderr,"\r\t%d [time position %f]...     ",i,val);
        ret=ov_time_seek(&ov,val);
        if(ret<0){
          fprintf(stderr,"seek failed: %d\n",ret);
          exit(1);
        }
        if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
          fprintf(stderr,"Declared position didn't perfectly match request: %f != %f\n",
                 val,ov_time_tell(&ov));
          exit(1);
        }

        _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);

      }
    }

    fprintf(stderr,"\r                                           \nOK.\n\n");


  }else{
Exemplo n.º 29
0
SoundBuffer* loadOggFile(const std::string &filepath)
{
	int endian = 0; // 0 for Little-Endian, 1 for Big-Endian
	int bitStream;
	long bytes;
	char array[BUFFER_SIZE]; // Local fixed size array
	vorbis_info *pInfo;
	OggVorbis_File oggFile;
	
	// Do a dumb-ass static string copy for old versions of ov_fopen
	// because they expect a non-const char*
	char nonconst[10000];
	snprintf(nonconst, 10000, "%s", filepath.c_str());
	// Try opening the given file
	//if(ov_fopen(filepath.c_str(), &oggFile) != 0)
	if(ov_fopen(nonconst, &oggFile) != 0)
	{
		infostream<<"Audio: Error opening "<<filepath<<" for decoding"<<std::endl;
		return NULL;
	}

	SoundBuffer *snd = new SoundBuffer;

	// Get some information about the OGG file
	pInfo = ov_info(&oggFile, -1);

	// Check the number of channels... always use 16-bit samples
	if(pInfo->channels == 1)
		snd->format = AL_FORMAT_MONO16;
	else
		snd->format = AL_FORMAT_STEREO16;

	// The frequency of the sampling rate
	snd->freq = pInfo->rate;

	// Keep reading until all is read
	do
	{
		// Read up to a buffer's worth of decoded sound data
		bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);

		if(bytes < 0)
		{
			ov_clear(&oggFile);
			infostream<<"Audio: Error decoding "<<filepath<<std::endl;
			return NULL;
		}

		// Append to end of buffer
		snd->buffer.insert(snd->buffer.end(), array, array + bytes);
	} while (bytes > 0);

	alGenBuffers(1, &snd->buffer_id);
	alBufferData(snd->buffer_id, snd->format,
			&(snd->buffer[0]), snd->buffer.size(),
			snd->freq);

	ALenum error = alGetError();

#ifdef NOTDEF
	if(error != AL_NO_ERROR){
		infostream<<"Audio: OpenAL error: "<<alErrorString(error)
				<<"preparing sound buffer"<<std::endl;
	}

	infostream<<"Audio file "<<filepath<<" loaded"<<std::endl;
#endif

	// Clean up!
	ov_clear(&oggFile);

	return snd;
}
Exemplo n.º 30
0
static LONG APIENTRY IOProc_Entry2(PVOID pmmioStr, USHORT usMsg, LONG lParam1,
                     LONG lParam2) {
	PMMIOINFO pmmioinfo = (PMMIOINFO)pmmioStr;
	switch (usMsg) {
	case MMIOM_OPEN:
		{	
     		HMMIO hmmioSS;
     		MMIOINFO mmioinfoSS;
	    	PSZ pszFileName = (char *)lParam1;
   	 		if (!pmmioinfo) return MMIO_ERROR;
  	  		if ((pmmioinfo->ulFlags & MMIO_READWRITE)) {
#ifdef DEBUG
			fprintf(file,"ReadWrite - requested.\n");
#endif
   	  		   return MMIO_ERROR;
  	  		}
			if (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEHEADER) &&
			    !(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA)) return MMIO_ERROR;
			if (!pmmioinfo->fccChildIOProc) {
				FOURCC fccFileStorageSystem;
				if (pmmioinfo->ulFlags & MMIO_CREATE) {
       				if (mmioDetermineSSIOProc(pszFileName, pmmioinfo, &fccFileStorageSystem, NULL)) {
              			fccFileStorageSystem = FOURCC_DOS;
              		}
       			} else {
	        		if (mmioIdentifyStorageSystem(pszFileName, pmmioinfo, &fccFileStorageSystem)) {
 		           		return MMIO_ERROR;
    	        	}
    	        }
            	if (!fccFileStorageSystem) {
             	  	return MMIO_ERROR;
            	} else {
             	  	pmmioinfo->fccChildIOProc = fccFileStorageSystem;
            	} /* endif */
			}
			memmove(&mmioinfoSS, pmmioinfo, sizeof(MMIOINFO));
			mmioinfoSS.pIOProc = NULL;
			mmioinfoSS.fccIOProc = pmmioinfo->fccChildIOProc;
			mmioinfoSS.ulFlags |= MMIO_NOIDENTIFY;
			
			hmmioSS = mmioOpen (pszFileName, &mmioinfoSS, mmioinfoSS.ulFlags);
			if (pmmioinfo->ulFlags & MMIO_DELETE) {
      			if (!hmmioSS) {
            		pmmioinfo->ulErrorRet = MMIOERR_DELETE_FAILED;
            		return MMIO_ERROR;
            	}
            	else return MMIO_SUCCESS;
			}
   			if (!hmmioSS) return MMIO_ERROR;
   			if (pmmioinfo->ulFlags & MMIO_READ) {
 			   DecInfo *decInfo = (DecInfo *)malloc(sizeof(DecInfo));
#ifdef DEBUG
			fprintf(file,"File Read: %s\n",pszFileName);
#endif
        		if (!decInfo) {
  	          		mmioClose(hmmioSS, 0);
            		return MMIO_ERROR;
	            }
				decInfo->t = READNUM;
			    decInfo->vorbisOptions = pmmioinfo->pExtraInfoStruct;
 	      		pmmioinfo->pExtraInfoStruct = (PVOID)decInfo;
  	     		{
            		ov_callbacks cb;
   	         		cb.read_func = mread;
            		cb.seek_func = mseek;
            		cb.close_func = mclose;
            		cb.tell_func = mtell;
	       			if(0 != ov_open_callbacks((void *)hmmioSS, &decInfo->oggfile, 0, 0, cb)) {
           	  			free(decInfo);
	            		mmioClose(hmmioSS, 0);
 	           			return MMIO_ERROR;
             		}
            	}
#ifdef DEBUG
				fprintf(file,"Open successfull\n");
#endif
				return MMIO_SUCCESS;
			} else if (pmmioinfo->ulFlags & MMIO_WRITE) {
	       		EncInfo *encInfo = (EncInfo *)malloc(sizeof(EncInfo));
#ifdef DEBUG
			fprintf(file,"File Write: %s\n",pszFileName);
#endif
	       		if (!encInfo) {
  	          		mmioClose(hmmioSS, 0);
            		return MMIO_ERROR;
                }
	       		memset(encInfo, 0, sizeof(EncInfo));
	       		encInfo->t = WRITENUM;
	       		encInfo->hmmioSS = hmmioSS;
				encInfo->vorbisOptions = (PVORBISOPTIONS)pmmioinfo->pExtraInfoStruct;
 	      		pmmioinfo->pExtraInfoStruct = (PVOID)encInfo;
 	      		return MMIO_SUCCESS;
      		}
#ifdef DEBUG
			fprintf(file,"File not read nor write: %s\n",pszFileName);
#endif
      		return MMIO_ERROR;
		}
	    break;                                                 
	case MMIOM_READ: {
		if (!pmmioinfo || !pmmioinfo->pExtraInfoStruct || !lParam1) return MMIO_ERROR;
		
		if (!pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA) {
     		return MMIO_ERROR;
//     		return mmioRead (ogginfo->hmmioSS, (PVOID) lParam1, (ULONG) lParam2);
     	} else {
			OggVorbis_File *oggfile;
			long rc = 0;
			int current_section;
			long total = 0;
			
			oggfile = &((DecInfo *)pmmioinfo->pExtraInfoStruct)->oggfile;
			if (READNUM != ((DecInfo *)pmmioinfo->pExtraInfoStruct)->t) return MMIO_ERROR;
			while (lParam2 > 0) {
	         	rc = ov_read(oggfile, (char *)lParam1, (int)lParam2, 0, 2, 1,  &current_section);
	         	if (rc < 0) {
#ifdef DEBUG
fprintf(file, "Read failed once\n");
#endif
				continue;
				}
				if (rc <= 0) break;
				lParam2 -= rc;
				lParam1 += rc;
				total += rc;
			}
#ifdef DEBUG
fprintf(file,"Read rc:%ld total:%ld\n",rc,total);
#endif
         	if (rc < 0) return MMIO_ERROR;
         	return total;
        }
   	}
	break;
	case MMIOM_SEEK: {
        LONG lPosDesired;
		OggVorbis_File *oggfile;
    	vorbis_info *vi;
		
		if (!pmmioinfo || !pmmioinfo->pExtraInfoStruct) return MMIO_ERROR;
		if (!pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA) return MMIO_ERROR;    	
		
		oggfile = &((DecInfo *)pmmioinfo->pExtraInfoStruct)->oggfile;
		if (READNUM != ((DecInfo *)pmmioinfo->pExtraInfoStruct)->t) return MMIO_ERROR;
		vi = ov_info(oggfile, -1);
		if (!vi) return MMIO_ERROR;
	
		if (SEEK_SET == lParam2) {
     		lPosDesired = lParam1/(2*vi->channels);
        } else if (SEEK_CUR == lParam2) {
            if (0 == lParam1) {
               return ov_pcm_tell(oggfile)*2*vi->channels;
            } /* endif */
           	lPosDesired = ov_pcm_tell(oggfile) + lParam1/(2*vi->channels);
        } else if (SEEK_END == lParam2) {
           	lPosDesired = ov_pcm_total(oggfile,-1) + lParam1/(2*vi->channels);
        } else {
           return MMIO_ERROR;
        }
#ifdef DEBUG
fprintf(file,"Seek to %ld by %d\n",lPosDesired, lParam2);
#endif
		if (ov_pcm_seek(oggfile, lPosDesired) < 0) return MMIO_ERROR;

    	return lPosDesired*2*vi->channels;
	}
    break;

	case MMIOM_CLOSE: {
		int rc;
#ifdef DEBUG
       	    fprintf(file,"start CLOSE\n");
#endif		
		if (!pmmioinfo) return MMIO_ERROR;
		
		if (pmmioinfo->pExtraInfoStruct) {
     		DecInfo *decInfo = (DecInfo *)pmmioinfo->pExtraInfoStruct;
#ifdef DEBUG
       	    fprintf(file,"ready CLOSE\n");
#endif		
			if (READNUM == decInfo->t) {
#ifdef DEBUG
       	    fprintf(file,"read CLOSE\n");
#endif		
     			ov_clear(&decInfo->oggfile);
     			free(decInfo);
     			decInfo = 0;
                rc=MMIO_SUCCESS;
     		} else if (WRITENUM == decInfo->t) {
   	           EncInfo *encInfo = (EncInfo*)pmmioinfo->pExtraInfoStruct;
#ifdef DEBUG
       	    fprintf(file,"write CLOSE\n");
#endif		
			   if (encInfo->headerSet) {
	               vorbis_analysis_wrote(&encInfo->vd,0);
 	               rc = oggWrite(encInfo,1);
	               ogg_stream_clear(&encInfo->os);
	               vorbis_block_clear(&encInfo->vb);
	               vorbis_dsp_clear(&encInfo->vd);
 	               vorbis_comment_clear(&encInfo->vc);
	               vorbis_info_clear(&encInfo->vi);
               }
   	           mmioClose(encInfo->hmmioSS, 0);
  	           free(encInfo);
 	           encInfo = 0;
               rc = MMIO_SUCCESS;
	        } else rc = MMIO_ERROR;
     		pmmioinfo->pExtraInfoStruct = 0;
#ifdef DEBUG
       	    fprintf(file,"CLOSE\n");
#endif		
			return rc;
        }
     	return MMIO_ERROR;
    }
    break;
	case MMIOM_IDENTIFYFILE: {
    	unsigned char buf[4];
		HMMIO hmmioTemp;
		ULONG ulTempFlags = MMIO_READ | MMIO_DENYWRITE | MMIO_NOIDENTIFY;
		LONG rc = MMIO_ERROR;

		if (!lParam1 && !lParam2) return MMIO_ERROR;
    	hmmioTemp = (HMMIO)lParam2;
    	if (!hmmioTemp) {
        	hmmioTemp = mmioOpen((PSZ)lParam1, NULL, ulTempFlags);
        }

		if (hmmioTemp) {
			rc = mmioRead(hmmioTemp, buf, 4);
			if (rc == 4 && buf[0] == 'O' && buf[1] == 'g' &&
					buf[2] == 'g' && buf[3] == 'S') {
				rc = MMIO_SUCCESS;
          	}
			if (!lParam2) mmioClose(hmmioTemp, 0);
		}
		return rc;
	}
    break;
	case MMIOM_GETFORMATINFO: {
    	PMMFORMATINFO pmmformatinfo;
    	pmmformatinfo = (PMMFORMATINFO)lParam1;
    	pmmformatinfo->ulStructLen = sizeof(MMFORMATINFO);
    	pmmformatinfo->fccIOProc = FOURCC_Vorbis;
    	pmmformatinfo->ulIOProcType = MMIO_IOPROC_FILEFORMAT;
    	pmmformatinfo->ulMediaType = MMIO_MEDIATYPE_AUDIO;
    	pmmformatinfo->ulFlags = MMIO_CANREADTRANSLATED 
    	   | MMIO_CANWRITETRANSLATED
           | MMIO_CANSEEKTRANSLATED;
    	strcpy(pmmformatinfo->szDefaultFormatExt, "OGG");
    	pmmformatinfo->ulCodePage = 0;
    	pmmformatinfo->ulLanguage = 0;
    	pmmformatinfo->lNameLength = 21;
    	return MMIO_SUCCESS;
    }
    break;
	case MMIOM_GETFORMATNAME:
		if (lParam2 > 21) { 
     		strcpy((PSZ)lParam1, "Ogg Vorbis");
     		return MMIO_SUCCESS;
     	} else return MMIO_ERROR;
    break;
    case MMIOM_QUERYHEADERLENGTH: return (sizeof (MMAUDIOHEADER));
    break;
	case MMIOM_GETHEADER: {
		OggVorbis_File *oggfile;
		DecInfo *decInfo;
    	PMMAUDIOHEADER mmaudioheader;
    	vorbis_info *vi;
    	
		if (!pmmioinfo || !pmmioinfo->pExtraInfoStruct) return 0;
		if (!(pmmioinfo->ulFlags & MMIO_READ)) return 0;
		decInfo = (DecInfo *)pmmioinfo->pExtraInfoStruct;
		oggfile = &decInfo->oggfile;
		if (READNUM != decInfo->t){
            pmmioinfo->ulErrorRet = MMIOERR_INVALID_STRUCTURE;
            return 0;
        }
		
#ifdef DEBUG
		fprintf(file,"HERE\n");
#endif
		if (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEHEADER) &&
		    !(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA)) return 0;
		mmaudioheader = (MMAUDIOHEADER *)lParam1;
		if (sizeof(MMAUDIOHEADER) > lParam2) {
            pmmioinfo->ulErrorRet = MMIOERR_INVALID_BUFFER_LENGTH;
			return 0;
		}

#ifdef DEBUG
		fprintf(file,"THERE\n");
#endif

		vi = ov_info(oggfile, -1);
		if (!vi) {
            pmmioinfo->ulErrorRet = MMIOERR_INVALID_STRUCTURE;
            return 0;
        }

		mmaudioheader->ulContentType = MMIO_MIDI_UNKNOWN;
		mmaudioheader->ulMediaType = MMIO_MEDIATYPE_AUDIO;
		mmaudioheader->mmXWAVHeader.WAVEHeader.usFormatTag=DATATYPE_WAVEFORM;
		mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels = vi->channels;
		mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec = vi->rate;
		mmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample = 16;
		mmaudioheader->mmXWAVHeader.WAVEHeader.ulAvgBytesPerSec=
			mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels * 
			mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec *
			mmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample / 8;
		mmaudioheader->mmXWAVHeader.WAVEHeader.usBlockAlign=
			mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels * 
			mmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample / 8;
		mmaudioheader->mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInMS=
			(unsigned long)(ov_time_total(oggfile, -1)*1000.0);
		mmaudioheader->mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes=
		    (unsigned long)ov_pcm_total(oggfile, -1)*
		    mmaudioheader->mmXWAVHeader.WAVEHeader.usBlockAlign;

#ifdef DEBUG
		fprintf(file,"time: %ld size: %ld rate: %ld\n",
			mmaudioheader->mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInMS,
			mmaudioheader->mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes,
			mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec);
	
#endif
		if (0 != decInfo->vorbisOptions && VORBIS_COOKIE == decInfo->vorbisOptions->cookie) {
			decInfo->vorbisOptions->nominal_bitrate = ov_bitrate(oggfile, -1);
			mmaudioheader->mmXWAVHeader.XWAVHeaderInfo.pAdditionalInformation = decInfo->vorbisOptions;
        }
		return (sizeof (MMAUDIOHEADER));
    }
    break;

	case MMIOM_SETHEADER: {
    	EncInfo *encInfo;
    	PMMAUDIOHEADER mmaudioheader;
        int totalout = 0;
        int rc;

		if (!pmmioinfo || !pmmioinfo->pExtraInfoStruct) return 0;
		encInfo = (EncInfo*)pmmioinfo->pExtraInfoStruct;
		if (WRITENUM != encInfo->t) return 0;
#ifdef DEBUG
fprintf(file,"write header: %x, %x, %x\n",!(pmmioinfo->ulFlags & MMIO_WRITE),
	encInfo->headerSet, (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEHEADER) && 
		        !(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA)));
fprintf(file,"flag: %x, trans: %x\n",pmmioinfo->ulFlags,pmmioinfo->ulTranslate);
#endif
		if (/*!(pmmioinfo->ulFlags & MMIO_WRITE) ||*/ encInfo->headerSet
		    || (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEHEADER) && 
		        !(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA))) return 0;
		if (!lParam1) {
     		pmmioinfo->ulErrorRet = MMIOERR_INVALID_STRUCTURE;
     		return 0;
     	}
     	mmaudioheader = (PMMAUDIOHEADER)lParam1;
     	if (lParam2 != sizeof(MMAUDIOHEADER)) {
         	pmmioinfo->ulErrorRet = MMIOERR_INVALID_BUFFER_LENGTH;
         	return 0;
        }
		  /********** Encode setup ************/
	if (0 != mmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample%8) {
      /* Bit-rate must be multiple of 8 */
      return 0;
    }
	encInfo->bitsPerSample=mmaudioheader->mmXWAVHeader.WAVEHeader.usBitsPerSample;
#ifdef DEBUG
fprintf(file,"ready to write header: ");
#endif
    vorbis_info_init(&encInfo->vi);
	if (0 == encInfo->vorbisOptions || VORBIS_COOKIE != encInfo->vorbisOptions->cookie) {
#ifdef DEBUG
fprintf(file,"default quality 0.3\n");
#endif
	    rc = vorbis_encode_init_vbr(&encInfo->vi,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec, 0.3);
    } else {
#ifdef DEBUG
fprintf(file,"bitsPerSample: %d channels: %d samplesPerSec: %ld min: %ld nominal: %ld max: %ld\n",
	encInfo->bitsPerSample,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec,
	  	encInfo->vorbisOptions->max_bitrate,
	  	encInfo->vorbisOptions->nominal_bitrate,
	  	encInfo->vorbisOptions->min_bitrate);
#endif
	    rc = vorbis_encode_init(&encInfo->vi,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.usChannels,
	  	mmaudioheader->mmXWAVHeader.WAVEHeader.ulSamplesPerSec,
	  	encInfo->vorbisOptions->max_bitrate,
	  	encInfo->vorbisOptions->nominal_bitrate,
	  	encInfo->vorbisOptions->min_bitrate);
    }

    if (rc) {
#ifdef DEBUG
fprintf(file,"encodeInit failed: %d\n",rc);
#endif
       return 0;
    } /* endif */

  /* add a comment */
  vorbis_comment_init(&encInfo->vc);
  vorbis_comment_add_tag(&encInfo->vc,"ENCODER","mmioVorbis");

  /* set up the analysis state and auxiliary encoding storage */
  vorbis_analysis_init(&encInfo->vd,&encInfo->vi);
  vorbis_block_init(&encInfo->vd,&encInfo->vb);

  /* set up our packet->stream encoder */
  /* pick a random serial number; that way we can more likely build
     chained streams just by concatenation */
  srand(time(NULL));
  ogg_stream_init(&encInfo->os,rand());

  {
    ogg_packet header;
    ogg_packet header_comm;
    ogg_packet header_code;

    vorbis_analysis_headerout(&encInfo->vd,&encInfo->vc,&header,&header_comm,&header_code);
    ogg_stream_packetin(&encInfo->os,&header); /* automatically placed in its own
					 page */
    ogg_stream_packetin(&encInfo->os,&header_comm);
    ogg_stream_packetin(&encInfo->os,&header_code);
	while(1){
		int result=ogg_stream_flush(&encInfo->os,&encInfo->og);
		if(result==0)break;
		result = mmioWrite(encInfo->hmmioSS, encInfo->og.header,encInfo->og.header_len);
        totalout += result;
		if (result!=encInfo->og.header_len) {
	               ogg_stream_clear(&encInfo->os);
	               vorbis_block_clear(&encInfo->vb);
	               vorbis_dsp_clear(&encInfo->vd);
 	               vorbis_comment_clear(&encInfo->vc);
	               vorbis_info_clear(&encInfo->vi);
			return 0;
        }
		result = mmioWrite(encInfo->hmmioSS, encInfo->og.body,encInfo->og.body_len);
        totalout += result;
		if (result!=encInfo->og.body_len) {
	               ogg_stream_clear(&encInfo->os);
	               vorbis_block_clear(&encInfo->vb);
	               vorbis_dsp_clear(&encInfo->vd);
 	               vorbis_comment_clear(&encInfo->vc);
	               vorbis_info_clear(&encInfo->vi);
			return 0;
		}
	}
  }
  		encInfo->headerSet = 1;
  		return totalout;
    }
    break;
	case MMIOM_WRITE: {
    	EncInfo *encInfo;
		if (!pmmioinfo || !pmmioinfo->pExtraInfoStruct) return MMIO_ERROR;
		encInfo = (EncInfo*)pmmioinfo->pExtraInfoStruct;
		if (WRITENUM != encInfo->t) return MMIO_ERROR;
		if (!encInfo->headerSet) return MMIO_ERROR;
		if (!(pmmioinfo->ulTranslate & MMIO_TRANSLATEDATA)) {
     		if (!lParam1) return MMIO_ERROR;
     		return mmioWrite(encInfo->hmmioSS, (PVOID)lParam1, lParam2);
     	} else {
            if (lParam2 == 0) {
                vorbis_analysis_wrote(&encInfo->vd,0);
            } else {
                long i;
				int j, k;
                int num;
				float denom = 1;
                signed char *readbuffer = (char *)lParam1;
                /* data to encode */
                /* expose the buffer to submit data */
				int sampleSize = encInfo->vi.channels*encInfo->bitsPerSample/8;
				int samples = lParam2/sampleSize;
	            float **buffer=vorbis_analysis_buffer(&encInfo->vd, samples);
#ifdef DEBUG
fprintf(file,"write: %ld\n",lParam2);
#endif

  	            /* :TODO: Work with buffers not a multiple of sampleSize*/
                if (lParam2 % sampleSize != 0) {
#ifdef DEBUG
fprintf(file,"Bad Write Buffer Size\n");
#endif
                    return MMIO_ERROR;
                }
                for(i=0;i<samples;i++){
                   for (j=0;j<encInfo->vi.channels;j++) {
                    num=0; denom=0.5;
					if (encInfo->bitsPerSample<=8) {
        				buffer[j][i]=(float)((unsigned char)(readbuffer[i*sampleSize])-
							(1<<(encInfo->bitsPerSample-1)))/
							(float)(1<<(encInfo->bitsPerSample-1));
					} else {
						for (k=encInfo->bitsPerSample/8;k>0;k--) {
							if (k==encInfo->bitsPerSample/8) {
								num=(readbuffer[i*sampleSize+k-1]);
							} else {
								num=(num<<8)|((0xff)&(int)(readbuffer[i*sampleSize+k-1]));
    		    			}
							denom *= 256.0;
						}
 	                   buffer[j][i]=((float)num)/denom;
					}
                   } /* endfor */
                }
                vorbis_analysis_wrote(&encInfo->vd,i);
            } /* endif */
            if (oggWrite(encInfo,0)>=0) {
                return lParam2;
            } else {
                return MMIO_ERROR;
            } /* endif */
        }
    }
    break;
#ifdef DEBUG
	case MMIOM_TEMPCHANGE: {
        return MMIO_SUCCESS;
    }
    break;
#endif
	}
#ifdef DEBUG	
	fprintf(file,"unexpected command: %x\n",usMsg);
#endif
	return MMIOERR_UNSUPPORTED_MESSAGE;
}