Homebrew I want to play back streams of OGG files, but the playback speed gets faster.

tgaiu

Active Member
OP
Newcomer
Joined
Sep 10, 2017
Messages
33
Trophies
0
XP
55
Country
Japan
I attempted to play stream of OGG file by referring to ctrmus code, but the playback speed becomes a little faster.
Please let me know if you understand the cause.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <tremor/ivorbiscodec.h>
#include <tremor/ivorbisfile.h>
#include <3ds.h>

#define BUFF_SIZE 8 * 4096
typedef struct {
	float rate;
	u32 channels;
	u32 encoding;
	u32 nsamples;
	u32 size;
	char* data1;
	char* data2;
	bool loop;
	int audiochannel;
	float mix[12];
	ndspInterpType interp;
	OggVorbis_File ovf;
} Music;
Music music;
ndspWaveBuf waveBuf[2];

uint64_t fillVorbisBuffer(OggVorbis_File ovf, char* buffer) {	
	uint64_t samplesRead = 0;
	int samplesToRead = BUFF_SIZE;
	while (samplesToRead > 0) {
		static int current_section;
		int samplesJustRead =
			ov_read(&ovf,
				buffer,
				samplesToRead > 4096 ? 4096 : samplesToRead,
				&current_section);

		if (samplesJustRead < 0) {
			return samplesJustRead;
		}else if (samplesJustRead == 0){
			break;
		}
		samplesRead += samplesJustRead;
		samplesToRead -= samplesJustRead;
		buffer += samplesJustRead;
	}
	return samplesRead / sizeof(int16_t);
}


int load() {
	memset(&music, 0, sizeof(music));
	music.mix[0] = 1.0f;
	music.mix[1] = 1.0f;
	FILE * file = fopen("example.ogg", "rb");
	if (file == 0) {
		printf("no file\n");
		while (1);
	}
	if (ov_open(file, &music.ovf, NULL, 0) < 0) {
		printf("ogg vorbis file error\n");
		while (1);
	}
	vorbis_info * vorbisInfo = ov_info(&music.ovf, -1);
	if (vorbisInfo == NULL) {
		printf("could not retrieve ogg audio stream information\n");
		while (1);
	}
	music.rate = (float)vorbisInfo->rate;
	music.channels = (u32)vorbisInfo->channels;
	music.encoding = NDSP_ENCODING_PCM16;
	//music.nsamples = (u32)ov_pcm_total(&music.ovf, -1);
	music.size = music.nsamples * music.channels * 2;
	music.audiochannel = 0;
	music.interp = NDSP_INTERP_NONE;
	music.loop = false;
	if (linearSpaceFree() < music.size) {
		printf("not enough linear memory available %ld\n", music.size);
	}
	music.data1 = (char *)linearAlloc(BUFF_SIZE * sizeof(int16_t));
	music.data2 = (char *)linearAlloc(BUFF_SIZE * sizeof(int16_t));
	if (music.audiochannel == -1) {
		printf("No available audio channel\n");
		return -1;
	}
		ndspChnWaveBufClear(music.audiochannel);
		ndspChnReset(music.audiochannel);
		ndspChnInitParams(music.audiochannel);
		ndspChnSetMix(music.audiochannel, music.mix);
		ndspChnSetInterp(music.audiochannel, music.interp);
		ndspChnSetRate(music.audiochannel, music.rate);
		ndspChnSetFormat(music.audiochannel, NDSP_CHANNELS(music.channels) | NDSP_ENCODING(music.encoding));

	memset(&waveBuf, 0, sizeof(WaveBuf));
	waveBuf[0].data_vaddr = &music.data1[0];
	waveBuf[0].nsamples = fillVorbisBuffer(music.ovf, &music.data1[0]) / music.channels;
	waveBuf[0].looping = music.loop;
	ndspChnWaveBufAdd(music.audiochannel, &waveBuf[0]);
	waveBuf[1].data_vaddr = &music.data2[0];
	waveBuf[1].nsamples = fillVorbisBuffer(music.ovf, &music.data2[0]) / music.channels;
	waveBuf[1].looping = music.loop;
	ndspChnWaveBufAdd(music.audiochannel, &waveBuf[1]);
	return 0;
}

int main(int argc, char **argv) {
	gfxInitDefault();
	consoleInit(GFX_TOP, 0);
	ndspInit();
	ndspSetOutputMode(NDSP_OUTPUT_STEREO);
	ndspSetOutputCount(1);
	load();
	bool lastbuf = false;
	//while (ndspChnIsPlaying(music.audiochannel) == false);
	while (aptMainLoop()) {
		hidScanInput();
		u32 keys = hidKeysDown();
		if (keys & KEY_START)
			break;
		if (lastbuf == true) {
			continue;
		}
			if (waveBuf[0].status == NDSP_WBUF_DONE) {
				size_t read = fillVorbisBuffer(music.ovf, &music.data1[0]);
				if (read <= 0) {
					lastbuf = true;
					printf("END\n");
					continue;
				}
				else if (read < BUFF_SIZE) {
					waveBuf[0].nsamples = read / music.channels;
				}
				ndspChnWaveBufAdd(music.audiochannel, &waveBuf[0]);
			}

			if (waveBuf[1].status == NDSP_WBUF_DONE) {
				size_t read = fillVorbisBuffer(music.ovf, &music.data2[0]);
				if (read <= 0) {
					lastbuf = true;
					printf("END\n");
					continue;
				}
				else if (read < BUFF_SIZE) {
					waveBuf[1].nsamples = read / music.channels;
				}
				ndspChnWaveBufAdd(music.audiochannel, &waveBuf[1]);
			}
		DSP_FlushDataCache(music.data1, BUFF_SIZE * sizeof(int16_t));
		DSP_FlushDataCache(music.data2, BUFF_SIZE * sizeof(int16_t));
		gfxFlushBuffers();
		gfxSwapBuffers();
		gspWaitForVBlank();
	}
	ndspChnWaveBufClear(music.audiochannel);
	ndspExit();
	gfxExit();
	return 0;
}
 
General chit-chat
Help Users
    NeoGaming @ NeoGaming: yep