k2-fsa/sherpa-ncnn

采样点需要对齐还是 UTF8 编码的问题?

Closed this issue · 11 comments

endink commented

Windows 编译开启 utf8 :

set(CMAKE_C_FLAGS_RELEASE  "${CMAKE_C_FLAGS_RELEASE} /bigobj /utf-8 /MT")

0.2 秒双通道的音频重采样(使用 ffmpeg 的 swr_convert)为16000 单通道后,可能 samples 不再是正好 0.2 秒,这个会影响识别吗,现在调用 api 是可以成功但是得到的字符串都是这样:

轴轴轴
轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴
轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴轴

想确认一下 display 不支持 windows UTF8 ?源码里有注释说这个类只能 linux ?

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /bigobj /utf-8 /MT")

为什么加这个选项呢? c++ 里,默认是 utf-8 编码.

0.2 秒双通道的音频重采样

我们只要求单通道, 16kHz.

0.2 秒这个数,应该是你自己取的吧?我们对这个时间没限制。极端情况下,你一次只送一个 sample 也是可以的。


现在调用 api 是可以成功但是得到的字符串都是这样:

python识别会有问题吗? 我们是第一次碰见你这个问题。 如果识别结果,显示有乱码的话,请在命令行里输入

CHCP 65001

想确认一下 display 不支持 windows UTF8

  1. display 和 utf-8 没关系.
  2. display 用于操作 terminal, 这个只支持 linux 和 macos , 不支持 windows
  3. c++ 里,字符串都是 utf-8 编码的.
endink commented

/utf-8 只是限制 MSVC 的文件字符集和解释字符集都用 UTF8,同一个工程里其他代码(比如 TTS)UTF8 是没有问题的.

0.2 是自己取的,因为我看 c-api 例子里是 0.2,为了复现例子,所以我程序里也自己缓冲到 0.2 秒才提交。

因为刚写完的代码跑通后看着是乱码所以来询问一下,那等我保存重采样音频确认一下重采样没有问题再讨论,我是集成到 Unreal Engine 里,因为 UE 的麦克风默认被采样为双通道 48KHZ, 所以我自己重采样了一下,那个 ffmepg 例子是用 avcodec 读文件, 我需要实时重采样每一帧的 samples,所以没用那个代码。

endink commented

BTW, 我是 C++ 代码,没有 python

BTW, 我是 C++ 代码,没有 python

那你先用我们的 c++ 代码编译后生成的 exe, 在 windows 上跑一下,看看有没有问题?

endink commented

好,我自己先排除一下自己的问题,因为代码很简单,所以先来问问~~

endink commented

嗨~我已经排除了所有问题,今天写了代码包把重采样后的语音保存成 wav 听了是没有问题的,可能是使用姿势不正确?

调用的代码基本就是这样,没有多少行

 if(_initialized)
    {
        AcceptWaveform(_stream, static_cast<float>(_sample_rate), samples, samples_len);
        while (IsReady(_recognizer, _stream)) {
            Decode(_recognizer, _stream);
        }
        SherpaNcnnResult* r = GetResult(_recognizer, _stream);
        if (strlen(r->text)) {
            SherpaNcnnPrint(_display, _segment_id, r->text); //这里打印出来和问题描述一致
            auto* wrap = new RecognizerOutput(r);
            *output = wrap;
            return true;
        }
        if(r)
        {
            DestroyResult(r);
        }
        return false;
    }
    return false;

为了排除我自己输出有问题我又用了你们代码里的 Print 函数,也是显示不正确,我用的源码编译,自己已经找不到问题了

endink commented

我觉得就是编码的问题,字数感觉是对的,就是全是 “轴”

字数感觉是对的,就是全是 “轴”

那你改下代码,把 识别结果的 数字id 打印出来?

endink commented

你的意思是打印 char 吗

不是的,是打印 int32_t

auto res = p->recognizer->GetResult(s->stream.get());

std::vector<int32_t> tokens;

std::vector<int32_t> tokens; 输出来,然后自己根据 tokens.txt, 手动用笔把数字 id 转成 对应的汉字,看看结果对不对.

endink commented

明白,那我先close issue 了,如果需要调试源码这个 issue 没有意义,自己调试就可以了。