int playerStart(char *path,pMalloc extern_malloc,pFree extern_free, int(*callback)(int)){ int ret,ch;MODFILE mod; if(!extern_malloc || !extern_free)return -1; if((ch=sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL,PSP_AUDIO_SAMPLE_ALIGN(768),PSP_AUDIO_FORMAT_STEREO))<0)return ch; myMalloc=extern_malloc; myFree =extern_free; MODFILE_Init(&mod); if((ret=MODFILE_Load(path, &mod))<0)return ret; mod.musicvolume = 255; mod.sfxvolume = 255; mod.callback = NULL;//callback; MODFILE_Start(&mod); MODFILE_SetFormat(&mod, 44100, 2,16,1/*unsigned*/); SceCtrlData pad; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(1); for(int i=0;;i++){ sceCtrlReadBufferPositive(&pad,1); if(pad.Buttons&PSP_CTRL_START)break; mod.mixingbuf =(void*)out[i%2]; mod.mixingbuflen = 768*2*2; MODFILE_Player(&mod); sceAudioOutputBlocking(ch, PSP_AUDIO_VOLUME_MAX,out[i%2]); } MODFILE_Stop(&mod); MODFILE_Free(&mod); sceAudioChRelease(ch); return 0; }
void audioOutput(char * buffer, int blocking) { struct timeval start; gettimeofday(&start, NULL); int result; if (blocking) { result = sceAudioOutputBlocking(channel, VOLUME, buffer); } else { result = sceAudioOutput(channel, VOLUME, buffer); } struct timeval end; gettimeofday(&end, NULL); int duration_usec = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); int interval_usec = (start.tv_sec - previousAudioOutput.tv_sec) * 1000000 + (start.tv_usec - previousAudioOutput.tv_usec); char s[1000]; sprintf(s, "Interval %d usec, result %d, duration: %d usec\n", interval_usec, result, duration_usec); strcat(text, s); gettimeofday(&previousAudioOutput, NULL); }
/** * playback_thread: Sound playback thread. Continually sends the ring * buffer data to the OS until signaled to stop. * * [Parameters] * args: Thread argument size * argp: Thread argument pointer * [Return value] * Always zero */ static int playback_thread(SceSize args, void *argp) { PSPSoundBufferDesc * const buffer_desc = *(PSPSoundBufferDesc **)argp; /* Temporary buffer for dummy audio data when the emulator falls behind * real time (filled with the last sample sent to avoid clicks). This * thread is only launched once, so "static" is safe. */ static uint32_t dummy_buffer[BUFFER_SIZE]; // 1 stereo sample = 32 bits static uint32_t last_sample; // Last stereo sample played while (!buffer_desc->stop) { const unsigned int next_play = buffer_desc->next_play; //static int x;int now=sceKernelGetSystemTimeLow();if(now-x>100000){printf("--- audio stat: %u %u %u %u cp=%u np=%u nw=%u\n",UNCACHED(buffer_desc->write_ready[0]),UNCACHED(buffer_desc->write_ready[1]),UNCACHED(buffer_desc->write_ready[2]),UNCACHED(buffer_desc->write_ready[3]),buffer_desc->cur_play,next_play,UNCACHED(buffer_desc->next_write));x=now;} if (!UNCACHED(buffer_desc->write_ready[next_play])) { // i.e., ready for playback const void *buffer = buffer_desc->buffer[next_play]; last_sample = ((const uint32_t *)buffer)[BUFFER_SIZE - 1]; sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, buffer); #ifdef DUMP_AUDIO sceIoWrite(dump_fd, buffer, BUFFER_SIZE*4); #endif UNCACHED(buffer_desc->write_ready[buffer_desc->cur_play]) = 1; buffer_desc->cur_play = next_play; buffer_desc->next_play = (next_play + 1) % NUM_BUFFERS; } else { const uint32_t sample = last_sample; // Help out optimizer uint32_t *ptr32 = dummy_buffer; unsigned int i; for (i = 0; i < BUFFER_SIZE; i += 8) { ptr32[i+0] = sample; ptr32[i+1] = sample; ptr32[i+2] = sample; ptr32[i+3] = sample; ptr32[i+4] = sample; ptr32[i+5] = sample; ptr32[i+6] = sample; ptr32[i+7] = sample; } sceAudioOutputBlocking(buffer_desc->channel, muted ? 0 : 0x8000, dummy_buffer); } } sceAudioChRelease(buffer_desc->channel); memset(buffer_desc, 0, sizeof(*buffer_desc)); return 0; }
static void PSPAUDIO_PlayDevice(_THIS) { Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; if (this->spec.channels == 1) { sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf); } else { sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf); } this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; }
// Don't do it with blocking inline bool PspAudio::playBuffer() { DEBUG_ENTER_FUNC(); int ret; if (_numOfChannels == 1) ret = sceAudioOutputBlocking(_pspChannel, PSP_AUDIO_VOLUME_MAX, _buffers[_bufferToPlay]); else ret = sceAudioOutputPannedBlocking(_pspChannel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, _buffers[_bufferToPlay]); if (ret < 0) { PSP_ERROR("failed to output audio. Error[%d]\n", ret); return false; } return true; }
static int SoundThread() { int err=0; int sample_count; int chan; int realSampleCount; int buf = 0; //For SMS, we need tighter timings if (menuConfig.sound.perfectSynchro && gblMachineType == EM_SMS) sample_count = 128; else sample_count = snd.sample_rate/snd.fps; sample_count = PSP_AUDIO_SAMPLE_ALIGN(sample_count); realSampleCount = sample_count / (44100 / snd.sample_rate); chan = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, sample_count, PSP_AUDIO_FORMAT_STEREO); if(chan > 0 && sample_count > 0 && sample_count <= 2048) { for(; soundRunning; ) { if (soundPause) memset(audioOut[buf], 0, sample_count * sizeof(sample_t)); else StandardSoundProcess(); //Game Boy: réglage du son ne fonctionne pas! AudioGet(audioOut[buf], sample_count, realSampleCount); sceAudioOutputBlocking(chan, PSP_AUDIO_VOLUME_MAX, (void*)audioOut[buf]); if (menuConfig.sound.perfectSynchro) buf = 1 - buf; } sceAudioChRelease(chan); } soundRunning = -1; sceKernelExitDeleteThread(0); }
triSInt AT3_Thread(SceSize args, ScePVoid argp) { while(AT3_Loaded) { if(AT3_Playing) { if(AT3_CallBack) AT3_CallBack((triS16 *) ((triSInt) AT3_Mix_Buffer | 0x40000000), AT3_SAMPLES); AT3_Samples_Played += sceAudioOutputBlocking(AT3_Channel, AT3_Volume, (triVoid *) ((triSInt) AT3_Mix_Buffer | 0x40000000)); sceAudiocodecDecode(AT3_Codec_Buffer, AT3_TYPE_ATRAC3); AT3_pos += AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER]; memcpy( (void*)AT3_Buffer, (void*)AT3_pos, AT3_align ); if (AT3_align==192) { memcpy( (void*)(AT3_Buffer+192), (void*)AT3_Buffer, 192 ); } //AT3_Codec_Buffer[AT3_POS_INPUT_BUFFER] = AT3_pos; if(AT3_pos >= ((AT3_length - AT3_Datas_Start) + AT3_Codec_Buffer[AT3_INITIAL_BUFFER])) { AT3_pos = AT3_Codec_Buffer[AT3_INITIAL_BUFFER] + AT3_Datas_Start; if(!AT3_Loop) AT3_Playing = 0; } } else memset(AT3_Mix_Buffer, 0, AT3_SAMPLES * 2 * 2); sceKernelDcacheWritebackInvalidateAll(); sceKernelDelayThread(10); } return(0); }
static int pmp_output_thread(SceSize input_length, void *input) { volatile struct pmp_play_struct *p = *((void **) input); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); SceCtrlData previous_controller; sceCtrlPeekBufferPositive(&previous_controller, 1); unsigned int first_video_frame = 1; unsigned int current_buffer_number = 0; while (p->return_request == 0) { volatile struct pmp_decode_buffer_struct *current_buffer = &p->decoder.output_frame_buffers[current_buffer_number]; if (pmp_wait(p, p->semaphore_can_get, "pmp_output_thread: sceKernelWaitSema failed on semaphore_can_get") == 0) { break; } if (sceKernelSignalSema(p->semaphore_can_show, 1) < 0) { p->return_result = "pmp_output_thread: sceKernelSignalSema failed on semaphore_can_show"; p->return_request = 1; break; } if (p->seek == 0) { current_buffer->first_delay -= 500; sceKernelDelayThread(current_buffer->first_delay < 1 ? 1 : current_buffer->first_delay); sceAudioOutputBlocking(0, PSP_AUDIO_VOLUME_MAX, current_buffer->audio_frame); } pmp_input(p, &previous_controller); if (p->seek == 0) { int i = 1; for (; i < current_buffer->number_of_audio_frames; i++) { sceAudioOutputBlocking(0, PSP_AUDIO_VOLUME_MAX, current_buffer->audio_frame + p->decoder.audio_frame_size * i); } current_buffer->last_delay -= 500; sceKernelDelayThread(current_buffer->last_delay < 1 ? 1 : current_buffer->last_delay); } current_buffer_number = (current_buffer_number + 1) % p->decoder.number_of_frame_buffers; if (pmp_wait(p, p->semaphore_show_done, "pmp_output_thread: sceKernelWaitSema failed on semaphore_show_done") == 0) { break; } if (first_video_frame == 1) { first_video_frame = 0; } else { if (sceKernelSignalSema(p->semaphore_can_put, 1) < 0) { p->return_result = "pmp_output_thread: sceKernelSignalSema failed on semaphore_can_put"; p->return_request = 1; break; } } while (p->return_request == 0 && p->paused == 1) { sceKernelDelayThread(100000); pmp_input(p, &previous_controller); } } return(0); }
int main(int argc, char *argv[]) { char *at3_data; int at3_size; char *decode_data; int decode_size; int n; FILE *file; int atracID; int maxSamples = 0; int result; int channel; u32 puiPosition; u32 puiDataByte; if ((file = fopen("sample.at3", "rb")) != NULL) { fseek(file, 0, SEEK_END); at3_size = ftell(file); fseek(file, 0, SEEK_SET); at3_data = malloc(at3_size); decode_data = malloc(decode_size = 512 * 1024); memset(at3_data, 0, at3_size); memset(decode_data, 0, decode_size); fread(at3_data, at3_size, 1, file); fclose(file); } pspSdkLoadStartModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL); pspSdkLoadStartModule("flash0:/kd/libatrac3plus.prx", PSP_MEMORY_PARTITION_KERNEL); printf("at3: %08X, %08X\n", (unsigned int)at3_data, at3_size); printf("Header: %s\n", (char *)at3_data); atracID = sceAtracSetDataAndGetID(at3_data, at3_size); result = sceAtracSetLoopNum(atracID, 2); printf("sceAtracSetLoopNum: %08X\n", result); printf("sceAtracSetDataAndGetID: %08X\n", atracID); result = sceAtracGetMaxSample(atracID, &maxSamples); printf("sceAtracGetMaxSample: %08X, %d\n", result, maxSamples); channel = sceAudioChReserve(0, maxSamples, PSP_AUDIO_FORMAT_STEREO); result = sceAtracGetSecondBufferInfo(atracID, &puiPosition, &puiDataByte); printf("sceAtracGetSecondBufferInfo: %08X, %u, %u\n", result, (unsigned int)puiPosition, (unsigned int)puiDataByte); int end = 0; int steps = 0; while (!end) { //int remainFrame = -1; int remainFrame = 0; //int decodeBufferPosition = 0; int samples = 0; int nextSample = 0; u32 nextPosition = 0; if (steps < 4) { result = sceAtracGetNextSample(atracID, &nextSample); printf("sceAtracGetNextSample(%d): %d\n", result, nextSample); result = sceAtracGetNextDecodePosition(atracID, &nextPosition); printf("sceAtracGetNextDecodePosition(%d): %u\n", result, (unsigned int)nextPosition); } result = sceAtracDecodeData(atracID, (u16 *)decode_data, &samples, &end, &remainFrame); if (steps < 4) { } sceAudioSetChannelDataLen(channel, samples); sceAudioOutputBlocking(channel, 0x8000, decode_data); result = sceAtracGetRemainFrame(atracID, &remainFrame); if (steps < 4) { printf("sceAtracDecodeData: %08X, at3_size: %d, decode_size: %d, samples: %d, end: %d, remainFrame: %d\n\n", result, at3_size, decode_size, samples, end, remainFrame); if (steps == 1) { for (n = 0; n < 32; n++) printf("%04X ", (u16)decode_data[n]); } printf("sceAtracGetRemainFrame: %08X\n", result); } steps++; } sceAudioChRelease(channel); result = sceAtracReleaseAtracID(atracID); printf("sceAtracGetRemainFrame: %08X\n", result); return 0; }
int T_Audio(SceSize _args, void *_argp) { DecoderThreadData* D = *((DecoderThreadData**)_argp); sceKernelWaitSema(D->Audio->m_SemaphoreStart, 1, 0); for(;;) { if(D->Audio->m_iAbort != 0) break; if(D->Audio->m_iFullBuffers > 0) { sceAudioOutputBlocking(D->Audio->m_AudioChannel, PSP_AUDIO_VOLUME_MAX, D->Audio->m_pAudioBuffer[D->Audio->m_iPlayBuffer]); D->Audio->m_iPlayBuffer = (D->Audio->m_iPlayBuffer + 1) % D->Audio->m_iNumBuffers; sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0); D->Audio->m_iFullBuffers--; sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1); } else { sceKernelDelayThread(1000); } sceKernelDelayThread(100); stop_pmf(); /*Human-Behind ** use to stop*/ if(stop == 1) { break; }/*Human-Behind ** use to stop*/ } while(D->Audio->m_iFullBuffers > 0) { sceAudioOutputBlocking(D->Audio->m_AudioChannel, PSP_AUDIO_VOLUME_MAX, D->Audio->m_pAudioBuffer[D->Audio->m_iPlayBuffer]); D->Audio->m_iPlayBuffer = (D->Audio->m_iPlayBuffer + 1) % D->Audio->m_iNumBuffers; sceKernelWaitSema(D->Audio->m_SemaphoreLock, 1, 0); D->Audio->m_iFullBuffers--; sceKernelSignalSema(D->Audio->m_SemaphoreLock, 1); sceKernelDelayThread(100); stop_pmf(); /*Human-Behind ** use to stop*/ if(stop == 1) { break; }/*Human-Behind ** use to stop*/ } sceKernelExitThread(0); return 0; }