中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?
作者:
标题: 哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙? 上一主题 | 下一主题
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『楼 主』:  哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?

哪位懂WIN-TC(或TC2.0)加入音频播放的仁兄能不能帮一下忙?
这几天用WINTC做了个小程序,急需加入WAV音频,但WINTC TC没有音频函数,下了ALLEGRO,但好象要在DJGPP下,我没用过,现在又很急, 弄了个NEO SDK , 仅仅单独播放音频可以,但加入到带图形的C程序中就冲突,编译通不过! 禁用了相关的宏定义也没用..
不知哪位仁兄有在WINTC TC2.0下能兼容的音频函数? 帮我解决这个难题? (通宵了几夜了,都没弄成,非常失望!..)
传到论坛也行, 也可EMAIL我,   tdaim@sina.com    感谢了...


[此贴子已经被作者于2005-1-19 16:46:12编辑过]




2005-1-19 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
Loff
中级用户




积分 286
发帖 59
注册 2003-4-8
状态 离线
『第 2 楼』:  

几点问题要说明:
1. Allegro也可以在Windows平台下的、GCC、VC等编译器下使用。
2. 无论是DJGPP还是TC,都是DOS下的编译器,一般都是产生DOS程序的(用来写Windows程序的步骤比较复杂),而你要在DOS下发声,需要DOS下的声卡驱动程序,否则即使给你音频API函数,还是不行。
3. 在DOS下编写音频程序,如果没有相应声卡厂商提供的SDK的话,就只能自己写端口来实现,比如以前Adlib兼容芯片的控制就是通过写0x388、0x389端口。同样,前提是必须有声卡驱动。所以,劝楼主打消这个念头,或者在虚拟机下编写,不过速度可能很慢。

2005-2-1 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 3 楼』:  

我是假定装了SB16DOS驱动的情况下的调用一个音频函数就可解决的那种...苦于TC2没有音频函数!!

2005-4-29 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
郭恒
中级用户




积分 225
发帖 39
注册 2004-10-6
状态 离线
『第 4 楼』:  

//   我以前有一个C++版本的函数,且数据是放在“扩展内存”里的,是可行的。//现在我改成C语言的版本,并且波形数据从“文件”里读,未经测试,故仅作参考!#include <Dos.h>
#include <Stdio.h>
#include <Stdlib.h>
#include <io.h>
#ifndef  TRUE
#define  TRUE 1
#endif
#ifndef  FALSE
#define  FALSE 0
#endif#ifndef         NULL
#define         NULL 0
#endif
typedef         int   BOOL;
typedef  unsigned int WORD;
typedef     unsigned long DWORD;
typedef     unsigned char   BYTE;typedef struct waveformat_tag{
    WORD  wFormatTag;
    WORD  nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD  nBlockAlign;
} WAVEFORMAT;

