Exemplo n.º 1
0
void Sound::play()
{
	if (!m_buffer || m_buffer->getSampleCount() == 0)
		return;
	if (getStatus() == Playing)
		stop();

	m_channel = 0;
	while (m_channel < 24 && ndspChnIsPlaying(m_channel))
		m_channel++;

	if (m_channel == 24) {
		err() << "Sound::play() failed because all channels are in use." << std::endl;
		m_channel = -1;
		return;
	}

	setPlayingOffset(m_pauseOffset);

	if (m_pauseOffset != Time::Zero)
		m_pauseOffset = Time::Zero;

	u32 size = sizeof(Int16) * m_buffer->getSampleCount();

	ndspChnReset(m_channel);
	ndspChnSetInterp(m_channel, NDSP_INTERP_POLYPHASE);
	ndspChnSetRate(m_channel, float(m_buffer->getSampleRate()));
	ndspChnSetFormat(m_channel, (m_buffer->getChannelCount() == 1) ? NDSP_FORMAT_MONO_PCM16 : NDSP_FORMAT_STEREO_PCM16);

	DSP_FlushDataCache((u8*)m_buffer->getSamples(), size);

	ndspChnWaveBufAdd(m_channel, &m_ndspWaveBuf);
}
Exemplo n.º 2
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;
		
		}
	}		
}