2009-11-05 15 views
5

पर स्ट्रीमिंग इनपुट मैं एक टीसीपी सॉकेट से सी # में भाषण मान्यता "स्ट्रीमिंग" करने की कोशिश कर रहा हूं। मेरी समस्या यह है कि SpeechRecognitionEngine.SetInputToAudioStream() को परिभाषित लंबाई की स्ट्रीम की आवश्यकता होती है जो खोज सकता है। अभी एक ही रास्ता है कि मैं इस काम करने के लिए सोच सकते हैं बार-बार एक MemoryStream पर पहचानकर्ता चलाने हेतु रूप में और अधिक इनपुट में आता हैSystem.Speech.Recognition.SpeechRecognitionEngine

यहाँ वर्णन करने के लिए कुछ कोड है:।

  SpeechRecognitionEngine appRecognizer = new SpeechRecognitionEngine(); 

      System.Speech.AudioFormat.SpeechAudioFormatInfo formatInfo = new System.Speech.AudioFormat.SpeechAudioFormatInfo(8000, System.Speech.AudioFormat.AudioBitsPerSample.Sixteen, System.Speech.AudioFormat.AudioChannel.Mono); 

      NetworkStream stream = new NetworkStream(socket,true); 
      appRecognizer.SetInputToAudioStream(stream, formatInfo); 
      // At the line above a "NotSupportedException" complaining that "This stream does not support seek operations." 

किसी को भी पता है कि कैसे प्राप्त करने के लिए इस के आसपास? इसे किसी प्रकार के स्ट्रीमिंग इनपुट का समर्थन करना चाहिए, क्योंकि यह SetInputToDefaultAudioDevice() का उपयोग कर माइक्रोफ़ोन के साथ ठीक काम करता है।

धन्यवाद, शॉन

+0

हो सकता है कि 'SetInputToDefaultAudioDevice()' माइक्रोसॉफ्ट "काला जादू" (सामान्य) है, या यह बैचिंग किसी प्रकार का प्रदर्शन करती है जैसे आप का सुझाव दिया। –

उत्तर

2

आप एक System.IO.BufferedStream में नेटवर्क धारा लपेटकर की कोशिश की है?

NetworkStream netStream = new NetworkStream(socket,true); 
BufferedStream buffStream = new BufferedStream(netStream, 8000*16*1); // buffers 1 second worth of data 
appRecognizer.SetInputToAudioStream(buffStream, formatInfo); 
+1

बस कोशिश की, और मुझे एक ही त्रुटि मिली। – spurserh

+0

क्या आपने सत्यापित किया है कि बफरर्ड स्ट्रीम मांगने में समर्थित है? आईई, उपर्युक्त कोड में, buffStream.CanSeek() सच हो जाता है? –

1

मैंने इनपुट को बफर कर दिया और फिर इसे बड़े पैमाने पर भाषण मान्यता इंजन में भेज दिया। उदाहरण के लिए, मैं पहले पहले 0.25 सेकेंड, फिर पहले 0.5 सेकंड, फिर पहले 0.75 सेकेंड, और तब तक परिणाम प्राप्त कर सकता हूं जब तक मुझे कोई परिणाम न मिले। मुझे यकीन नहीं है कि यह इस बारे में जाने का सबसे प्रभावी तरीका है, लेकिन यह मेरे लिए संतोषजनक परिणाम उत्पन्न करता है।

बेस्ट ऑफ लक, शॉन

+0

मुझे एसएपीआई और मेमोरीस्ट्रीम के साथ भी समस्याएं आ रही हैं .. अन्याय इसे काम नहीं कर सकता है हालांकि सब कुछ डिफ़ॉल्ट इनपुट, या फ़ाइल से ठीक काम करता है। जब आपने कहा कि आपको बफर का उपयोग करके काम करना है, तो क्या आपका मतलब है कि आप बर्गरस्ट्रीम दृष्टिकोण का उपयोग करते हैं जो सर्गुई ने सुझाव दिया है, या क्या आप मेमोरीस्ट्रीम बड़ा होने तक पहचान को वापस पकड़ते हैं? मैंने सफलता के बिना दोनों की कोशिश की है। क्या आप SpeechHypothesized, SpeechRecognized ईवेंट का उपयोग कर रहे हैं, या RecognitionResult rr = पहचानकर्ता को मजबूर कर रहे हैं। हर बार पहचानें()? क्या आप मदद करने के लिए कोई और कोड पोस्ट करने में सक्षम हैं? बहुत सराहना की जाएगी। – timemirror

9

मैं धारा वर्ग अधिभावी द्वारा काम करने को लाइव भाषण मान्यता मिल देखें:

class SpeechStreamer : Stream 
{ 
    private AutoResetEvent _writeEvent; 
    private List<byte> _buffer; 
    private int _buffersize; 
    private int _readposition; 
    private int _writeposition; 
    private bool _reset; 

    public SpeechStreamer(int bufferSize) 
    { 
     _writeEvent = new AutoResetEvent(false); 
     _buffersize = bufferSize; 
     _buffer = new List<byte>(_buffersize); 
     for (int i = 0; i < _buffersize;i++) 
      _buffer.Add(new byte()); 
     _readposition = 0; 
     _writeposition = 0; 
    } 

