예제 #1
0
int VorbisProcessData(OggData *data, char *buffer)
{
	int num_samples;
	float **pcm;
	float *chan;
	int i, j;
	int val;
	ogg_packet packet;
	int len;

	len = 0;
	num_samples = 0;

	while (!len) {
		if (ogg_stream_packetout(&data->astream, &packet) != 1) {
			if (OggGetNextPage(&data->page, &data->sync, data->File)) {
				// EOF
				return -1;
			}

			ogg_stream_pagein(&data->astream, &data->page);
		} else {
			if (vorbis_synthesis(&data->vblock, &packet) == 0) {
				vorbis_synthesis_blockin(&data->vdsp, &data->vblock);
			}

			while ((num_samples = vorbis_synthesis_pcmout(&data->vdsp, &pcm)) > 0) {
				j = 0;
				for (i = 0; i < data->vinfo.channels; ++i) {
					chan = pcm[i];
					for (j = 0; j < num_samples; ++j) {
						val = static_cast<int>(chan[j] * 32767.f);
						if (val > 32767) {
							val = 32767;
						} else if (val < -32768) {
							val = -32768;
						}

						*(Sint16 *)(buffer + len
						  + (j * 2 * data->vinfo.channels) + i * 2) = (Sint16)val;
					}
				}
				len += j * 2 * data->vinfo.channels;

				// we consumed num_samples
				vorbis_synthesis_read(&data->vdsp, num_samples);
			}
		}
	}

	return len;
}
예제 #2
0
파일: movie.cpp 프로젝트: KroArtem/Wyrmgus
/**
**  Process Ogg data
*/
static int TheoraProcessData(OggData *data)
{
	ogg_packet packet;

	while (1) {
		if (ogg_stream_packetout(&data->vstream, &packet) != 1) {
			if (OggGetNextPage(&data->page, &data->sync, data->File)) {
				// EOF
				return -1;
			}
			ogg_stream_pagein(&data->vstream, &data->page);
		} else {
			theora_decode_packetin(&data->tstate, &packet);
			return 0;
		}
	}
}
예제 #3
0
int OggInit(CFile *f, OggData *data)
{
	ogg_packet packet;
	int num_vorbis;
#ifdef USE_THEORA
	int num_theora;
#endif
	int stream_start;
	int ret;

	unsigned magic;
	f->read(&magic, sizeof(magic));
	if (SDL_SwapLE32(magic) != 0x5367674F) { // "OggS" in ASCII
		return -1;
	}
	f->seek(0, SEEK_SET);

	ogg_sync_init(&data->sync);

	vorbis_info_init(&data->vinfo);
	vorbis_comment_init(&data->vcomment);

#ifdef USE_THEORA
	theora_info_init(&data->tinfo);
	theora_comment_init(&data->tcomment);
#endif

#ifdef USE_THEORA
	num_theora = 0;
#endif
	num_vorbis = 0;
	stream_start = 0;
	while (!stream_start) {
		ogg_stream_state test;

		if (OggGetNextPage(&data->page, &data->sync, f)) {
			return -1;
		}

		if (!ogg_page_bos(&data->page)) {
			if (num_vorbis) {
				ogg_stream_pagein(&data->astream, &data->page);
			}
#ifdef USE_THEORA
			if (num_theora) {
				ogg_stream_pagein(&data->vstream, &data->page);
			}
#endif
			stream_start = 1;
			break;
		}

		ogg_stream_init(&test, ogg_page_serialno(&data->page));
		ogg_stream_pagein(&test, &data->page);

		// initial codec headers
		while (ogg_stream_packetout(&test, &packet) == 1) {
#ifdef USE_THEORA
			if (theora_decode_header(&data->tinfo, &data->tcomment, &packet) >= 0) {
				memcpy(&data->vstream, &test, sizeof(test));
				++num_theora;
			} else
#endif
			if (!vorbis_synthesis_headerin(&data->vinfo, &data->vcomment, &packet)) {
				memcpy(&data->astream, &test, sizeof(test));
				++num_vorbis;
			} else {
				ogg_stream_clear(&test);
			}
		}
	}

	data->audio = num_vorbis;
#ifdef USE_THEORA
	data->video = num_theora;
#endif

	// remainint codec headers
	while ((num_vorbis && num_vorbis < 3)
#ifdef USE_THEORA
	  || (num_theora && num_theora < 3) ) {
		// are we in the theora page ?
		while (num_theora && num_theora < 3 &&
		  (ret = ogg_stream_packetout(&data->vstream, &packet))) {
			if (ret < 0) {
				return -1;
			}
			if (theora_decode_header(&data->tinfo, &data->tcomment, &packet)) {
				return -1;
			}
			++num_theora;
		}
#else
	  ) {
#endif

		// are we in the vorbis page ?
		while (num_vorbis && num_vorbis < 3 && 
		  (ret = ogg_stream_packetout(&data->astream, &packet))) {
			if (ret < 0) {
				return -1;
			}
			if (vorbis_synthesis_headerin(&data->vinfo, &data->vcomment, &packet)) {
				return -1;
				
			}
			++num_vorbis;
		}

		if (OggGetNextPage(&data->page, &data->sync, f)) {
				break;
		}

		if (num_vorbis) {
			ogg_stream_pagein(&data->astream, &data->page);
		}
#ifdef USE_THEORA
		if (num_theora) {
			ogg_stream_pagein(&data->vstream, &data->page);
		}
#endif
	}

	if (num_vorbis) {
		vorbis_synthesis_init(&data->vdsp, &data->vinfo);
		vorbis_block_init(&data->vdsp, &data->vblock);
	} else {
    	vorbis_info_clear(&data->vinfo);
    	vorbis_comment_clear(&data->vcomment);
	}

#ifdef USE_THEORA
	if (num_theora) {
		theora_decode_init(&data->tstate, &data->tinfo);
		data->tstate.internal_encode = NULL;  // needed for a bug in libtheora (fixed in next release)
	} else {
    	theora_info_clear(&data->tinfo);
    	theora_comment_clear(&data->tcomment);
	}

	return !(num_vorbis || num_theora);
#else
	return !num_vorbis;
#endif
}