最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從零開(kāi)始教你利用C#輕松實(shí)現(xiàn)語(yǔ)音識(shí)別功能

 更新時(shí)間:2025年12月07日 10:01:31   作者:luojin765  
本文以語(yǔ)音識(shí)別為例,看如何高效的將語(yǔ)音識(shí)別功能集成至C#系統(tǒng)中,后續(xù)大家可以繼續(xù)完善擴(kuò)展,去處理如語(yǔ)音指令、語(yǔ)音交互、字幕生成、會(huì)議紀(jì)要分析、語(yǔ)音翻譯等相關(guān)任務(wù)

人工智能歷經(jīng)多年演進(jìn),昔日高門(mén)檻的圖像與語(yǔ)音識(shí)別任務(wù),如今已有成熟的開(kāi)源框架可供免費(fèi)使用,只要花點(diǎn)時(shí)間,就可以零成本部署。本文以語(yǔ)音識(shí)別為例,看如何高效的將語(yǔ)音識(shí)別功能集成至C#系統(tǒng)中,后續(xù)大家可以繼續(xù)完善擴(kuò)展,去處理如語(yǔ)音指令、語(yǔ)音交互、字幕生成、會(huì)議紀(jì)要分析、語(yǔ)音翻譯等相關(guān)任務(wù)。

本文項(xiàng)目在筆記本電腦上用cpu就可以自己動(dòng)手輕松實(shí)現(xiàn)

一、環(huán)境配置基礎(chǔ)

