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

📄 mpeg.c

📁 编译后直接运行的MP3播放器全部C语言源代码 一个包含FAT文件系统、系统引导 Boot、FLASH Driver等内容的
💻 C
📖 第 1 页 / 共 5 页
字号:
                if (id3->vbr)                {                    if (id3->has_toc)                    {                        /* Use the TOC to find the new position */                        unsigned int percent, remainder;                        int curtoc, nexttoc, plen;                                                percent = (newtime*100)/id3->length;                         if (percent > 99)                            percent = 99;                                                curtoc = id3->toc[percent];                                                if (percent < 99)                            nexttoc = id3->toc[percent+1];                        else                            nexttoc = 256;                                                newpos = (id3->filesize/256)*curtoc;                                                /* Use the remainder to get a more accurate position */                        remainder   = (newtime*100)%id3->length;                        remainder   = (remainder*100)/id3->length;                        plen        = (nexttoc - curtoc)*(id3->filesize/256);                        newpos     += (plen/100)*remainder;                    }                    else                    {                        /* No TOC exists, estimate the new position */                        newpos = (id3->filesize / (id3->length / 1000)) *                            (newtime / 1000);                    }                }                else if (id3->bpf && id3->tpf)                    newpos = (newtime/id3->tpf)*id3->bpf;                else                {                    /* Not enough information to FF/Rewind */                    id3->elapsed = oldtime;                    break;                }                if (newpos >= (int)(id3->filesize - id3->id3v1len))                {                    /* Don't seek right to the end of the file so that we can                       transition properly to the next song */                    newpos = id3->filesize - id3->id3v1len - 1;                }                else if (newpos < (int)id3->first_frame_offset)                {                    /* skip past id3v2 tag and other leading garbage */                    newpos = id3->first_frame_offset;                }                if (mpeg_file >= 0)                    curpos = lseek(mpeg_file, 0, SEEK_CUR);                else                    curpos = id3->filesize;                if (num_tracks_in_memory() > 1)                {                    /* We have started loading other tracks that need to be                       accounted for */                    int i = tag_read_idx;                    int j = tag_write_idx - 1;                    if (j < 0)                        j = MAX_ID3_TAGS - 1;                    while (i != j)                    {                        curpos += id3tags[i]->id3.filesize;                        i = (i+1) & MAX_ID3_TAGS_MASK;                    }                }                diffpos = curpos - newpos;                if(!filling && diffpos >= 0 && diffpos < mp3buflen)                {                    int unplayed_space_left, unswapped_space_left;                    /* We are changing to a position that's already in                       memory, so we just move the DMA read pointer. */                    mp3buf_read = mp3buf_write - diffpos;                    if (mp3buf_read < 0)                    {                        mp3buf_read += mp3buflen;                    }                    unplayed_space_left  = get_unplayed_space();                    unswapped_space_left = get_unswapped_space();                    /* If unswapped_space_left is larger than                       unplayed_space_left, it means that the swapwrite pointer                       hasn't yet advanced up to the new location of the read                       pointer. We just move it, there is no need to swap                       data that won't be played anyway. */                                        if (unswapped_space_left > unplayed_space_left)                    {                        DEBUGF("Moved swapwrite\n");                        mp3buf_swapwrite = mp3buf_read;                        play_pending = true;                    }                    if (mpeg_file>=0 && unplayed_space_left < low_watermark)                    {                        /* We need to load more data before starting */                        filling = true;                        queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                        play_pending = true;                    }                    else                    {                        /* resume will start at new position */                        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;                    }                }                else                {                    /* Move to the new position in the file and start                       loading data */                    reset_mp3_buffer();                    if (num_tracks_in_memory() > 1)                    {                        /* We have to reload the current track */                        close(mpeg_file);                        remove_all_non_current_tags();                        mpeg_file = -1;                    }                    if (mpeg_file < 0)                    {                        mpeg_file = open(id3->path, O_RDONLY);                        if (mpeg_file < 0)                        {                            id3->elapsed = oldtime;                            break;                        }                    }                    if(-1 == lseek(mpeg_file, newpos, SEEK_SET))                    {                        id3->elapsed = oldtime;                        break;                    }                    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;                }                id3->offset = newpos;                break;            }            case MPEG_FLUSH_RELOAD: {                int  numtracks    = num_tracks_in_memory();                bool reload_track = false;                if (numtracks > 1)                {                    /* Reload songs */                    int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;                    /* Reset the buffer */                    mp3buf_write = id3tags[next]->mempos;                    /* Reset swapwrite unless we're still swapping current                       track */                    if (get_unplayed_space() <= get_playable_space())                        mp3buf_swapwrite = mp3buf_write;                    close(mpeg_file);                    remove_all_non_current_tags();                    mpeg_file = -1;                    reload_track = true;                }                else if (numtracks == 1 && mpeg_file < 0)                {                    reload_track = true;                }                if(reload_track && new_file(1) >= 0)                {                    /* Tell ourselves that we want more data */                    queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                    filling = true;                }                break;            }            case MPEG_NEED_DATA:                free_space_left = mp3buf_read - mp3buf_write;                /* We interpret 0 as "empty buffer" */                if(free_space_left <= 0)                    free_space_left = mp3buflen + free_space_left;                unplayed_space_left = mp3buflen - free_space_left;                /* Make sure that we don't fill the entire buffer */                free_space_left -= MPEG_HIGH_WATER;                /* do we have any more buffer space to fill? */                if(free_space_left <= MPEG_HIGH_WATER)                {                    DEBUGF("0\n");                    filling = false;                    ata_sleep();                    break;                }                /* Read small chunks while we are below the low water mark */                if(unplayed_space_left < low_watermark)                    amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,                                         free_space_left);                else                    amount_to_read = free_space_left;                /* Don't read more than until the end of the buffer */                amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);#if MEM == 8                    amount_to_read = MIN(0x100000, amount_to_read);#endif /* #if MEM == 8 */                /* Read as much mpeg data as we can fit in the buffer */                if(mpeg_file >= 0)                {                    DEBUGF("R\n");                    t1 = current_tick;                    len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);                    if(len > 0)                    {                        t2 = current_tick;                        DEBUGF("time: %d\n", t2 - t1);                        DEBUGF("R: %x\n", len);                        /* Now make sure that we don't feed the MAS with ID3V1                           data */                        if (len < amount_to_read)                        {                            int tagptr = mp3buf_write + len - 128;                            int i;                            char *tag = "TAG";                            int taglen = 128;                                                        for(i = 0;i < 3;i++)                            {                                if(tagptr >= mp3buflen)                                    tagptr -= mp3buflen;                                if(mp3buf[tagptr] != tag[i])                                    taglen = 0;                                tagptr++;                            }                            if(taglen)                            {                                /* Skip id3v1 tag */                                DEBUGF("Skipping ID3v1 tag\n");                                len -= taglen;                                /* The very rare case when the entire tag                                   wasn't read in this read() call must be                                   taken care of */                                if(len < 0)                                    len = 0;                            }                        }                        mp3buf_write += len;                                                if(mp3buf_write >= mp3buflen)                        {                            mp3buf_write = 0;                            DEBUGF("W\n");                        }                        /* Tell ourselves that we want more data */                        queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                    }                    else                    {                        if(len < 0)                        {                            DEBUGF("MPEG read error\n");                        }                                                close(mpeg_file);                        mpeg_file = -1;                                            if(new_file(1) < 0)                        {                            /* No more data to play */                            DEBUGF("No more files to play\n");                            filling = false;                        }                        else                        {                            /* Tell ourselves that we want more data */                            queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);                        }                    }                }                break;                            case MPEG_TRACK_CHANGE:                track_change();                break;#ifndef USB_NONE            case SYS_USB_CONNECTED:                is_playing = false;                paused = false;                stop_playing();#ifndef SIMULATOR                                /* 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);#endif /* #ifndef SIMULATOR */                break;#endif /* #ifndef USB_NONE */                #ifdef HAVE_MAS3587F            case MPEG_INIT_RECORDING:                init_recording();                init_recording_done = true;                break;#endif /* #ifdef HAVE_MAS3587F */            }#ifdef HAVE_MAS3587F        }        else        {            queue_wait(&mpeg_queue, &ev);            switch(ev.id)            {                case MPEG_RECORD:                    if(is_prerecording)                    {                        int startpos, i;                                                /* Go back prerecord_count seconds in the buffer */                        startpos = prerecord_index - prerecord_count;                        if(startpos < 0)                            startpos += prerecording_max_seconds;                        /* Read the mp3 buffer pointer from the prerecord buffer */                        startpos = prerecord_buffer[startpos];                        DEBUGF("Start looking at address %x (%x)\n",                               mp3buf+startpos, startpos);                        saved_header = get_last_recorded_header();                                                mem_find_next_frame(startpos, &offset, 5000,                                            saved_header);                        mp3buf_read = startpos + offset;                                                DEBUGF("New mp3buf_read address: %x (%x)\n",                               mp3buf+mp3buf_read, mp3buf_read);                        /* Make room for headers */                        mp3buf_read -= MPEG_RESERVED_HEADER_SPACE;                        if(mp3buf_read < 0)                        {                            /* Clear the bottom half */                            memset(mp3buf, 0,                                   mp3buf_read + MPEG_RESERVED_HEADER_SPACE);                            /* And the top half */                            mp3buf_read += mp3buflen;                            memset(mp3buf + mp3buf_read, 0,                                   mp3buflen - mp3buf_read);                        }                        else                        {                            memset(mp3buf + mp3buf_read, 0,                                   MPEG_RESERVED_HEADER_SPACE);                        }                        /* Copy the empty ID3 header */                        startpos = mp3buf_read;                        for(i = 0;i < (int)sizeof(empty_id3_header);i++)                        {                            mp3buf[startpos++] = empty_id3_header[i];                            if(startpos == mp3buflen)

⌨️ 快捷键说明

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