Board logo

标题: DOS/WIN两栖的CD Player [打印本页]

作者: happybasic     时间: 2007-4-7 06:25    标题: DOS/WIN两栖的CD Player

可以在DOS下播入CD, 不需要MSCDEX的支持,
ps: 在WINDOWS下也可以哦~
作者: Wengier     时间: 2007-4-7 19:17
看日期是2007/04/06,是原创的吗?
作者: happybasic     时间: 2007-4-7 21:07
当然了,俺一般要发就发原创。虽然比较差。。。
作者: Wengier     时间: 2007-4-7 22:32
楼上谦虚了,写得比较不错,支持原创!

建议加入按上下光标键调节音量的功能,并且可以按PageUp和PageDown键切换到上一首/下一首歌曲(PageUp/PageDown键切换歌曲比起F4/F5键似乎要更自然些)。

发现有一处笔误,“暂停”的英文应为PAUSE,而不是PASUE。另外建议除按F6键外也可以按空格键来暂停。
作者: happybasic     时间: 2007-4-8 00:37
哎呀,这个笔误真是。。。已经改正了, 另你的建议也加了:

1.除按F6键外也可以按空格键来暂停。
2.除F4/F5键外也可以按PageUp和PageDown键切换到上一首/下一首歌曲。

至于按上下光标键调节音量的功能, 很多光驱模拟播放时,是不支持控制音量的啊,只能用前面板的电位器调...
附件 1: CDPLAY.rar (2007-4-8 00:37, 20.29 K,下载次数: 66)

作者: Wengier     时间: 2007-4-13 02:39
不知道楼主有没有兴趣给DOS下的MPlayer播放器写一个简单的文本方式的GUI界面?MPlayer可以在DOS下(包括纯DOS和CMD下)播放各种多媒体格式,包括AVI、MOV、MKV、MPG、RMVB、WMV,以及CD/VCD/DVD等,可惜就是只有命令行方式,没有一个像QV那样能选择文件的界面,所以使用起来有些不太方便。如果您愿意的话不妨给它写一个简单的文本方式的GUI界面试试看。更详细信息可见下面的帖子:

http://www.cn-dos.net/forum/viewthread.php?tid=16206&fpage=1
http://www.cn-dos.net/forum/viewthread.php?tid=28707&fpage=1
作者: happybasic     时间: 2007-4-13 06:50
我试试看。。。
作者: GOTOmsdos     时间: 2007-4-13 08:09


  Quote:
DOS/WIN两栖的CD Player

这个程序只是DOS程序,在WIN, 要在WIN的DOS虚拟器的环境中才能运行.
所以,它不是DOS/WIN两栖的

不需要WIN的DOS虚拟器,就能运行的才是.
比如, win98的 REGEDIT
作者: defrag     时间: 2007-5-4 20:51    标题: 用WDOS/X

用WDOS/X
作者: happybasic     时间: 2007-6-18 19:10
WDOS/X是什么啊??没用过....
作者: byxyk     时间: 2007-6-19 00:35
win32+stub ?
作者: xing7749     时间: 2007-6-19 16:43
看起来不错
作者: AlexZhang     时间: 2007-6-27 18:25    标题: Excellent

Excellent!Successfully loaded and run under WindowsXP[sp2 build2600] environment withOUT any extra tools
作者: happybasic     时间: 2008-12-3 20:21
最新版请到这里下载
http://yxbasic.51.net/zhxs-dostool.htm
作者: happybasic     时间: 2009-3-13 11:02
好久没有来了, 想不到还有不少人关注
分享一下源码....
/***************************************************************************
  name: atapiEject
  action: loads or ejects CD-ROM
  returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiEject(driveinfo *Drive, bool Load)
{
  u8 Pkt[12]={ATAPI_CMD_START_STOP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

    printf("atapiEject:");
    memset(&Cmd, 0, sizeof(Cmd));

    Pkt[4]= (Load ? 3 : 2);

    return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
    name: atapiGetEventStatus
   action: Get Disc is present && Tray opend or Closed
  returns: whatever atapiCmd() returns
****************************************************************************/
static int atapiGetEventStatus(driveinfo *Drive, u8 *Buffer, unsigned Count)
{
  u8 Pkt[12]={ATAPI_CMD_GET_EVENT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

  printf("atapiGetEventStatus:");
  memset(&Cmd, 0, sizeof(Cmd));

  Cmd.Count=Count;
  Cmd.Data=Buffer;

  Pkt[1]=1;
  Pkt[4]=0x10;
  Pkt[8]=Count;

  return(atapiCmd(Drive, &Cmd, Pkt));

}

/***************************************************************************
  name: atapiChkTrayIsOpen
action: check cd-rom tray opened or closed
returns: 1 is opend , 0 is closed  and -1 is Error
****************************************************************************/
static int atapiChkTrayIsOpen(driveinfo *Drive)
{
  u8 Buffer[8];
  int Temp;

    Temp=atapiGetEventStatus(Drive, Buffer, 6);

    if (Temp != 0)
    {
      return(-1);
    }

    return(Buffer[5]&0x01);     // Bit 0 is Tray Status, See SFF-8090 v6R7 P362
}

/***************************************************************************
  name: atapiTOCEnt
  action: reads one or more table-of-contents entries from audio CD
  returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiTOCEnt(driveinfo *Drive, u8 *Buffer, unsigned Count)
{
  u8 Pkt[12]={ATAPI_CMD_READTOC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

  printf("atapiTOCEnt:");
  memset(&Cmd, 0, sizeof(Cmd));

  Cmd.Count=Count;
  Cmd.Data=Buffer;

  Pkt[1]=2;
  Pkt[7]=Count >> 8;
  Pkt[8]=Count;

  return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
  name: atapiTOC
  action: reads table of contents of audio CD and prints starting
    time of each track
  returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiTOC(driveinfo *Drive)
{
  u8 *Entry, Buffer[4 + 8 * (MAX_TRACKS+1)];
  int TOCEnt, Temp;

    printf("atapiTOC:\n");

    // 16-bit TOC length, 8-bit first track,  8-bit last track
    TOCEnt = 4;
   
    #ifdef DEBUG
    printf("  calling atapiTOCEnt with Count=%u\n", TOCEnt);
    #endif

    // Read TOC
    Temp=atapiTOCEnt(Drive, Buffer, TOCEnt);
    if(Temp != 0)
    {
      return(Temp);
    }

    // NumTracks = LastTrack - FristTrack + 1
    NumTracks=Buffer[3] - Buffer[2] + 1;

    // Check NumTracks(must in range 1~99)
    if(NumTracks <= 0 || NumTracks > 99)
    {
      printf("  error: bad number of tracks %d\n", NumTracks);
      return(-1);
    }

    // Check MAX_TRACKS handle
    if(NumTracks > MAX_TRACKS)
    {
      printf("  warning: too many tracks(%u); reducing to %u.\n",NumTracks, MAX_TRACKS);
      NumTracks=MAX_TRACKS;
    }

    // read 4-byte header and 8-byte table-of-contents entries
    TOCEnt = 4 + 8 * (NumTracks+1);
   
    #ifdef DEBUG
    printf("  calling atapiTOCEnt with Count=%u\n", TOCEnt);
    #endif
   
    // Read TOC
    Temp=atapiTOCEnt(Drive, Buffer, TOCEnt);
    if(Temp != 0)
    {
      return(Temp);
    }

    // point to first TOC entry
    Entry=Buffer + 4;

    // read NumTracks+1 entries the last entry is for the disk lead-out
    for(Temp=0; Temp < NumTracks + 1; Temp++)
    {
      Track[Temp].Min=Entry[5];
      Track[Temp].Sec=Entry[6];
      Track[Temp].Frame=Entry[7];

      printf("%02u:%02u:%02u  ", Track[Temp].Min, Track[Temp].Sec, Track[Temp].Frame);

      // advance to next entry
      Entry += 8;
    }

    printf("\n");

  return(0);
}

/***************************************************************************
  name: atapiPlay
  action: plays audio from time index Start to End (units of 1/75 sec)
  returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiPlay(driveinfo *Drive, atapimsf *Start, atapimsf *End)
{
  u8 Pkt[12]={ATAPI_CMD_PLAY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

    printf("atapiPlay:");
    memset(&Cmd, 0, sizeof(Cmd));

    Pkt[3]=Start->Min;
    Pkt[4]=Start->Sec;
    Pkt[5]=Start->Frame;

    Pkt[6]=End->Min;
    Pkt[7]=End->Sec;
    Pkt[8]=End->Frame;

    return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
  name: atapiPause
  action: pauses or continues audio CD
  returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiPause(driveinfo *Drive, bool Continue)
{
  u8 Pkt[12]={ATAPI_CMD_PAUSE,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

    printf("atapiPause:");
    memset(&Cmd, 0, sizeof(Cmd));

    Pkt[8]=Continue ? 1 : 0;

    return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
   name: atapiStop
   action: stop audio play or scan
   return: whatever atapiCmd() returns
****************************************************************************/
static int atapiStop(driveinfo *Drive)
{
  u8 Pkt[12]={ATAPI_CMD_STOP,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  drivecmd Cmd;

    printf("atapiStop:");
    memset(&Cmd, 0, sizeof(Cmd));

    return(atapiCmd(Drive, &Cmd, Pkt));
}

作者: happybasic     时间: 2009-3-13 11:04
前面贴的是主要的一些命令,所以再加一组合就可以完成player的功能了...
/***************************************************************************
  name: AudioCDPlayer
  return: 0 - sucess
****************************************************************************/
static int AudioCDPlayer(driveinfo *Drive)
{
  bool Load=false, Disc=false, Continue=false;
  int Temp, Tries, CurrTrack=0, Key;
  
  // Show Help first
  ShowHelp();

  // Check tray status
  Temp=atapiChkTrayIsOpen(Drive);

  if (Temp == 0)                    // Tray is closed
  {
    // Read Disc TOC
    printf("\nTrying to read Audio CD Table-Of-Contents ...\n");
   
    // 5 times max for retry
    for(Tries=5; Tries>0; Tries--)
    {
      Temp=atapiTOC(Drive);
      if (Temp == 0 )
      {
        break;
      }
      delay(2000);
    }

    if (Temp == 0)                  // Disc is Ready
    {
      Disc=true;
    }
    else
    {
      printf("No Disc!");
    }
  }
  else                              // Tray is opened , can Load
  {
    Load=true;
  }

  if(Disc == true )                 // 找到碟片,且读Toc OK
  {
    printf ("Disc is READY\n");
  }

  while(1)
  {
    Key=bioskey(0);

    if (Key == 0x0000)              // Ctrl-Break时强行终止
    {
      return(0);
    }

    //****** Esc   or    Q -> quit ****************
    if(Key == 0x011b || Key == 0x1071 || Key == 0x1051)
    {
      clrscr();
      break;
    }
    //********** e   or   E -> load/eject ********
    else if( Key==0x1265 || Key==0x1245)
    {
      if(Load)
      {
        printf ("Please wait for LOAD disc...\n");
      }
      else
      {
        printf ("EJECT....\n");
      }
      atapiEject(Drive, Load);
      //Load=!Load;
      Load=(Load==true ? false : true);

      goto LoadToc;
    }
    //********** t   or   T -> load TOC *********
    else if(( Key==0x1474 || Key==0x1454) && Load==false)
    {

LoadToc:

      printf ("WAITING ....\n");

      CurrTrack=0;                  // init variable
      NumTracks=0;

      for(Tries=5; Tries>0; Tries--)
      {
         Temp=atapiTOC(Drive);
         if (Temp == 0 || Load == true)
         {
           break;
         }
         delay(2000);
      }

      if (Temp != 0)
      {
        printf ("NO DISC\n");
        Disc=false;
      }
      else
      {
        printf ("Disc is READY\n");
        printf ("Track %d of %d\n", (Temp==0 ? CurrTrack+1 : 0), NumTracks);
        Disc=true;
      }

    }
    //********** p   or   P -> play *************
    else if((Key==0x1970 || Key==0x1950) && Disc==true)
    {
      atapimsf *Start, *End;

      Start= Track+CurrTrack;
      End= Track+(CurrTrack + 1);

      printf ("PLAYING...\n");
      printf ("Track %d of %d\n", CurrTrack+1, NumTracks);

      atapiPlay(Drive, Start, End);
    }
    //********** n   or   N -> play next track **
    else if((Key==0x316e || Key==0x314e) && Disc==true)
    {
      atapimsf *Start, *End;

      if(CurrTrack < NumTracks - 1)
      {
        CurrTrack++;
        Start=Track+CurrTrack;
        End=Track+(CurrTrack+1);
      }

      printf ("PLAYING...\n");
      printf ("Track %d of %d\n", CurrTrack+1,NumTracks);

      atapiPlay(Drive, Start, End);
    }
    //********** v  or   V -> play previous trk ****
    else if((Key == 0x2f76 || Key == 0x2f56) && Disc==true)
    {
      atapimsf *Start, *End;

      if(CurrTrack > 0)
      {
        CurrTrack--;
        Start=Track+CurrTrack;
        End=Track+(CurrTrack+1);
      }

      printf ("PLAYING...\n");
      printf ("Track %d of %d\n", CurrTrack+1,NumTracks);

      atapiPlay(Drive, Start, End);
    }
    //*********** u   or   U -> pause/continue ****
    else if(( Key==0x1675 || Key==0x1655) && Disc==true)
    {
      if(Continue)
      {
        printf ("PLAYING...\n");
      }
      else
      {
        printf ("PAUSE...\n");
      }
      atapiPause(Drive, Continue);
      //Continue=!Continue;
      Continue=(Continue==true ? false : true);
    }
    //*********** s  or   S -> stop play/scan ***
    else if((Key==0x1f73 || Key==0x1f53) && Disc==true)
    {
      printf ("STOP...\n");
      atapiStop(Drive);
    }
  }
  return(0);
}
呵呵,这个CDPLAY播放器其实就是这么简单的..