Пример #1
0
Time Sound::getPlayingOffset() const
{
	if (getStatus() == Stopped)
		return Time::Zero;
	if (getStatus() == Paused)
		return m_pauseOffset;

	u32 samplePos = ndspChnGetSamplePos(m_channel);
	return seconds(static_cast<float>(samplePos) / m_buffer->getSampleRate()) + m_playOffset;
}
Пример #2
0
// startMusic: Plays a song with network streaming feature
void startMusic(Socket* sock, Music* src)
{
	closeStream = false;
	src->streamLoop = false; // TODO: Add looping feature
	songPointer = 0;
	netSize = 0;
	u32 ch = 0x08;
	u32 ch2 = 0x09;
	bool non_native_encode = false;
	ThreadFunc streamFunction = streamWAV;
	u8 tmp_encode;
	/*if (src->encoding == CSND_ENCODING_VORBIS){
		streamFunction = streamOGG;
		tmp_encode = src->encoding;
		src->encoding = CSND_ENCODING_PCM16;
		non_native_encode = true;
	}*/
	int raw_format;
	if (src->audiotype == 1) raw_format = NDSP_FORMAT_MONO_PCM16;
	else raw_format = NDSP_FORMAT_STEREO_PCM16;
	ndspChnReset(ch);
	ndspChnWaveBufClear(ch);
	ndspChnSetInterp(ch, NDSP_INTERP_LINEAR);
	ndspChnSetRate(ch, float(src->samplerate));
	ndspChnSetFormat(ch, raw_format);
	ndspWaveBuf* waveBuf = (ndspWaveBuf*)calloc(1, sizeof(ndspWaveBuf));
	createDspBlock(waveBuf, src->bytepersample, src->mem_size, 0, (u32*)src->audiobuf);
	src->blocks = NULL;
	populatePurgeTable(src, waveBuf);
	ndspChnWaveBufAdd(ch, waveBuf);
	src->tick = osGetTime();
	src->wavebuf = waveBuf;
	src->ch = ch;
	src->isPlaying = true;
	src->lastCheck = ndspChnGetSamplePos(ch);
	src->streamLoop = false;
	svcCreateEvent(&updateStream,0);
	cachePackage* pkg = (cachePackage*)malloc(sizeof(cachePackage));
	pkg->client = sock;
	pkg->song = src;
	svcSignalEvent(updateStream);
	threadCreate(streamFunction, pkg, 8192, 0x18, 0, true);
	src->isPlaying = true;
}
Пример #3
0
void streamWAV(void* arg){

	// Fetching cachePackage struct from main thread
	cachePackage* pack = (cachePackage*)arg;
	while(1) {
	
		// Waiting for updateStream event
		svcWaitSynchronization(updateStream, U64_MAX);
		svcClearEvent(updateStream);
		
		// Close the thread if closeStream event received
		if(closeStream){
			closeStream = false;
			svcExitThread();
		}
		
		// Check if the current stream is paused or not
		Music* src = pack->song;
		Socket* Client = pack->client;
		if (src->isPlaying){
		
			// Check if a free buffer is available
			if (src->wavebuf2 == NULL){
			
				// Check if file reached EOF
				if (src->audio_pointer >= src->size){
				
					// Check if playback ended
					if (!ndspChnIsPlaying(src->ch)){
						src->isPlaying = false;
						src->tick = (osGetTime()-src->tick);
					}
					
					continue;
				}
				
				// Swap audiobuffers
				u8* tmp = src->audiobuf;
				src->audiobuf = src->audiobuf2;
				src->audiobuf2 = tmp;
				
				// Create a new block for DSP service
				u32 bytesRead;
				src->wavebuf2 = (ndspWaveBuf*)calloc(1,sizeof(ndspWaveBuf));
				createDspBlock(src->wavebuf2, src->bytepersample, src->mem_size, 0, (u32*)src->audiobuf);
				populatePurgeTable(src, src->wavebuf2);
				ndspChnWaveBufAdd(src->ch, src->wavebuf2);
				socketSend(Client, "exec2:0000");
				u32 processedBytes = 0;
				netSize = 0;
				while (netSize <= 0) heapRecv(Client, 2048);
				while (processedBytes < (src->mem_size / 2)){
					if (netSize <= 0){
							heapRecv(Client, 2048);
							continue;
					}
					if (strncmp((char*)netBuffer, "EOF", 3) == 0) break;
					memcpy(&streamCache[songPointer + processedBytes], netBuffer, netSize);
					processedBytes = processedBytes + netSize;
					heapRecv(Client, 2048);
				}
				memcpy(src->audiobuf, &streamCache[songPointer], src->mem_size);
				if (songPointer == 0) songPointer = src->mem_size / 2;
				else songPointer = 0;
				src->audio_pointer = src->audio_pointer + src->mem_size;
				
				// Changing endianess if Big Endian
				if (src->big_endian){
					u64 i = 0;
					while (i < src->mem_size){
						u8 tmp = src->audiobuf[i];
						src->audiobuf[i] = src->audiobuf[i+1];
						src->audiobuf[i+1] = tmp;
						i=i+2;	
					}
				}
			
			}
			
			// Check if a block playback is finished
			u32 curSample = ndspChnGetSamplePos(src->ch);
			if (src->lastCheck > curSample){
			
				// Prepare next block
				src->wavebuf = src->wavebuf2;
				src->wavebuf2 = NULL;
			
			}
			
			// Update sample position tick
			src->lastCheck = curSample;
		
		}
	}		
}