語(yǔ)音識(shí)別的方案有很多,windows系統(tǒng)本身也自帶有語(yǔ)音識(shí)別的方案(System.Speech.Recognition),但是效果查強(qiáng)人意。既要簡(jiǎn)單好用,又要功能強(qiáng)大效果好,我們選擇基于Whisper(MIT,https://github.com/openai/whisper)的Whisper.Net(MIT,https://github.com/sandrohanea/whisper.net)來(lái)實(shí)現(xiàn)。

Whisper 是2022年OpenAI發(fā)布的一個(gè)通用語(yǔ)音識(shí)別模型。它基于大量多樣化的音頻數(shù)據(jù)進(jìn)行訓(xùn)練,同時(shí)也是一個(gè)多任務(wù)模型,能夠執(zhí)行多語(yǔ)言語(yǔ)音識(shí)別、語(yǔ)音翻譯和語(yǔ)言識(shí)別任務(wù)。項(xiàng)目創(chuàng)建完成后直接在nuget拉取Whisper.net(1.9.0)和Whisper.net.Runtime(1.9.0)即可。

另外為了實(shí)現(xiàn)語(yǔ)音交互,還要在nuget拉取NAudio(2.2.1)(MIT,https://github.com/naudio/NAudio),以實(shí)現(xiàn)通過(guò)麥克風(fēng)設(shè)備對(duì)聲音的捕獲。

二、核心代碼實(shí)現(xiàn)

2.1 四行核心代碼實(shí)現(xiàn)語(yǔ)音轉(zhuǎn)文本

上面的控制臺(tái)demo的main函數(shù)代碼如下:

 private static readonly string OutFile = "d:\\record.wav";  //臨時(shí)輸出文件
 
 // 讀取json配置文件,nuget拉取LumConfig,往期文章有介紹
 private static LumConfigManager con = new LumConfigManager("model.conf");

private static void Main()
{
    // 1. 加載模型
    // 輸入模型地址,model文件夾下面提供了一個(gè)tiny版模型可以直接用
    var wm = new WhisperManager((string)con.Get("modelPath")); 

    while (true)
    {
        bool started = false;
        Console.WriteLine("按 Space 開(kāi)始/停止錄音");

        while (true)
        {
            var key = Console.ReadKey(true).Key;
            if (key == ConsoleKey.Spacebar)
            {
                if (started)
                {
                    // 2. 開(kāi)始錄音
                    StopRec();
                    break;
                }
                else
                {
                    // 3. 結(jié)束錄音
                    StartRec();
                }
                started=!started;
            }
        }


        // 4. 轉(zhuǎn)文本 
        var res = wm.RunAsync(OutFile).GetAwaiter().GetResult();

        Console.WriteLine(res);             
    }
}

代碼通過(guò)循環(huán)控制來(lái)實(shí)現(xiàn)反復(fù)讀取語(yǔ)音再轉(zhuǎn)換為文本的動(dòng)作。其實(shí)核心代碼只有四行,分別是加載模型、開(kāi)始錄音、停止錄音、語(yǔ)音轉(zhuǎn)文本。后面我們將對(duì)其一一拆解。

2.2 麥克風(fēng)錄制聲音

麥克風(fēng)的錄制很簡(jiǎn)單,我們只需要完成2個(gè)動(dòng)作,一個(gè)是開(kāi)始錄制聲音,另一個(gè)是停止錄制聲音。WaveFileWriter方法兩個(gè)重載,可以選擇把聲音錄制到文件,也可以錄制到流(stream)中。以錄制到文件為例具體代碼如下:

private static void StartRec()
{            
    waveIn = new WaveInEvent
    {
        DeviceNumber = 0,                      // 默認(rèn)麥克風(fēng)
        WaveFormat = new WaveFormat(16000, 1), // 44.1kHz 單聲道
        BufferMilliseconds = 100
    };

    writer = new WaveFileWriter(OutFile, waveIn.WaveFormat);

    // 數(shù)據(jù)到達(dá)事件
    waveIn.DataAvailable += (s, e) =>
    {
        writer.Write(e.Buffer, 0, e.BytesRecorded);
    };

    // 錄音停止事件(負(fù)責(zé)釋放 writer)
    waveIn.RecordingStopped += (s, e) =>
    {
        writer?.Dispose();
        writer = null;
        waveIn?.Dispose();
        waveIn = null;
        stop.Set();
    };

    waveIn.StartRecording();
    Console.WriteLine(">>> 正在錄音……");
}

private static void StopRec()
{
    Console.WriteLine("<<< 停止錄音");
    waveIn?.StopRecording();   // 觸發(fā) RecordingStopped 事件

    // 停止錄制時(shí),流數(shù)據(jù)的處理不一定已經(jīng)完成
    // 我們額外使用一個(gè)信號(hào)量來(lái)實(shí)現(xiàn)簡(jiǎn)單的同步
    stop.WaitOne();  
}

2.3 語(yǔ)音轉(zhuǎn)文字的實(shí)現(xiàn)

盡管Whisper.Net已經(jīng)封裝好了所有相關(guān)功能,但是我們最好額外寫(xiě)一個(gè)WhisperManager類來(lái)高效的反復(fù)使用他。具體代碼如下:

internal class WhisperManager:IDisposable
{
    WhisperFactory whisperFactory;
    WhisperProcessor processor;


    public WhisperManager(string path)
    {
        whisperFactory = WhisperFactory.FromPath(path);
        processor = whisperFactory.CreateBuilder()
            .WithLanguage("zh")
            .WithPrompt("以下是,簡(jiǎn)體中文普通話的句子。")  // 否則大概率會(huì)輸出繁體中文
            .WithThreads(16)
            .Build();            
    }
    
    public async Task<string> RunAsync(string path)
    {
        try
        {
            var sb = new StringBuilder();
            using var fileStream = File.OpenRead(path);
            //  異步獲取識(shí)別后的分段結(jié)果
            await foreach (var seg in processor.ProcessAsync(fileStream))
            {
                var str = $"{seg.Start}->{seg.End}: {seg.Text}\r\n";
                sb.AppendLine(str);
                var per = (fileStream.Position / fileStream.Length*100).ToString("N2");
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }

    public void Dispose()
    {
        processor.Dispose();
        whisperFactory.Dispose();
    }
}

Whisper重要基礎(chǔ)參數(shù)配置:

  • WithLanguage,指定輸入語(yǔ)音的語(yǔ)言,如zh、en、ja、auto(自動(dòng));
  • WithPrompt,輸出提示詞,這里與大語(yǔ)言模型不同,只能說(shuō)引導(dǎo)模型生成,比如“以下是一個(gè)訪談。”。此處需要與指定語(yǔ)言一致,否則可能會(huì)強(qiáng)行切換,50~200 個(gè)字符足夠,最好出現(xiàn)"標(biāo)點(diǎn)符號(hào)"(不然可能會(huì)無(wú)標(biāo)點(diǎn))、"口語(yǔ)詞、專有名詞"(適配語(yǔ)境)。

另外還有很多與線程、輸出相關(guān)的控制,大伙可根據(jù)需要自行研究了解。

2.4 模型、輸入與輸出

c#使用的Whisper模型是.bin的二進(jìn)制格式的,現(xiàn)在可以在https://huggingface.co/ggerganov/whisper.cpp/tree/main下載。本項(xiàng)目里用到的是好久以前下載的ggml-model-whisper-tiny.bin,74mb,速度很快但效果中等。

本項(xiàng)目對(duì)Whisper的輸入用的是wav格式的文件,且采樣率必須為16kHz,否則會(huì)報(bào)錯(cuò)。如果導(dǎo)入音頻時(shí)采樣頻率不對(duì),可以用NAudio通過(guò)下代碼進(jìn)行轉(zhuǎn)換:

public void Execute()
{
    //using (Mp3FileReader reader = new Mp3FileReader("D:\\Documents\\Temp\\WhisperDesktop\\上午對(duì)接結(jié)構(gòu)錄音.mp3"))
    using (AudioFileReader reader = new AudioFileReader("D:\\Documents\\Temp\\WhisperDesktop\\錄音.m4a"))
    {
      // 16kHz, 16bit,單聲道
      var newFormat = new WaveFormat(16000, 16, 1); 
      using (var conversionStream = new WaveFormatConversionStream(newFormat, reader))
      {
          WaveFileWriter.CreateWaveFile("D:\\Documents\\Temp\\WhisperDesktop\\錄音.wav", conversionStream);
      }             
    }
}

Whisper輸出是分多個(gè)段(IAsyncEnumerable)輸出的,包含如起始時(shí)間,文本,語(yǔ)言等多個(gè)信息,我們可以選擇性的進(jìn)行導(dǎo)出查看。

public class SegmentData
{
    public string Text { get; } 文本

    public TimeSpan Start { get; }

    public TimeSpan End { get; }

    public float MinProbability { get; }

    public float MaxProbability { get; }

    public float Probability { get; }

    public string Language { get; }

    public WhisperToken[] Tokens { get; }

    public float NoSpeechProbability { get; }
}

打印的結(jié)果示意:

00:00:00->00:00:15: 一二三四五,上山打老虎,老虎沒(méi)打到,打到了小松鼠。

三、最后

  • 在使用tiny模型下,整體速度和質(zhì)量還是基本可以的,如果追求更好的效果則考慮使用更大模型,但與之對(duì)內(nèi)存的需求及運(yùn)算時(shí)間會(huì)相應(yīng)大幅增加。
  • 在轉(zhuǎn)換時(shí),語(yǔ)音越長(zhǎng),轉(zhuǎn)換速度越慢,因此建議在轉(zhuǎn)換前,主動(dòng)對(duì)長(zhǎng)語(yǔ)音進(jìn)行分段。盡管這樣可能導(dǎo)致上下文丟失造成一定程度的不精確,但卻能顯著提高轉(zhuǎn)換速度。
  • 語(yǔ)音識(shí)別是支持多語(yǔ)言混合的。但翻譯的功能,試了下,失靈時(shí)不靈,可能和模型本身及大小有關(guān)。

到此這篇關(guān)于從零開(kāi)始教你利用C#輕松實(shí)現(xiàn)語(yǔ)音識(shí)別功能的文章就介紹到這了,更多相關(guān)C#語(yǔ)音識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C# 列表List的常用屬性和方法介紹

    C# 列表List的常用屬性和方法介紹

    這篇文章主要介紹了C# 列表List的常用屬性和方法介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • C#微信開(kāi)發(fā)第一章

    C#微信開(kāi)發(fā)第一章

    這篇文章主要為大家詳細(xì)介紹了C#微信開(kāi)發(fā)第一章,很有參考價(jià)值和實(shí)用性,感興趣的小伙伴們可以參考一下
    2016-07-07
  • C#中使用Override和New關(guān)鍵字進(jìn)行版本控制

    C#中使用Override和New關(guān)鍵字進(jìn)行版本控制

    在?C#?中,override?和?new?關(guān)鍵字用于控制類之間的成員方法的隱藏和重寫(xiě),理解它們之間的差異和使用場(chǎng)景對(duì)于設(shè)計(jì)靈活且易于維護(hù)的代碼至關(guān)重要,在這篇博客中,我們將詳細(xì)探討這兩個(gè)關(guān)鍵字的用法,并通過(guò)示例來(lái)說(shuō)明它們的實(shí)際應(yīng)用,需要的朋友可以參考下
    2024-10-10
  • Unity3D實(shí)現(xiàn)人物移動(dòng)示例

    Unity3D實(shí)現(xiàn)人物移動(dòng)示例

    這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)人物移動(dòng)示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • C#抽象類與抽象方法詳解

    C#抽象類與抽象方法詳解

    這篇文章主要為大家詳細(xì)介紹了C#抽象類與抽象方法的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • C#實(shí)現(xiàn)策略模式

    C#實(shí)現(xiàn)策略模式

    這篇文章介紹了C#實(shí)現(xiàn)策略模式的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 基于C#實(shí)現(xiàn)PDF轉(zhuǎn)圖片的詳細(xì)教程

    基于C#實(shí)現(xiàn)PDF轉(zhuǎn)圖片的詳細(xì)教程

    在數(shù)字化辦公場(chǎng)景中,PDF文件的可視化處理需求日益增長(zhǎng),本文將圍繞 Spire.PDF for .NET 這一工具,詳解如何通過(guò) C# 將 PDF 轉(zhuǎn)換為 JPG、PNG等主流圖片格式,需要的可以了解下
    2025-08-08
  • 基于WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具

    基于WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具

    串口是設(shè)備和上位機(jī)通信的常用接口,UDP則是網(wǎng)絡(luò)通信常用的通信協(xié)議,串口和UDP之間的相互轉(zhuǎn)換是非常有意義的。本文就利用WPF編寫(xiě)一個(gè)串口轉(zhuǎn)UDP工具,需要的可以參考一下
    2023-04-04
  • 基于C#實(shí)現(xiàn)ModbusTCP服務(wù)器接口的方法

    基于C#實(shí)現(xiàn)ModbusTCP服務(wù)器接口的方法

    ModbusTCP服務(wù)器的本質(zhì)就是TCP服務(wù)器,根據(jù)識(shí)別ModbusTCP請(qǐng)求報(bào)文,返回對(duì)應(yīng)的ModbusTCP報(bào)文,今天給大家分享一下,如何基于C#來(lái)ModbusTCP服務(wù)器接口,需要的朋友可以參考下
    2025-01-01
  • c#初學(xué)簡(jiǎn)單程序?qū)嵗a介紹

    c#初學(xué)簡(jiǎn)單程序?qū)嵗a介紹

    這篇文章介紹了c#初學(xué)簡(jiǎn)單程序?qū)嵗a,有需要的朋友可以參考一下
    2013-10-10

最新評(píng)論

SHOW| 凤翔县| 丰顺县| 大姚县| 屯留县| 夏津县| 丹阳市| 平乡县| 晋宁县| 扶绥县| 崇明县| 且末县| 临颍县| 阿坝| 宜宾市| 奉新县| 黄山市| 平罗县| 鹿邑县| 饶阳县| 佛教| 邹平县| 德令哈市| 克东县| 城市| 兰西县| 扎兰屯市| 平利县| 留坝县| 蒙山县| 新源县| 阜新市| 桓台县| 阿瓦提县| 嘉兴市| 隆安县| 延安市| 调兵山市| 开化县| 湘潭市| 恩施市|