void play_fill_buffer(void) { if (gDMABufferDone) { UINT bytesRead; uint8_t readBufIx = 1 - gActiveDMABuffer; // Which buffer we are going to fill from SD card data // Have we marked a "last buffer to play"? if (gCtrlFlags & (CTRL_FLAG_BUFFER0_IS_LAST|CTRL_FLAG_BUFFER1_IS_LAST)) { if (DMA.CTRL & DMA_CH_ENABLE_bm) { // Still transferring...just let it go return; } // DMA ISR has stopped the transfer process. We're done. play_stop(); return; } gDMABufferDone = 0; if (! wav_fill_buffer((uint16_t *)(gBuffers[readBufIx]), &bytesRead)) { play_stop(); return; } _transform_buffer((uint16_t *)gBuffers[readBufIx], BUFFER_SIZE/2); // Is this the last buffer? If so, fill it with 0's and set a flag indicating // that on the next ping-pong, we should quit. if (bytesRead < BUFFER_SIZE) { char *ptr; ptr = (char *)(gBuffers[readBufIx]) + bytesRead; memset(ptr, 0, BUFFER_SIZE-bytesRead); // Indicate that after the buffer we've just read in plays, we should stop gCtrlFlags = (1 << (readBufIx)); } // Are we waiting to kickstart the playback? if (gCtrlFlags & CTRL_FLAG_KICKSTART) { rateclock_start(gWAVInfo.mSamplingRate); // DMA transfers will start shortly, triggered by Event Channel 0 // Enable Channel 0. Let double-buffering action enable buffer 1 after first block of channel 0 is done. DMA.CH0.CTRLA |= DMA_ENABLE_bm; // Fill the other buffer now too gDMABufferDone = 1; gActiveDMABuffer = 0; gCtrlFlags &= ~CTRL_FLAG_KICKSTART; } } }
void CPPlayer::play_start(int p_pattern, int p_order, int p_row,bool p_lock) { if (control.play_mode!=PLAY_NOTHING) play_stop(); reset(); if (p_pattern!=-1) { control.play_mode=PLAY_PATTERN; control.position.current_pattern=p_pattern; control.position.current_row=(p_row!=-1)?p_row:0; } else { control.position.current_order=get_song_next_order_idx(song,(p_order==-1)?p_order:p_order-1); if (control.position.current_order!=-1) { control.play_mode=PLAY_SONG; control.position.current_pattern=song->get_order(control.position.current_order); control.position.current_row=(p_row!=-1)?p_row:0; } } control.reached_end=(control.play_mode==PLAY_NOTHING); }
// ---------------------------------------------------------------------------- void player::stop() { command_queue_.push([this]() { play_stop(); }); }
U8 Key_Detect(void) { if(gc_KeyValue==0) { gc_KeyEvent=0; return 1; } else { gc_KeyEvent = gc_KeyValue; gc_KeyValue = 0; //#if 0 //由于长按PLAY需要做成 if(gc_KeyEvent==0x12) { //sunzhk add power off 100809 if( gs_System_State.c_Phase==TASK_PHASE_PAUSE) { MediaChange(); return 0; } else { if(gc_Task_Current == C_Task_Play) { play_stop(); } else if(gc_Task_Current == C_Task_Jpeg) { jpeg_stop(); } else if(gc_Task_Current == C_Task_Mjpeg) { mjpeg_stop(); } } gc_Task_Next = C_Task_PowerOff; gc_PhaseInx = C_PowerOff; gc_KeyEvent = 0; return 0; } //#endif if(gc_Task_Current==C_Task_Play) //20090107 chiayen modify { ProcKey_in_play(); } else if(gc_Task_Current==C_Task_Jpeg) //20090107 chiayen modify { ProcKey_in_jpeg(); } else if(gc_Task_Current==C_Task_Mjpeg) //20090107 chiayen modify { ProcKey_in_mjpeg(); } else { ProcKey_in_play(); } return 0; } }
// ---------------------------------------------------------------------------- void player::skip() { command_queue_.push([this]() { play_stop(); play_from_queue(); }); }
int play_wav(const char *wavname) { FIL fwav; FRESULT res; UINT readsize; unsigned char wavbuff[44]; unsigned int wavfreq,wavsize; int stmono,samplebit,err; // WAVファイルを開く res = f_open(&fwav, wavname, FA_READ); if(res != FR_OK) { printf("[!] file open failure. (code:%d)\n", res); return -1; } // WAVヘッダの解析(簡易版) err = 1; res = f_read(&fwav, wavbuff, 44, &readsize); // ヘッダ読み出し if (res == FR_OK && readsize == 44) { if (wavbuff[8]=='W' && wavbuff[9]=='A' && wavbuff[10]=='V' && wavbuff[11]=='E' && // WAVチャンク wavbuff[20] == 0x01) { // リニアPCM stmono = wavbuff[22]; // モノラル=1,ステレオ=2 wavfreq = (wavbuff[25]<< 8)| wavbuff[24]; samplebit = wavbuff[34]; // サンプルあたりのビット数 16/8 wavsize = (wavbuff[43]<<24)|(wavbuff[42]<<16)|(wavbuff[41]<< 8)| wavbuff[40]; if (stmono == 2 && samplebit == 16 && wavfreq == pcm_samplefreq) err = 0; } } if (err) { printf("[!] '%s' is not supported.\n", wavname); f_close(&fwav); return -1; } // 再生開始 printf("wavfile : %s\n freq %dHz / time %dsec\n",wavname, wavfreq, wavsize/(wavfreq*4)); if (g_wavsize) play_stop(); // もし再生中のファイルがあれば停止させる g_fsobj = fwav; g_wavsize = wavsize; g_playsize = 0; isr_handle_pcmfifofill(NULL); // 再生FIFO割り込みをキック return wavsize; // WAVファイルサイズを返す }
void play(char *fname) { int fi[2]; int fo[2]; struct stat st; int i; i = 5; while( stat(fname, &st) == -1) //文件不存在 { sleep(1); LOGPRINT("stat:%s\n", errstr()); if(i-- == 0) { return; } } play_stop(); pipe(fi); pipe(fo); signal(SIGCHLD, do_wait); playing = 1; if(fork() == 0) { dup2(fi[0], 0); dup2(fo[1], 1); close(fi[0]); close(fi[1]); close(fo[0]); close(fo[1]); close(2); LOGPRINT("play:%s\n", fname); execlp("mplayer", "mplayer", "-slave", "-quiet", fname, NULL); exit(-1); } close(fi[0]); close(fo[1]); fin = fi[1]; fout = fo[0]; }
// ---------------------------------------------------------------------------- std::string player::play_tag(std::string tag) { auto promise = std::make_shared<std::promise<std::string>>(); command_queue_.push([=]() { // Reinitialize continous playback selector. ctpb_selector_.init_by_tag(tag); play_queue_.clear(); play_queue_.push(ctpb_selector_.next()); play_stop(); play_from_queue(); promise->set_value("ok"); }); return promise->get_future().get(); }
// ---------------------------------------------------------------------------- void player::play_from_queue() { if ( play_queue_.size() > 0 ) { auto track = play_queue_.front(); auto src = track.find_source(); if ( !src.is_null() ) { std::cerr << "play_from_queue id=" << track.id() << ", title='" << track.title() << "', source=" << src.name() << std::endl; state_.state = playing; state_.track = std::move(track); state_.source = src.name(); std::cout << "player state=" << state_.state << std::endl; if ( !audio_output_ ) { audio_output_open(); } play_source(src); play_queue_.pop(); } else { std::cerr << "play_from_queue id=" << track.id() << ", title='" << track.title() << "', NO SOURCE!" << std::endl; play_queue_.pop(); play_from_queue(); } } else if ( continuous_playback_ ) { play_queue_.push(ctpb_selector_.next()); play_from_queue(); } else { play_stop(); } }
/** * @brief Get an event * * Wait for an event from the standard input. * * @param ui User Interface. */ static void ui_read_input(UI *ui) { char *buffer; char cmd[8]; Event *event = ui->event; Play *play = ui->play; buffer = string_read_line(stdin); if (buffer == NULL) { if (ferror(stdin)) { if (errno == EINTR) clearerr(stdin); else fatal_error("stdin is broken\n"); } else if (feof(stdin)) { buffer = string_duplicate("eof"); } event->loop = false; } else { if (ui->type == UI_GTP) gtp_preprocess(buffer); parse_word(buffer, cmd, 5); string_to_lowercase(cmd); if (strcmp(cmd, "stop") == 0) { event_clear_messages(event); info("<stop>\n"); play_stop(play); if (ui->type == UI_GGS) play_stop(play + 1); } else if (ui->type == UI_NBOARD && strcmp(cmd, "ping") == 0) { play_stop(play); } else if (ui->type == UI_XBOARD && strcmp(cmd, "?") == 0) { play_stop(play); } else { if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0) { event_clear_messages(event); play_stop(play); if (ui->type == UI_GGS) play_stop(play + 1); event->loop = false; } } } if (buffer) { lock(event); event_add_message(event, buffer); condition_signal(event); unlock(event); } }
/** * @brief ui_loop_ggs * * GGS main loop. Here the input from both the user and * GGS server is interpreted. * * @param ui User Interface. */ void ui_loop_ggs(UI *ui) { char *cmd = NULL, *param = NULL; Text text[1]; GGSClient *client = ui->ggs; ui->mode = 3; text_init(text); for (;;) { relax(10); /* look for a user event */ if (ui_event_peek(ui, &cmd, ¶m)) { /* stop the search */ if (strcmp(cmd, "stop") == 0) { if (ui->play[0].state == IS_THINKING) play_stop(ui->play); else if (ui->play[1].state == IS_THINKING) play_stop(ui->play + 1); /* repeat a cmd <n> times */ } else if (strcmp(cmd, "loop") == 0) { free(client->loop->cmd); errno = 0; client->loop->cmd = string_duplicate(parse_int(param, &client->loop->i)); if (errno) client->loop->i = 100; if (client->loop->i > 0) { info("<loop %d>\n", client->loop->i); --client->loop->i; ggs_client_send(client, "%s\n", client->loop->cmd); } /* exit from ggs */ } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0) { ggs_client_send(client, "tell .%s Bye bye!\n", client->me); ggs_client_send(client, "quit\n"); free(cmd); free(param); return; /* send the command to ggs */ } else { ggs_client_send(client, "%s %s\n", cmd, param); } } /* stay on line... */ ggs_client_refresh(client); /* look for a ggs event */ if (!ggs_event_peek(&client->event, text)) { continue; } text_print(text, stdout); if (ggs_log->f) text_print(text, ggs_log->f); /* login */ if (ggs_login(text)) { ggs_client_send(client, "%s\n", options.ggs_login); /* password */ } else if (ggs_password(text)) { ggs_client_send(client, "%s\n", options.ggs_password); ggs_client_send(client, "vt100 -\n"); ggs_client_send(client, "bell -t -tc -tg -n -nc -ng -ni -nn\n"); ggs_client_send(client, "verbose -news -faq -help -ack\n"); ggs_client_send(client, "chann %%\n"); ggs_client_send(client, "chann + .chat\n"); ggs_client_send(client, "chann + .%s\n", client->me); ggs_client_send(client, "tell .%s Hello!\n", client->me); /* os on */ } else if (ggs_os_on(text)) { printf("[received GGS_OS_ON]\n"); ggs_client_send(client, "tell /os trust +\n" ); ggs_client_send(client, "tell /os rated +\n" ); ggs_client_send(client, "tell /os request +\n" ); ggs_client_send(client, "tell /os client -\n" ); ggs_client_send(client, "tell /os open %d\n", options.ggs_open); ggs_client_send(client, "mso\n" ); /* os off */ } else if (ggs_os_off(text)) { printf("[received GGS_OS_OFF]\n"); /* match on */ } else if (ggs_match_on(client->match_on, text)) { if (ggs_has_player(client->match_on->player, client->me)) { printf("[received GGS_MATCH_ON]\n"); client->is_playing = true; ggs_client_send(client, "tell /os open 0\n" ); } else { printf("[received GGS_WATCH_ON]\n"); } /* match off */ } else if (ggs_match_off(client->match_off, text)) { if (ggs_has_player(client->match_off->player, client->me)) { printf("[received GGS_MATCH_OFF]\n"); if (!client->match_on->match_type->is_rand) { if (client->match_on->match_type->is_synchro) { printf("[store match #1]\n"); play_store(ui->play); printf("[store match #2]\n"); play_store(ui->play + 1); } else { printf("[store match]\n"); play_store(ui->play); } if (ui->book->need_saving) { book_save(ui->book, options.book_file); ui->book->need_saving = false; } } client->is_playing = false; ggs_client_send(client, "tell /os open %d\n", options.ggs_open); if (client->loop->i > 0) { info("<loop %d>\n", client->loop->i); --client->loop->i; client->loop->delay = 10000 + real_clock(); // wait 10 sec. } } else { printf("[received GGS_WATCH_OFF]\n"); } /* board join/update */ } else if (ggs_board(client->board, text)) { if (ggs_has_player(client->board->player, client->me)) { if (client->board->is_join) ui_ggs_join(ui); else ui_ggs_update(ui); } else { printf("[received GGS_WATCH_BOARD]\n"); } /* request */ } else if (ggs_request(client->request, text)) { printf("[received GGS_REQUEST]\n"); /* admin on */ } else if (ggs_admin(client->admin, text)) { printf("[received GGS_ADMIN_CMD]\n"); ggs_client_send(client, client->admin->command); ggs_client_send(client, "\ntell %s command processed\n", client->admin->name); /* To request Saio a game later */ } else if (ggs_saio_delay(text, &client->once->delay)) { printf("[received GGS_SAIO_DELAY]\n"); free(client->once->cmd); client->once->cmd = NULL; if (cmd != NULL && param != NULL) { if (strcmp(cmd, "loop") == 0) { client->once->cmd = string_duplicate(client->loop->cmd); } else { client->once->cmd = (char*) malloc(strlen(cmd) + strlen(param) + 3); sprintf(client->once->cmd, "%s %s\n", cmd, param); } printf("[received GGS_SAIO_DELAY, retry request in %.1f s]\n", 0.001 * (client->once->delay - real_clock())); } else { client->once->delay = 0; } /* READY */ } else if (ggs_ready(text)) { /* ALERT */ } else if (ggs_alert(text)) { printf("[received ALERT]\n"); /* Other messages */ } else { } text_free(text); } }