    public override bool CanRead 
    { 
     get { return true; } 
    } 

    public override bool CanSeek 
    { 
     get { return false; } 
    } 

    public override bool CanWrite 
    { 
     get { return true; } 
    } 

    public override long Length 
    { 
     get { return -1L; } 
    } 

    public override long Position 
    { 
     get { return 0L; } 
     set { } 
    } 

    public override long Seek(long offset, SeekOrigin origin) 
    { 
     return 0L; 
    } 

    public override void SetLength(long value) 
    { 

    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     int i = 0; 
     while (i<count && _writeEvent!=null) 
     { 
      if (!_reset && _readposition >= _writeposition) 
      { 
       _writeEvent.WaitOne(100, true); 
       continue; 
      } 
      buffer[i] = _buffer[_readposition+offset]; 
      _readposition++; 
      if (_readposition == _buffersize) 
      { 
       _readposition = 0; 
       _reset = false; 
      } 
      i++; 
     } 

     return count; 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     for (int i = offset; i < offset+count; i++) 
     { 
      _buffer[_writeposition] = buffer[i]; 
      _writeposition++; 
      if (_writeposition == _buffersize) 
      { 
       _writeposition = 0; 
       _reset = true; 
      } 
     } 
     _writeEvent.Set(); 

    } 

    public override void Close() 
    { 
     _writeEvent.Close(); 
     _writeEvent = null; 
     base.Close(); 
    } 

    public override void Flush() 
    { 

    } 
} 

... और SetInputToAudioStream विधि करने के लिए धारा इनपुट के रूप में है कि का एक उदाहरण का उपयोग करते हुए। जैसे ही स्ट्रीम लम्बाई लौटाती है या लौटाई गई गिनती उस अनुरोध से कम होती है, पहचान इंजन सोचता है कि इनपुट समाप्त हो गया है। यह एक गोलाकार बफर सेट करता है जो कभी खत्म नहीं होता है।

+0

हाय सीन, मैं काम करने के लिए अपना समाधान पाने की कोशिश कर रहा हूं लेकिन अभी तक इसे प्रबंधित नहीं किया है। जैसा कि उपरोक्त अन्य सभी के साथ डिस्क फ़ाइल से ठीक काम करता है लेकिन मेमोरीस्ट्रीम के साथ काम नहीं करता है। क्या आप कभी-कभी एक पहचान अनुरोध जारी करते हैं, या आप SpeechHypothesized, SpeechRecognized घटनाओं का उपयोग करने में सक्षम हैं? क्या आप मदद के लिए कोई और कोड पोस्ट कर सकते हैं? धन्यवाद! – timemirror

+0

क्षमा करें, आपका प्रश्न याद किया, वहां आप जाते हैं। इसके साथ में मैं वास्तविक समय भाषण मान्यता करने में सक्षम हूं और नेटवर्क पर ऑडियो फीड को भी स्ट्रीम करता हूं (मेरे ओपन सोर्स प्रोजेक्ट आईएसपी का हिस्सा - http://www.ispyconnect.com) – Sean

+0

धन्यवाद शॉन ... महान दिखने वाला प्रोजेक्ट । – timemirror

1

यह मेरा समाधान है।

class FakeStreamer : Stream 
{ 
    public bool bExit = false; 
    Stream stream; 
    TcpClient client; 
    public FakeStreamer(TcpClient client) 
    { 
     this.client = client; 
     this.stream = client.GetStream(); 
     this.stream.ReadTimeout = 100; //100ms 
    } 
    public override bool CanRead 
    { 
     get { return stream.CanRead; } 
    } 

    public override bool CanSeek 
    { 
     get { return false; } 
    } 

    public override bool CanWrite 
    { 
     get { return stream.CanWrite; } 
    } 

    public override long Length 
    { 
     get { return -1L; } 
    } 

    public override long Position 
    { 
     get { return 0L; } 
     set { } 
    } 
    public override long Seek(long offset, SeekOrigin origin) 
    { 
     return 0L; 
    } 

    public override void SetLength(long value) 
    { 
     stream.SetLength(value); 
    } 
    public override int Read(byte[] buffer, int offset, int count) 
    { 
     int len = 0, c = count; 
     while (c > 0 && !bExit) 
     { 
      try 
      { 
       len = stream.Read(buffer, offset, c); 
      } 
      catch (Exception e) 
      { 
       if (e.HResult == -2146232800) // Timeout 
       { 
        continue; 
       } 
       else 
       { 
        //Exit read loop 
        break; 
       } 
      } 
      if (!client.Connected || len == 0) 
      { 
       //Exit read loop 
       return 0; 
      } 
      offset += len; 
      c -= len; 
     } 
     return count; 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     stream.Write(buffer,offset,count); 
    } 

    public override void Close() 
    { 
     stream.Close(); 
     base.Close(); 
    } 

    public override void Flush() 
    { 
     stream.Flush(); 
    } 
} 

का उपयोग कैसे करें:

//client connect in 
TcpClient clientSocket = ServerSocket.AcceptTcpClient(); 
FakeStreamer buffStream = new FakeStreamer(clientSocket); 
... 
//recognizer init 
m_recognizer.SetInputToAudioStream(buffStream , audioFormat); 
... 
//recognizer end 
if (buffStream != null) 
    buffStream.bExit = true;