typedef struct pcmwaveformat_tag{
    WAVEFORMAT wf;
    WORD       wBitsPerSample;
} PCMWAVEFORMAT;typedef struct riffformat_tag
{
BYTE  bysFormat[4];
DWORD dwSize;
}RIFFFORMAT;//从声卡的DSP中读数据
BYTE ReadSound16_DSP(int nBase)
{
unsigned int i;
    for (i = 0; i < 3000u; i++)
    {
        if (0 != (inportb(nBase + 0xE) & (1<<7)))
        {
            return (inportb(nBase + 0xA));
        }
    }
    return(0);
}//往声卡的DSP写数据
BOOL WriteSound16_DSP(int nBase, unsigned char nCh)
{
    while (0 != (inportb(nBase + 0xC) & (1<<7)))
    {
    }    outportb(nBase + 0xC , nCh);
    return(FALSE);
}//往声卡的DSP写基本参数
void WriteSound16_Const(int nBase, int nChannels, WORD wSampling)
{
    WORD wConst = 65536L - (256000000L/(1L * ((WORD)nChannels) * wSampling));
    WriteSound16_DSP(nBase, 0x40);
    WriteSound16_DSP(nBase, wConst >> 8);
}//设置声卡的采样率
void WriteSound16_Sampling(int nBase, WORD wSampling, BOOL bOutput)
{
    //HI = 0x56, LO =0x22 while wSample = 22050
    WriteSound16_DSP(nBase, (bOutput)?0x41:0x42);
    WriteSound16_DSP(nBase, wSampling >> 8);
    WriteSound16_DSP(nBase, wSampling & 0xFF);
    return;
}//声卡复位
BOOL ResetSound16_DSP(int nBase)
{
int i;    outportb(nBase + 0x6, 1);
    delay(3);
    outportb(nBase + 0x6, 0);    for (i = 0; i < 300; i++)
    {
        if (ReadSound16_DSP(nBase) != (BYTE)0xAA)
        {
            delay(1);
            continue;
        }
        return(TRUE);
    }
    return(FALSE);
}//声卡播放文件 --- 8位立即数方式播入。
//入口参数:int  nBase ------ 声卡基地址
//********  WORD wDelay ----- 播入每一数据时的软件延迟时间
//********  char* pStrFile -- WAVE文件名
BOOL PlayWaveFile(int nBase, WORD wDelay, char* pStrFile)
{
    int nData;
    WORD  p;
    long i, lgLeft;
    FILE* pFile = NULL;
    BYTE* pBuffer;
    BYTE* pLinBuffer;
    BYTE  byData;
    RIFFFORMAT mRiffFormat;
    PCMWAVEFORMAT pcmWaveFormat;
    //打开文件   
    if (NULL == (pFile = fopen(pStrFile, "rb"))
    {
        return(FALSE);
    }    //获得文件长度
    long lgSize = filelength(fileno(pFile));    //验证文件长度的合法性
    if (lgSize < 3L * sizeof(RIFFFORMAT))
    {
        fclose(pFile);
        return(FALSE);
    }
    //读 "RIFF" 控制块
    if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat,
  1, sizeof(RIFFFORMAT), pFile))
    {
        fclose(pFile);
        return(FALSE);
    }    //验证“RIFF”控制块
    if (mRiffFormat.bysFormat[0] != 'R' ||
        mRiffFormat.bysFormat[1] != 'I' ||
        mRiffFormat.bysFormat[2] != 'F' ||
        mRiffFormat.bysFormat[3] != 'F')
    {
        fclose(pFile);
        return(FALSE);
    }    //验证文件长度的合法性
    if (mRiffFormat.dwSize + 4L + 4L != lgSize)
    {
        fclose(pFile);
        return(FALSE);
    }    //读“WAVE”控制块
    if (4 != fread((void *)&mRiffFormat, 1, 4, pFile))
    {
        fclose(pFile);
        return(FALSE);
    }    //验证“WAVE”控制块
    if (mRiffFormat.bysFormat[0] != 'W' ||
        mRiffFormat.bysFormat[1] != 'A' ||
        mRiffFormat.bysFormat[2] != 'V' ||
        mRiffFormat.bysFormat[3] != 'E')
    {
        fclose(pFile);
        return(FALSE);
    }    //读“FACT”或“FMT ”控制块
    if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat,
  1, sizeof(RIFFFORMAT), pFile))
    {
        fclose(pFile);
        return(FALSE);
    }    //验证“FACT”控制块
    if ((mRiffFormat.bysFormat[0] == 'f' || mRiffFormat.bysFormat[0] == 'F') &&
        (mRiffFormat.bysFormat[1] == 'a' || mRiffFormat.bysFormat[1] == 'A') &&
        (mRiffFormat.bysFormat[2] == 'c' || mRiffFormat.bysFormat[2] == 'C') &&
        (mRiffFormat.bysFormat[3] == 't' || mRiffFormat.bysFormat[3] == 'T'))
    {
        lgLeft = mRiffFormat.dwSize;
        for (i = 0; i < lgLeft; i++)
        {
            if (1 != fread((void *)&mRiffFormat, 1, 1, pFile))
            {
                fclose(pFile);
                return(FALSE);
            }
        }        //读“FMT ”控制块
        if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat,
   1, sizeof(RIFFFORMAT), pFile))
        {
            fclose(pFile);
            return(FALSE);
        }
    }    //验证“FMT ”控制块
    if (mRiffFormat.bysFormat[0] != 'f' && mRiffFormat.bysFormat[0] != 'F' ||
        mRiffFormat.bysFormat[1] != 'm' && mRiffFormat.bysFormat[1] != 'M' ||
        mRiffFormat.bysFormat[2] != 't' && mRiffFormat.bysFormat[2] != 'T' ||
        mRiffFormat.bysFormat[3] != ' ' && mRiffFormat.bysFormat[3] != ' ')
    {
        fclose(pFile);
        return(FALSE);
    }
    //读波形数据格式控制块
    if (sizeof(PCMWAVEFORMAT) != fread((void *)&pcmWaveFormat,
  1, sizeof(PCMWAVEFORMAT), pFile))
    {
        fclose(pFile);
        return(FALSE);
    }    //读其它不关心用途的控制块
    lgLeft = mRiffFormat.dwSize -  sizeof(PCMWAVEFORMAT);
    for (i = 0; i < lgLeft; i++)
    {
        if (1 != fread((void *)&byData, 1, 1, pFile))
        {
            fclose(pFile);
            return(FALSE);
        }
    }    //验证波形数据格式控制块的合法性
    if (pcmWaveFormat.wBitsPerSample > 6 * 8)
    {
        //fclose(pFile);
        //return(FALSE);
    }    //读“data”控制块
    if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat,
  1, sizeof(RIFFFORMAT), pFile))
    {
        fclose(pFile);
        return(FALSE);
    }    // !!!!!可能是拷贝时,重复了的代码,忘了起什么作用!
    if ((mRiffFormat.bysFormat[0] == 'f' || mRiffFormat.bysFormat[0] == 'F') &&
        (mRiffFormat.bysFormat[1] == 'a' || mRiffFormat.bysFormat[1] == 'A') &&
        (mRiffFormat.bysFormat[2] == 'c' || mRiffFormat.bysFormat[2] == 'C') &&
        (mRiffFormat.bysFormat[3] == 't' || mRiffFormat.bysFormat[3] == 'T'))
    {
        //读其它不关心用途的控制块
        lgLeft = mRiffFormat.dwSize;
        for (long i = 0; i < lgLeft; i++)
        {
            if (1 != fread((void *)&mRiffFormat, 1, 1, pFile))
            {
                fclose(pFile);
                return(FALSE);
            }
        }        //读“data”控制块
        if (sizeof(RIFFFORMAT) != fread((void *)&mRiffFormat,
   1, sizeof(RIFFFORMAT), pFile))
        {
            fclose(pFile);
            return(FALSE);
        }
    }    //验证“data”控制块
    if (mRiffFormat.bysFormat[0] != 'd' && mRiffFormat.bysFormat[0] != 'D'||
        mRiffFormat.bysFormat[1] != 'a' && mRiffFormat.bysFormat[1] != 'A' ||
        mRiffFormat.bysFormat[2] != 't' && mRiffFormat.bysFormat[2] != 'T' ||
        mRiffFormat.bysFormat[3] != 'a' && mRiffFormat.bysFormat[3] != 'A')
    {
        fclose(pFile);
        return(FALSE);
    }    //验证波形数据的长度
    if (mRiffFormat.dwSize > lgSize - ftell(pFile))
    {
        fclose(pFile);
        return(FALSE);
    }
    //验证文件的合法性
    if (pcmWaveFormat.wf.wFormatTag != 1 ||
       ((pcmWaveFormat.wf.nChannels * pcmWaveFormat.wBitsPerSample/8 !=
         pcmWaveFormat.wf.nBlockAlign) ||
        ((mRiffFormat.dwSize % pcmWaveFormat.wf.nBlockAlign) != 0 )))
    {
        fclose(pFile);
        return(FALSE);
    }
    //初始化SB16声卡
    ResetSound16_DSP(nBase);    //初始化采样率
    WriteSound16_Sampling(nBase, (WORD)pcmWaveFormat.wf.nSamplesPerSec, TRUE);
    WriteSound16_Const(nBase, pcmWaveFormat.wf.nChannels,
  (WORD)pcmWaveFormat.wf.nSamplesPerSec);
    //分配1024字节的数据缓冲区
    pBuffer = new BYTE[1024];
    pLinBuffer = pBuffer;    for (i = 0; i < mRiffFormat.dwSize; i++)
    {
        //将波形数据读入到pBuffer缓冲区中
        if ((i % 1024) == 0)
        {
         pLinBuffer = pBuffer;
         fread(pBuffer, 1, 1024, pFile);
        }        //根据波形数据的数据位进行
        switch (pcmWaveFormat.wBitsPerSample)
        {
            case 4: //4位波形数据
            {
                byData = *(pLinBuffer++);
                WriteSound16_DSP(nBase, 0x10);
                WriteSound16_DSP(nBase, byData);
                break;
            }
            case 8: //4位波形数据
            {
                byData = *(pLinBuffer++);
                WriteSound16_DSP(nBase,0x10);
                WriteSound16_DSP(nBase, byData);                if (pcmWaveFormat.wf.nChannels  >= 2) //双通道
                {
                    i++;
                    byData = *(pLinBuffer++);
                    WriteSound16_DSP(nBase,0x10);
                    WriteSound16_DSP(nBase, byData);
                }
                break;
            }
            case 16: //16位波形数据
            {
  *(((BYTE *)&nData) + 0)= *(pLinBuffer++);
  *(((BYTE *)&nData) + 1)= *(pLinBuffer++);  //将16位数据转成8位数据
                byData = (BYTE)(0.5f + 1.0f * (255 - 0) /
   (32757.0f - (-32768.0f)) * (1.0f * nData + (-32768.0f)));
                WriteSound16_DSP(nBase,0x10);
                WriteSound16_DSP(nBase,byData);                i++;
                if (pcmWaveFormat.wf.nChannels  >= 2) ////双通道
                {
   *(((BYTE *)&nData) + 0)= *(pLinBuffer++);
   *(((BYTE *)&nData) + 1)= *(pLinBuffer++);       //将16位数据转成8位数据
                     byData = (BYTE)(0.5f + 1.0f * (255 - 0) /
    (32757.0f - (-32768.0f)) * (1.0f * nData + (-32768.0f)));
                     WriteSound16_DSP(nBase,0x10);
                     WriteSound16_DSP(nBase,byData);
                     i += 2;
                }
                break;
            }
        }//Switch (pcmWaveFormat.wBitsSample)        //因为是立即数播放,故需要用软件来作延迟
for (p = 0; p < wDelay; p++)
     {
}    }    //释入缓冲区
    delete pBuffer;    //关闭文件
    fclose(pFile);
    return(TRUE);
}


2005-5-10 00:00
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 5 楼』:  

问一下,你这个是怎么用的? 是作为头文件,还是作为函数?具体说一下,怎么调用? 好么?

2005-5-12 00:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: