Bro*_*ler 7 audio x86 operating-system osdev hobby-os
我正在开发一个32位,保护模式的业余爱好操作系统.目前,我希望增加简单的声音支持.为此,我希望使用声音冲击波16并使用直接模式写入DAC(我想不惜一切代价避免使用DMA).但是,当我向DAC输出一个简单的方波(使用命令0x10)时,我的计算机扬声器没有声音输出.我正在寻找这个问题的解决方案.
我试图使用以下算法来产生声音:
1. Reset DSP
2. Enable the speakers
3. Write 0x10 to 0x22C (direct mode DAC write command)
4. Write 0x00 to 0x22C (To set the speaker to low)
5. Write 0x10 to 0x22C
6. Write 0xFF to 0x22C (To set the speaker to high)
7. Jump back to step 4 and repeat.
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
#define DSP_RESET 0x226
#define DSP_READ 0x22A
#define DSP_WRITE 0x22C
#define DSP_READ_STATUS 0x22E
#define DSP_INT_ACK 0x22F
#define REG_ADDR 0x224
#define REG_DATA 0x225
#define DIRECT_DAC 0x10
#define ENABLE_SPEAKER 0xD1
void dsp_reset(){
uint32_t buf[4];
*buf = 128;
rtc_write(0, buf, 4);
outb(1, DSP_RESET);
rtc_read(0, 0, NULL, 0);
outb(0, DSP_RESET);
if(inb(DSP_READ) != 0xAA){
print_term((uint8_t *)"Could not init sb16\n", 20);
}
return;
}
void play_simple_sound(){
dsp_reset();
while(inb(DSP_WRITE));
print_term((uint8_t *)"Enabling speaker\n", 18);
outb(0xD1, DSP_WRITE);
while(inb(DSP_WRITE));
print_term((uint8_t *)"Playing sound\n", 14);
outb(0xF0, DSP_WRITE);
while(1){
while(inb(DSP_WRITE));
outb(0x10, DSP_WRITE);
outb(0x00, DSP_WRITE);
rtc_read(0, 0, NULL, 0);
while(inb(DSP_WRITE));
outb(0x10, DSP_WRITE);
outb(0xFF, DSP_WRITE);
rtc_read(0, 0, NULL, 0);
}
return;
}
Run Code Online (Sandbox Code Playgroud)
rtc_write将rtc频率设置为几百赫兹,而rct_read使程序在rtc上等待(这两个程序都正常工作).dsp_reset也可以正常工作,因为当从DSP读取输出时,返回0xAA(表明存在声音器16).
目前我正在使用Windows 10 64位来运行模拟操作系统的Qemu.我正在使用"-soundhw all"选项集运行qemu.由于我编写的代码或者Qemu有问题,我不确定我是否听不到声音.我的问题是,问题可能是什么,以及我可以采取哪些措施来解决这个问题?此外,与sb 16相关的文档和教程将不胜感激.
在 Qemu 仿真下,无法使用 soundblaster 16 直接进行 DAC。也不允许直接进行 ADC。检查这里找到的源代码,查看从第 390 行开始支持的命令:
https://github.com/qemu/qemu/blob/master/hw/audio/sb16.c
看来为了使用声卡输出声音,必须使用DMA。更进一步,Qemu 上的 SB16 仿真似乎相当缺乏。真正的 SB16 支持的命令列表可以在这里找到: http: //the.earth.li/~tfm/oldpage/sb_dsp.html。将这些命令与 Qemu 支持的命令进行比较,只模拟了一小部分。
编辑2:看看其他模拟器,Bochs不支持sb16(参见第858行:http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/sound/sb16.cc),但DOSBox有非常令人印象深刻的SB16支持,并且确实支持直接DAC,但仍然不支持麦克风直接ADC(参见第1611行:http://dosbox-x.com/doxygen/html/sblaster_8cpp_source.html)