<dfn id="w48us"></dfn><ul id="w48us"></ul>
  • <ul id="w48us"></ul>
  • <del id="w48us"></del>
    <ul id="w48us"></ul>
  • 在 DOS 下使用Windows *.WAV 文件

    時間:2024-09-27 11:34:49 計算機畢業論文 我要投稿
    • 相關推薦

    在 DOS 下使用Windows *.WAV 文件

    摘 要 該文介紹了Windows聲波文件(*.WAV)的格式,然后分析了在DOS下不使用聲音適配卡播放聲波文件的關鍵問題,并給出了程序清單。

    關鍵詞 DOS應用軟件開發 多媒體聲波文件在DOS應用軟件開發過程中,我們非常希望能在不附加任何硬件設備的條件下實現一些簡單的多媒體功能。

    過去許多文章中都討論過Windows圖像文件(*.BMP,*.PCX)的格式及其用于美化DOS程序界面的方法。在MS WIMDOWS3.1以后,Windows又提供了標準的聲波文件(*.WAV),因此我們可以利用已有的聲波文件鑲嵌在自己的軟件中,在DOS下實現語音或其它音響的播放,提高我們的軟件質量。

    一、聲波文件格式分析

    *.WAV文件作為多媒體中使用的聲波文件格式之一,它是以RIFF格式為標準的。RIFF是英文Resource Interchange File Format的縮寫,每個WAV文件的頭四個字節便是“RIFF”。
    常見的聲波文件主要有兩種,分別對應于單聲道(11.025KHz采樣率、8Bit的采樣值)和雙聲道(44.1KHz采樣率、16Bit的采樣值)。這里,采樣率是指:聲波信號[模→數]轉換過程中單位時間內采樣的次數。采樣值是指每一次采樣周期內聲波模擬信號的積分值,在編程播放過程中我們認為它是揚聲器在此周期單位時間段的音量。
    *.WAV文件由文件頭和數據體兩大部分組成。其中文件頭又分為RIFF/WAV文件標識段和聲波數據格式說明段兩部分。
    WAV文件各部分內容及格式見附表。
    對于單聲道聲波文件,采樣數據為八位的短整數(short int 00H-FFH);而對于雙聲道立體聲聲波文件,每次采樣數據為一個16位的整數(int),高八位和低八位分別代表左右兩個聲道。
    @@03A04400.GIF;*.WAV文件格式說明表@@

    二、WAV文件編程

    在沒有聲音適配卡的條件下,利用PC機內部揚聲器發聲需解決幾個關鍵問題。
    首先是如何產生按指定采樣率要求的標準時間間隔段,以此為基礎控制揚聲器發聲。
    由于此時間段要求精確且非常短暫,因此實現起來有一定的難度。解決該問題的思路是修改8253定時器芯片的計數器0(地址:040H)的初始值,改變系統時鐘中斷頻率使其和采樣率相一致,建立用戶的時鐘中斷例程,最終產生標準的時間間隔段。但是在我們修改原有系統時鐘中斷(Int 08H)以后,最終必須恢復原有18.2Hz的系統時鐘中斷。
    其次是如何快速地打開和關閉揚聲器。解決這個問題的方法是直接向8255芯片端口(地址:061H)寫操作。由于PC機機內揚聲器發聲只有開/閉兩種狀態,并不能控制音量大小。
    因此還須考慮如何通過開閉揚聲器來摸擬實現音量大小的控制。實現方法是:在每個時間單位內通過改變揚聲器打開延時的長短代表音量的大小。例如:對于8Bit單聲道聲波文件,采樣數據的最大值是0FFH,那么在每個標準時間單位內揚聲器打開時間應為Delay=(采樣值/256)*標準時間段長度。在此思想下可以將該方法簡化,設揚聲器延時只有0、1(時間單位)兩種情況,即在每個時間單位內,如果采樣值大于128則發聲,如果采樣值小于128就不發聲。顯然這樣做是以拋棄大量聲波信息為代價的,采用的信息量只占原有用信息的1/12
    8,所以這種方法產生的音質較差。

    三、程序實例

    下面是一個能播放11.025KHz/8Bit/單聲道聲波文件的演示程序。關于使用*.WAV文件的其它細節,可通過閱讀本程序得到。它采用了第二種延時方式,如果讀者有興趣提高音質可將其改成使用第一種方法,只需將newint08h中的聲音開/關判斷(與128比較)部分改成循環等待即可。
    循環次數通過i=int(vol[counter]/256)*MAXTIMES得到。
    式中MAXTIMES為延長一個標準時間單位的循環次數。
    程度運行環境:486兼容機,MS DOS6.0,TC2.0編譯系統。
    /*/*/*
    *.WAV文件播放程序 DEMO.C,石寧 1994.12
    */*/*/
    #include "dos.h"
    #include "stdio.h"
    #include"string.h"
    #define MAXSIZE 50000
    struct wave-file_head /*聲波*/
    { /*文件頭*/
    char riff_id[4];/*結構體*/
    long int size0;
    char wave-fmt[8];
    lont int sizel;
    int fmttag;
    int channel;
    long int samplespersec;
    long int bytepersec;
    int blockalign;
    int bitpersamples;
    } filehead;
    long int datasize, counter=0;
    unsigned char vol[MAXSIZE];
    unsigned clkdiv;
    int oldclk=0,running=1;
    void soundon();
    void soundoff();
    void interrupt(*oldint8h)();
    void interrupt newint8h()
    { /*用戶中斷例程*/
    if(running)
    {

    unsigned int i;
    disable();/*屏蔽中斷*/
    running=0;
    if(vol[counter]>=128)
    {
    i=inportb(0x61);/*開揚*/
    i=i|0x03;
    outportb(0x61,i);/*聲器*/
    }


    else
    {
    i=inportb(0x61);/*關揚*/
    i=i&0x00fc;
    outportb(0x61,i);/*聲器*/
    }
    counter+=1;
    enable();/*打開中斷*/
    if(counter>=datasize) counter=0;
    outportb(0x20,0x20);
    running=1;
    }
    }
    void soundon()
    {
    clkdiv=1193180/filehead.samplespersec;
    /*計算8253計數器0初始值*/
    oldint8h=getvect(0x08);/*保存舊的08H中斷向量*/
    setvect(0x08,newint8h);/*置新的08H中斷例程*/
    outportb(0x43,0xB6);/*初始化*/
    outportb(0x42,1);/*8253計數器3/
    outportb(0x42,0)

    ;/*初始值*/
    outportb(0x43,0x36); /*修改8253*/
    outport(0x40,clkdiv&0x00ff);/*計數器0*/
    outport(0x40,(clkdiv>>8)&0x00ff);/*初始值*/
    }
    void soundoff()
    {
    int i;
    setvect(0x08,oldint8h);/*恢復舊的08H中斷向量*/
    outportb(0x43,0x36);/*恢復正常*/
    outport(0x40,0)/*的時鐘中*/
    outport(0x40,0);/*斷頻率*/
    i=inportb(0x61);/*關揚*/
    i=i&0x00fc;
    outportb(0x61,i);/*聲器*/
    }
    void main(int argc, char *argv[])
    {
    long j;
    int key;
    char *s;
    FILE *fp;/
    if(argc==1)
    {
    printf("%s\n","And The WAV Filename In Command Line!");
    exit(0);
    }
    else
    {
    if ((fp=fopen(argv[l],"rb"))==NULL)
    {
    printf("Cannot open the Data file %s\n",argv[1];
    exit(0);
    }
    }
    if(fread(&filehead,sizeof(struct wave-file-head),1,fp)==NULL)
    {
    printf("File Read Error!\n");
    exit(0);
    }
    fseek(fp,4,SEEK-CUR);
    fread(&datasize,4,1,fp);
    for(j=0;jclose(fp);
    printf("%s\n","Now Sound On, Press ESC to Stop!");
    soundon();
    for(;;)
    {
    key=getch();
    if(key==27)
    {
    soundoff();
    printf("%s\n","Sound off!");
    break;
    }
    }
    }

    《人妻少妇乱子伦精品,四虎国产精品免费观看,你懂的国产精品.doc》
    将本文的Word文档下载到电脑,方便收藏和打印
    推荐度:
    点击下载文档

    【在 DOS 下使用Windows *.WAV 文件】相關文章:

    DOS下DSP播音的編程03-03

    Windows環境下對象的鏈接與嵌入03-16

    DOS界面下通用圖形編輯軟件的設計03-06

    用Windows終端仿真程序實現微機遠程文件傳送03-18

    Windows 95下智能數據采集系統03-19

    DOS真彩色模式下真彩色圖像顯示技術03-03

    Windows CE環境下無線網卡的自動安裝03-19

    windows nt環境下fddi網卡驅動程序設計03-18

    DOS用戶界面的設計03-20

    在线咨询
    主站蜘蛛池模板: 最新欧美性爱精品一区二区三区| 久久精品国产91久久麻豆自制| 国产日韩精品中文字无码| 亚洲国产精品久久久久| 全球AV集中精品导航福利| 国产专区日韩精品欧美色| 国产精品宾馆在线精品酒店| 国产精品99久久久久久宅男| 国产剧情国产精品一区| 国产999精品久久久久久| 亚洲精品无码久久久影院相关影片 | 精品国产日产一区二区三区| 中文字幕日韩精品有码视频| 国内精品久久久久影院网站| 亚洲国产综合精品中文第一区| 国产精品原创巨作av女教师| 亚洲精品国产精品乱码视色| 欧美日韩精品久久久免费观看| 成人精品一区二区三区| 国语自产拍精品香蕉在线播放| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 国产精品亚洲片在线| 亚洲愉拍99热成人精品热久久| 亚洲精品97久久中文字幕无码| 国产午夜精品一区二区三区不卡| 97久久超碰国产精品旧版| 久久久久人妻一区精品色| 亚洲精品国自产拍在线观看| 久久久久亚洲精品天堂久久久久久 | 国产成人精品久久免费动漫 | 亚洲精品视频在线| 国产精品手机在线| 91精品国产综合久久婷婷| 国产精品免费大片| 国产精品人人爽人人做我的可爱| 久久精品无码一区二区无码| 麻豆成人久久精品二区三区免费| 欧美亚洲色综久久精品国产 | 国产成人精品久久亚洲高清不卡 | 日韩精品www| Aⅴ精品无码无卡在线观看|

    在 DOS 下使用Windows *.WAV 文件

    摘 要 該文介紹了Windows聲波文件(*.WAV)的格式,然后分析了在DOS下不使用聲音適配卡播放聲波文件的關鍵問題,并給出了程序清單。

    關鍵詞 DOS應用軟件開發 多媒體聲波文件在DOS應用軟件開發過程中,我們非常希望能在不附加任何硬件設備的條件下實現一些簡單的多媒體功能。

    過去許多文章中都討論過Windows圖像文件(*.BMP,*.PCX)的格式及其用于美化DOS程序界面的方法。在MS WIMDOWS3.1以后,Windows又提供了標準的聲波文件(*.WAV),因此我們可以利用已有的聲波文件鑲嵌在自己的軟件中,在DOS下實現語音或其它音響的播放,提高我們的軟件質量。

    一、聲波文件格式分析

    *.WAV文件作為多媒體中使用的聲波文件格式之一,它是以RIFF格式為標準的。RIFF是英文Resource Interchange File Format的縮寫,每個WAV文件的頭四個字節便是“RIFF”。
    常見的聲波文件主要有兩種,分別對應于單聲道(11.025KHz采樣率、8Bit的采樣值)和雙聲道(44.1KHz采樣率、16Bit的采樣值)。這里,采樣率是指:聲波信號[模→數]轉換過程中單位時間內采樣的次數。采樣值是指每一次采樣周期內聲波模擬信號的積分值,在編程播放過程中我們認為它是揚聲器在此周期單位時間段的音量。
    *.WAV文件由文件頭和數據體兩大部分組成。其中文件頭又分為RIFF/WAV文件標識段和聲波數據格式說明段兩部分。
    WAV文件各部分內容及格式見附表。
    對于單聲道聲波文件,采樣數據為八位的短整數(short int 00H-FFH);而對于雙聲道立體聲聲波文件,每次采樣數據為一個16位的整數(int),高八位和低八位分別代表左右兩個聲道。
    @@03A04400.GIF;*.WAV文件格式說明表@@

    二、WAV文件編程

    在沒有聲音適配卡的條件下,利用PC機內部揚聲器發聲需解決幾個關鍵問題。
    首先是如何產生按指定采樣率要求的標準時間間隔段,以此為基礎控制揚聲器發聲。
    由于此時間段要求精確且非常短暫,因此實現起來有一定的難度。解決該問題的思路是修改8253定時器芯片的計數器0(地址:040H)的初始值,改變系統時鐘中斷頻率使其和采樣率相一致,建立用戶的時鐘中斷例程,最終產生標準的時間間隔段。但是在我們修改原有系統時鐘中斷(Int 08H)以后,最終必須恢復原有18.2Hz的系統時鐘中斷。
    其次是如何快速地打開和關閉揚聲器。解決這個問題的方法是直接向8255芯片端口(地址:061H)寫操作。由于PC機機內揚聲器發聲只有開/閉兩種狀態,并不能控制音量大小。
    因此還須考慮如何通過開閉揚聲器來摸擬實現音量大小的控制。實現方法是:在每個時間單位內通過改變揚聲器打開延時的長短代表音量的大小。例如:對于8Bit單聲道聲波文件,采樣數據的最大值是0FFH,那么在每個標準時間單位內揚聲器打開時間應為Delay=(采樣值/256)*標準時間段長度。在此思想下可以將該方法簡化,設揚聲器延時只有0、1(時間單位)兩種情況,即在每個時間單位內,如果采樣值大于128則發聲,如果采樣值小于128就不發聲。顯然這樣做是以拋棄大量聲波信息為代價的,采用的信息量只占原有用信息的1/12
    8,所以這種方法產生的音質較差。

    三、程序實例

    下面是一個能播放11.025KHz/8Bit/單聲道聲波文件的演示程序。關于使用*.WAV文件的其它細節,可通過閱讀本程序得到。它采用了第二種延時方式,如果讀者有興趣提高音質可將其改成使用第一種方法,只需將newint08h中的聲音開/關判斷(與128比較)部分改成循環等待即可。
    循環次數通過i=int(vol[counter]/256)*MAXTIMES得到。
    式中MAXTIMES為延長一個標準時間單位的循環次數。
    程度運行環境:486兼容機,MS DOS6.0,TC2.0編譯系統。
    /*/*/*
    *.WAV文件播放程序 DEMO.C,石寧 1994.12
    */*/*/
    #include "dos.h"
    #include "stdio.h"
    #include"string.h"
    #define MAXSIZE 50000
    struct wave-file_head /*聲波*/
    { /*文件頭*/
    char riff_id[4];/*結構體*/
    long int size0;
    char wave-fmt[8];
    lont int sizel;
    int fmttag;
    int channel;
    long int samplespersec;
    long int bytepersec;
    int blockalign;
    int bitpersamples;
    } filehead;
    long int datasize, counter=0;
    unsigned char vol[MAXSIZE];
    unsigned clkdiv;
    int oldclk=0,running=1;
    void soundon();
    void soundoff();
    void interrupt(*oldint8h)();
    void interrupt newint8h()
    { /*用戶中斷例程*/
    if(running)
    {

    unsigned int i;
    disable();/*屏蔽中斷*/
    running=0;
    if(vol[counter]>=128)
    {
    i=inportb(0x61);/*開揚*/
    i=i|0x03;
    outportb(0x61,i);/*聲器*/
    }


    else
    {
    i=inportb(0x61);/*關揚*/
    i=i&0x00fc;
    outportb(0x61,i);/*聲器*/
    }
    counter+=1;
    enable();/*打開中斷*/
    if(counter>=datasize) counter=0;
    outportb(0x20,0x20);
    running=1;
    }
    }
    void soundon()
    {
    clkdiv=1193180/filehead.samplespersec;
    /*計算8253計數器0初始值*/
    oldint8h=getvect(0x08);/*保存舊的08H中斷向量*/
    setvect(0x08,newint8h);/*置新的08H中斷例程*/
    outportb(0x43,0xB6);/*初始化*/
    outportb(0x42,1);/*8253計數器3/
    outportb(0x42,0)

    ;/*初始值*/
    outportb(0x43,0x36); /*修改8253*/
    outport(0x40,clkdiv&0x00ff);/*計數器0*/
    outport(0x40,(clkdiv>>8)&0x00ff);/*初始值*/
    }
    void soundoff()
    {
    int i;
    setvect(0x08,oldint8h);/*恢復舊的08H中斷向量*/
    outportb(0x43,0x36);/*恢復正常*/
    outport(0x40,0)/*的時鐘中*/
    outport(0x40,0);/*斷頻率*/
    i=inportb(0x61);/*關揚*/
    i=i&0x00fc;
    outportb(0x61,i);/*聲器*/
    }
    void main(int argc, char *argv[])
    {
    long j;
    int key;
    char *s;
    FILE *fp;/
    if(argc==1)
    {
    printf("%s\n","And The WAV Filename In Command Line!");
    exit(0);
    }
    else
    {
    if ((fp=fopen(argv[l],"rb"))==NULL)
    {
    printf("Cannot open the Data file %s\n",argv[1];
    exit(0);
    }
    }
    if(fread(&filehead,sizeof(struct wave-file-head),1,fp)==NULL)
    {
    printf("File Read Error!\n");
    exit(0);
    }
    fseek(fp,4,SEEK-CUR);
    fread(&datasize,4,1,fp);
    for(j=0;jclose(fp);
    printf("%s\n","Now Sound On, Press ESC to Stop!");
    soundon();
    for(;;)
    {
    key=getch();
    if(key==27)
    {
    soundoff();
    printf("%s\n","Sound off!");
    break;
    }
    }
    }