返回列表 发帖

[系统相关] 批处理一种新的响铃方式

之前在xp下测试成功的echo 响铃方式
在win10下出现了问题
通过声卡扬声器发出的声音更加悠长顿挫
完全不是之前哪种短促单一的高频音调
而且会把多个响铃符号理解为一个响铃符号处理

经过一段时间测试
发现不同的主机和系统环境
发出来的声调可能不尽相同

为了找回之前哪种传统的声音
我试了多种方法
目前测试到使用方法
可以恢复短促单一可多次使用的响铃声
其主要原理是利用choice的无效选项字符触发响铃
rem 响铃1次
echo 1y|choice /t 10 /d y>nul
rem 连续响铃5次
echo 12345y|choice /t 10 /d y>nulCOPY
看看大家还有什么新思路?
2

评分人数

天的白色影子

新发现了一个nircmd的方法
nircmdc beep [Frequency] [Duration]COPY
而且还可以用它播放系统声音方案的配置声音
nircmdc stdbeepCOPY
天的白色影子

TOP

回复 9# smss


    powershell的[console]用法倒是第一次见到;感觉这段脚本不像临时写的,有些细节在这里根本用不到,比如set L= !L!,而且在脚本中也不需要那么多@。

搜了下,能见到的最早应用在PowerTip: Use PowerShell to Send Beep to Console

这里可以找到.net API关于Beep方法文档

另外在stackoverflow看到了另外一种ps的转义字符用法
Write-Host -NoNewLine "`a"COPY
也才注意到使用echo ^G方法响铃,会在窗口标题栏显示响铃图标
天的白色影子

TOP

@echo off&setlocal enabledelayedexpansion
(set S=212 212 190 212 159 169 212 212 190 212 142 159 212 212 106 126 159 169 190 119 119 126 159 142 159)&(set L=9 3 12 12 12 24 9 3 12 12 12 24 9 3 12 12 12 12 12 9 3 12 12 12 24)
set "L= !L!"&for %%A in (%S%)do @for /f "tokens=1*" %%B in ("!L!")do @(set "L=%%C"&set/at=400000/%%A,d=%%B*20 2>nul&&powershell "[Console]::Beep(!t!,!d!)" 2>nul)
pauseCOPY
1

评分人数

    • qzwqzw: 记忆的碎片在时空交错技术 + 1

TOP

30年前我用QBASIC播放音乐
semiuel 发表于 2025-3-7 15:16



    又一个暴露年龄段的

还记得从电脑期刊上抄过C语言编写的《月夜奔马图》,运行效果刚出来的那一刻,感觉震撼的无与伦比,一下子感觉那台破386也有了浪漫的气息
天的白色影子

TOP

调用播放器播放响铃音频文件
Five66 发表于 2025-3-7 13:17



    那倒不至于,CMD的所在的conhost.exe可以调用Win32 API播放,一个很常见的WAV还用不到媒体播放器的GUI+库
天的白色影子

TOP

30年前我用QBASIC播放音乐

TOP

调用播放器播放响铃音频文件

TOP

本帖最后由 qzwqzw 于 2025-3-7 12:02 编辑

回复 2# 523066680


经网络搜索,beep函数在新版本windows下已不可用蜂鸣器,也是改用声卡+扬声器输出
而且似乎在Win32 API函数中已经修改了,要使用主板自带蜂鸣器还需要调用ring0层的IO函数
https://blog.csdn.net/weixin_44290011/article/details/112348304#

另外下面的链接里也提到了在win10下用windbg的本地内核调试方法
同时也是ring0层的思路,需要用到管理员权限
https://01.me/en/2016/12/beep-in-windows-10/

没有perl环境,我用C++环境下试验了下那个kimi给出的beep代码
确认在win10下C的beep也是用声卡扬声器发声的
频率和延时都是有效的

看来唯独是cmd下的这个响铃符号被转移到了媒体文件上
C:\Windows\media\Windows Foreground.wav
天的白色影子

TOP

唤起远古的记忆,折腾过一阵子音频,但是完全忘记了
use Time::HiRes qw/time/;
use Win32::Sound;
# Create the object
my $WAV = new Win32::Sound::WaveOut(44100, 8, 2);
Win32::Sound::Volume('50%', '50%');
my $data = "";
my $samples = 44100; # 采样率
my $freq = 800;      # 波的频率 -> 每秒震动的次数
my $M_2PI = 2.0 * 3.1415926;
for ( my $frame = 0.0; $frame < $samples; $frame += 1.0 )
{
    # (0.0 ~ 1.0) * 2PI * $freq 次周期震荡
    my $rad = ($frame / $samples) * $M_2PI * $freq;
    # 波的采样值,范围从 1 ~ 255
    my $v = sin($rad) * 127 + 128;
    # "pack" it twice for left and right
    $data .= pack("CC", $v, $v);
}
printf "%.2f\n", time();
$WAV->Load($data);       # get it
$WAV->Write();           # hear it
1 until $WAV->Status();  # wait for completion
printf "%.2f\n", time();
$WAV->Save("sinus.wav"); # write to disk
$WAV->Unload();          # drop itCOPY
1

评分人数

[url=][/url]

TOP

本帖最后由 523066680 于 2025-3-7 10:51 编辑

这种大概是函数生成波形,通过win32的音频接口发声。

perl有一个 Auido::Beep 可以简单地播放指定频率/波形的声音
#functional simple way
use Audio::Beep;
beep(880, 1000); # freq, durationCOPY
---
然后追溯一下 Audio::Beep 的模块代码,是调用 Win32::API
use strict;
use Carp;
use Win32::API;
sub new {
    my $class = shift;
    my $player = Win32::API->new('kernel32', 'Beep', 'NN', 'N')
        or croak "Cannot initialize " . __PACKAGE__ . " object";
    return bless {
        player  => $player
    }, $class;
}
sub play {
    my $self = shift;
    my ($freq, $duration) = @_;
    return $self->{player}->Call(sprintf("%.0f", $freq), $duration);
}COPY
---
问一下kimi,结果更直接
#include <windows.h>  // 包含Windows API的头文件
#include <stdio.h>
int main() {
    // 调用Beep函数,参数分别为频率(Hz)和持续时间(毫秒)
    Beep(800, 1000);  // 频率800Hz,持续时间1000ms(1秒)
    printf("Beep sound played.\n");
    return 0;
}COPY
[url=][/url]

TOP

返回列表