⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Stop the current stream */    mp3_play_stop();    playing = false;    filling = false;    if(mpeg_file >= 0)        close(mpeg_file);    mpeg_file = -1;    remove_all_tags();}static void update_playlist(void){    int index;    if (num_tracks_in_memory() > 0)    {        index = playlist_next(id3tags[tag_read_idx]->id3.index);        id3tags[tag_read_idx]->id3.index = index;    }}static void track_change(void){    DEBUGF("Track change\n");#ifdef HAVE_MAS3587F    /* Reset the AVC */    mpeg_sound_set(SOUND_AVC, -1);#endif /* #ifdef HAVE_MAS3587F */    remove_current_tag();    update_playlist();    current_track_counter++;}#ifdef DEBUGvoid hexdump(unsigned char *buf, int len){    int i;    for(i = 0;i < len;i++)    {        if(i && (i & 15) == 0)        {            DEBUGF("\n");        }        DEBUGF("%02x ", buf[i]);    }    DEBUGF("\n");}#endif /* #ifdef DEBUG */static void start_playback_if_ready(void){    int playable_space;    playable_space = mp3buf_swapwrite - mp3buf_read;    if(playable_space < 0)        playable_space += mp3buflen;        /* See if we have started playing yet. If not, do it. */    if(play_pending || dma_underrun)    {        /* If the filling has stopped, and we still haven't reached           the watermark, the file must be smaller than the           watermark. We must still play it. */        if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||           !filling || dma_underrun)        {            DEBUGF("P\n");            play_pending = false;            playing = true;			            if (!paused)            {                last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());                mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);                dma_underrun = false;                last_dma_tick = current_tick;                mp3_play_pause(true);            }            /* Tell ourselves that we need more data */            queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);        }    }}static bool swap_one_chunk(void){    int free_space_left;    int amount_to_swap;    free_space_left = get_unswapped_space();    if(free_space_left == 0 && !play_pending)        return false;    /* Swap in larger chunks when the user is waiting for the playback       to start, or when there is dangerously little playable data left */    if(play_pending)        amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);    else    {        if(get_playable_space() < low_watermark)            amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,                                 free_space_left);        else            amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);    }        if(mp3buf_write < mp3buf_swapwrite)        amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,                             amount_to_swap);    else        amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,                             amount_to_swap);    bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);    mp3buf_swapwrite += amount_to_swap;    if(mp3buf_swapwrite >= mp3buflen)    {        mp3buf_swapwrite = 0;    }    return true;}static const unsigned char empty_id3_header[] ={    'I', 'D', '3', 0x04, 0x00, 0x00,    0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */};#ifdef HAVE_MAS3587Fstatic unsigned long get_last_recorded_header(void){    unsigned long tmp[2];    /* Read the frame data from the MAS and reconstruct it with the       frame sync and all */    mas_readmem(MAS_BANK_D0, 0xfd1, tmp, 2);    return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);}#endif /* #ifdef HAVE_MAS3587F */static void mpeg_thread(void){    static int pause_tick = 0;    static unsigned int pause_track = 0;    struct event ev;    int len;    int free_space_left;    int unplayed_space_left;    int amount_to_read;    int t1, t2;    int start_offset;#ifdef HAVE_MAS3587F    int amount_to_save;    int writelen;    int framelen;    unsigned long saved_header = 0;    int startpos;    int rc;    int offset;    int countdown;#endif /* #ifdef HAVE_MAS3587F */        is_playing = false;    play_pending = false;    playing = false;    mpeg_file = -1;    while(1)    {#ifdef HAVE_MAS3587F        if(mpeg_mode == MPEG_DECODER)        {#endif /* #ifdef HAVE_MAS3587F */        yield();        /* Swap if necessary, and don't block on the queue_wait() */        if(swap_one_chunk())        {            queue_wait_w_tmo(&mpeg_queue, &ev, 0);        }        else        {            DEBUGF("S R:%x W:%x SW:%x\n",                   mp3buf_read, mp3buf_write, mp3buf_swapwrite);            queue_wait(&mpeg_queue, &ev);        }        start_playback_if_ready();                switch(ev.id)        {            case MPEG_PLAY:                DEBUGF("MPEG_PLAY\n");#ifdef HAVE_FMRADIO                /* Silence the A/D input, it may be on because the radio                   may be playing */                mas_codec_writereg(6, 0x0000);#endif /* #ifdef HAVE_FMRADIO */                /* Stop the current stream */                play_pending = false;                playing = false;                paused = false;                mp3_play_pause(false);                reset_mp3_buffer();                remove_all_tags();                if(mpeg_file >= 0)                    close(mpeg_file);                if ( new_file(0) == -1 )                {                    is_playing = false;                    track_change();                    break;                }                start_offset = (int)ev.data;                /* mid-song resume? */                if (start_offset) {                    struct mp3entry* id3 = &id3tags[tag_read_idx]->id3;                    lseek(mpeg_file, start_offset, SEEK_SET);                    id3->offset = start_offset;                    set_elapsed(id3);                }                else {                    /* skip past id3v2 tag */                    lseek(mpeg_file,                           id3tags[tag_read_idx]->id3.first_frame_offset,                           SEEK_SET);                }                /* Make it read more data */                filling = true;                queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                /* Tell the file loading code that we want to start playing                   as soon as we have some data */                play_pending = true;                update_playlist();                current_track_counter++;                break;            case MPEG_STOP:                DEBUGF("MPEG_STOP\n");                is_playing = false;                paused = false;                stop_playing();                mpeg_stop_done = true;                break;            case MPEG_PAUSE:                DEBUGF("MPEG_PAUSE\n");                /* Stop the current stream */                paused = true;                playing = false;                pause_tick = current_tick;                pause_track = current_track_counter;                mp3_play_pause(false);                break;            case MPEG_RESUME:                DEBUGF("MPEG_RESUME\n");                /* Continue the current stream */                paused = false;                if (!play_pending)                {                    playing = true;                    if ( current_track_counter == pause_track )                        last_dma_tick += current_tick - pause_tick;                    else                        last_dma_tick = current_tick;                                            pause_tick = 0;                    mp3_play_pause(true);                }                break;            case MPEG_NEXT:                DEBUGF("MPEG_NEXT\n");                /* is next track in ram? */                if ( num_tracks_in_memory() > 1 ) {                    int unplayed_space_left, unswapped_space_left;                    /* stop the current stream */                    play_pending = false;                    playing = false;                    mp3_play_pause(false);                    track_change();                    mp3buf_read = id3tags[tag_read_idx]->mempos;                    last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());                    mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);                    dma_underrun = false;                    last_dma_tick = current_tick;                    unplayed_space_left  = get_unplayed_space();                    unswapped_space_left = get_unswapped_space();                    /* should we start reading more data? */                    if(!filling && (unplayed_space_left < low_watermark)) {                        filling = true;                        queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                        play_pending = true;                    } else if(unswapped_space_left &&                              unswapped_space_left > unplayed_space_left) {                        /* Stop swapping the data from the previous file */                        mp3buf_swapwrite = mp3buf_read;                        play_pending = true;                    } else {                        playing = true;                        if (!paused)                            mp3_play_pause(true);                    }                }                else {                    if (!playlist_check(1))                        break;                    /* stop the current stream */                    play_pending = false;                    playing = false;                    mp3_play_pause(false);                    reset_mp3_buffer();                    remove_all_tags();                    /* Open the next file */                    if (mpeg_file >= 0)                        close(mpeg_file);                                        if (new_file(1) < 0) {                        DEBUGF("No more files to play\n");                        filling = false;                    } else {                        /* Make it read more data */                        filling = true;                        queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                                                /* Tell the file loading code that we want                           to start playing as soon as we have some data */                        play_pending = true;                        update_playlist();                        current_track_counter++;                    }                }                break;            case MPEG_PREV: {                DEBUGF("MPEG_PREV\n");                if (!playlist_check(-1))                    break;                                /* stop the current stream */                play_pending = false;                playing = false;                mp3_play_pause(false);                reset_mp3_buffer();                remove_all_tags();                /* Open the next file */                if (mpeg_file >= 0)                    close(mpeg_file);                if (new_file(-1) < 0) {                    DEBUGF("No more files to play\n");                    filling = false;                } else {                    /* Make it read more data */                    filling = true;                    queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                    /* Tell the file loading code that we want to                       start playing as soon as we have some data */                    play_pending = true;                    update_playlist();                    current_track_counter++;                }                break;            }            case MPEG_FF_REWIND: {                struct mp3entry *id3  = mpeg_current_track();                unsigned int oldtime  = id3->elapsed;                unsigned int newtime  = (unsigned int)ev.data;                int curpos, newpos, diffpos;                DEBUGF("MPEG_FF_REWIND\n");                id3->elapsed = newtime;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -