📄 mpeg.c
字号:
startpos = 0; } DEBUGF("New mp3buf_read address (reservation): %x\n", mp3buf+mp3buf_read); DEBUGF("Prerecording...\n"); } else { reset_mp3_buffer(); num_rec_bytes = 0; /* Advance the write pointer to make room for an ID3 tag plus a VBR header */ mp3buf_write = MPEG_RESERVED_HEADER_SPACE; memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE); /* Insert the ID3 header */ memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header)); DEBUGF("Recording...\n"); } start_recording(); mpeg_file = open(recording_filename, O_WRONLY|O_CREAT); if(mpeg_file < 0) panicf("recfile: %d", mpeg_file); break; case MPEG_STOP: DEBUGF("MPEG_STOP\n"); /* Store the last recorded header for later use by the Xing header generation */ saved_header = get_last_recorded_header(); stop_recording(); /* Save the remaining data in the buffer */ stop_pending = true; queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0); break; case MPEG_STOP_DONE: DEBUGF("MPEG_STOP_DONE\n"); if(mpeg_file >= 0) close(mpeg_file); if(!disable_xing_header) { /* Create the Xing header */ mpeg_file = open(recording_filename, O_RDWR); if(mpeg_file < 0) panicf("rec upd: %d (%s)", mpeg_file, recording_filename); /* If the number of recorded frames have reached 0x7ffff, we can no longer trust it */ if(num_recorded_frames == 0x7ffff) num_recorded_frames = 0; /* Also, if we have been prerecording, the frame count will be wrong */ if(prerecording) num_recorded_frames = 0; /* saved_header is saved right before stopping the MAS */ framelen = create_xing_header(mpeg_file, 0, num_rec_bytes, mp3buf, num_recorded_frames, saved_header, NULL, false); lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen, SEEK_SET); write(mpeg_file, mp3buf, framelen); close(mpeg_file); } mpeg_file = -1; #ifdef DEBUG1 { int i; for(i = 0;i < 512;i++) { DEBUGF("%d - %d us (%d bytes)\n", timing_info[i*2], (timing_info[i*2+1] & 0xffff) * 10000 / 13824, timing_info[i*2+1] >> 16); } }#endif /* #ifdef DEBUG1 */ if(prerecording) { start_prerecording(); } mpeg_stop_done = true; break; case MPEG_NEW_FILE: /* Make sure we have at least one complete frame in the buffer. If we haven't recorded a single frame within 200ms, the MAS is probably not recording anything, and we bail out. */ countdown = 20; amount_to_save = get_unsaved_space(); while(countdown-- && amount_to_save < 1800) { sleep(HZ/10); amount_to_save = get_unsaved_space(); } if(amount_to_save >= 1800) { /* Now find a frame boundary to split at */ startpos = mp3buf_write - 1800; if(startpos < 0) startpos += mp3buflen; saved_header = get_last_recorded_header(); rc = mem_find_next_frame(startpos, &offset, 1800, saved_header); if(rc) /* Header found? */ { /* offset will now contain the number of bytes to add to startpos to find the frame boundary */ startpos += offset; if(startpos >= mp3buflen) startpos -= mp3buflen; } else { /* No header found. Let's save the whole buffer. */ startpos = mp3buf_write; } } else { /* Too few bytes recorded, timeout */ startpos = mp3buf_write; } amount_to_save = startpos - mp3buf_read; if(amount_to_save < 0) amount_to_save += mp3buflen; /* First save up to the end of the buffer */ writelen = MIN(amount_to_save, mp3buflen - mp3buf_read); if(writelen) { rc = write(mpeg_file, mp3buf + mp3buf_read, writelen); if(rc < 0) { if(errno == ENOSPC) { mpeg_errno = MPEGERR_DISK_FULL; demand_irq_enable(false); stop_recording(); queue_post(&mpeg_queue, MPEG_STOP_DONE, 0); break; } else { panicf("spt wrt: %d", rc); } } } /* Then save the rest */ writelen = amount_to_save - writelen; if(writelen) { rc = write(mpeg_file, mp3buf, writelen); if(rc < 0) { if(errno == ENOSPC) { mpeg_errno = MPEGERR_DISK_FULL; demand_irq_enable(false); stop_recording(); queue_post(&mpeg_queue, MPEG_STOP_DONE, 0); break; } else { panicf("spt wrt: %d", rc); } } } /* Advance the buffer pointers */ mp3buf_read += amount_to_save; if(mp3buf_read >= mp3buflen) mp3buf_read -= mp3buflen; /* Close the current file */ rc = close(mpeg_file); if(rc < 0) panicf("spt cls: %d", rc); /* Open the new file */ mpeg_file = open(recording_filename, O_WRONLY|O_CREAT); if(mpeg_file < 0) panicf("sptfile: %d", mpeg_file); break; case MPEG_SAVE_DATA: amount_to_save = get_unsaved_space(); /* If the result is negative, the write index has wrapped */ if(amount_to_save < 0) { amount_to_save += mp3buflen; } DEBUGF("r: %x w: %x\n", mp3buf_read, mp3buf_write); DEBUGF("ats: %x\n", amount_to_save); /* Save data only if the buffer is getting full, or if we should stop recording */ if(amount_to_save) { if(mp3buflen - amount_to_save < MPEG_RECORDING_LOW_WATER || stop_pending) { /* Only save up to the end of the buffer */ writelen = MIN(amount_to_save, mp3buflen - mp3buf_read); DEBUGF("wrl: %x\n", writelen); rc = write(mpeg_file, mp3buf + mp3buf_read, writelen); if(rc < 0) { if(errno == ENOSPC) { mpeg_errno = MPEGERR_DISK_FULL; stop_recording(); queue_post(&mpeg_queue, MPEG_STOP_DONE, 0); break; } else { panicf("rec wrt: %d", rc); } } mp3buf_read += amount_to_save; if(mp3buf_read >= mp3buflen) mp3buf_read = 0; rc = fsync(mpeg_file); if(rc < 0) panicf("rec fls: %d", rc); queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0); } else { saving = false; ata_sleep(); } } else { /* We have saved all data, time to stop for real */ if(stop_pending) queue_post(&mpeg_queue, MPEG_STOP_DONE, 0); saving = false; ata_sleep(); } break; case MPEG_INIT_PLAYBACK: /* Stop the prerecording */ stop_recording(); mp3_play_init(); init_playback_done = true; break; case SYS_USB_CONNECTED: /* We can safely go to USB mode if no recording is taking place */ if((!is_recording || is_prerecording) && mpeg_stop_done) { /* Even if we aren't recording, we still call this function, to put the MAS in monitoring mode, to save power. */ stop_recording(); /* Tell the USB thread that we are safe */ DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n"); usb_acknowledge(SYS_USB_CONNECTED_ACK); /* Wait until the USB cable is extracted again */ usb_wait_for_disconnect(&mpeg_queue); } break; } }#endif /* #ifdef HAVE_MAS3587F */ }}#endif /* SIMULATOR */#ifdef SIMULATORstatic struct mp3entry taginfo;#endif /* #ifdef SIMULATOR */struct mp3entry* mpeg_current_track(){#ifdef SIMULATOR return &taginfo;#else if(num_tracks_in_memory()) return &(id3tags[tag_read_idx]->id3); else return NULL;#endif /* #ifdef SIMULATOR */}struct mp3entry* mpeg_next_track(){#ifdef SIMULATOR return &taginfo;#else if(num_tracks_in_memory() > 1) return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK]->id3); else return NULL;#endif /* #ifdef SIMULATOR */}bool mpeg_has_changed_track(void){ if(last_track_counter != current_track_counter) { last_track_counter = current_track_counter; return true; } return false;}#ifdef HAVE_MAS3587Fvoid mpeg_init_playback(void){ init_playback_done = false; queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL); while(!init_playback_done) sleep_thread(); wake_up_thread();}/**************************************************************************** ** ** ** Recording functions ** ** ***************************************************************************/void mpeg_init_recording(void){ init_recording_done = false; queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL); while(!init_recording_done) sleep_thread(); wake_up_thread();}static void init_recording(void){ unsigned long val; int rc; /* Disable IRQ6 */ IPRB &= 0xff0f; stop_playing(); is_playing = false; paused = false; reset_mp3_buffer(); remove_all
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -