LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Read/Write Voice Data on Serial Link

Hi,

 

I am sending voice data over serial link acquired via microphone of PC. The data is in the form of array [1D array - 64 bit real(15 digit precision)]. I want to receive/read this data (ditto copy) using serial link. How can I do this? 

 

On my end, I successfully converted a 1D array into a string packet using the F-Format VI and transmitted it over a serial connection. The sending process went smoothly. However, on the receiving side, I am facing challenges reconstructing the original array. This is crucial for using the "Play Waveform VI," which demands the exact array to decode the voice at receiving end.

 

I have attached my code as well. Someone please assist me how can I accomplish this problem. (You may suggest a different way to accomplish this)

 

Note: Please Use microphone with PC/Laptop while running the code.

 

Thank you 🙂

0 Kudos
Message 1 of 8
(937 Views)

Hi nisarr,

 


@nisarr wrote:

On my end, I successfully converted a 1D array into a string packet using the F-Format VI and transmitted it over a serial connection. The sending process went smoothly. However, on the receiving side, I am facing challenges reconstructing the original array. This is crucial for using the "Play Waveform VI," which demands the exact array to decode the voice at receiving end.


You need to back-convert the received string in the reverse way as you created that string from your waveform data!

Unfortunately you don't show how you accomplished that part of the task…

 

Generic, but important, advice for serial communication: watch this video!

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 8
(903 Views)

Thanks for including your code, and for using LabVIEW 2019 (which is what I'm also using, so I can open your VI).

 

I'm going to comment on various "parts" of your code. 

  • Why are you combining code for reading from a VISA device (presumably reading from something, but I don't know what) at a ridiculously-low Baud rate (9600 Baud is about 1000 characters/second, so your sound information would have no components > 500 Hz, not even an octave above Middle C (= 256 Hz)?
  • Why are you reading from VISA 2 (presumably a sound representation of some sort) at the same (very slow) Baud rate?  Your loop time of 200 ms means each loop only gets around 1000 samples (or 500 per channel, I forgot the factor of 2 in my previous point, so the sounds are all below Middle C)?  [Oops -- you seem to be doing "Mono", not "Stereo", but what's a factor of 2 between friends?]
  • Remember the Second Law of Data Flow -- the While Loop cannot "loop" until everything inside it has executed, so the fastest it can run is 5 times/second.  Acquiring 22,500 samples at (roughly) 1000 samples/second would take 22.5 seconds, so instead of the loop running at 5 Hz, it can't run faster than 1/22.5 (or about 0.04 Hz).
  • Somewhere on the Forum @Crossrulz has posted his excellent NI Week presentation on VISA I/O, which notes one should (almost) never use Bytes at Port, particularly if the VISA channel is configured to use a Termination Character (which is how you have the VISA channel configured).  I'm sure someone will post a link here ...

It is unclear to me why you have one loop in which you appear to be both acquiring VISA data (from what?) and presumably playing it through the PC's speaker and simultaneously acquiring (in the same loop!) sound data from a microphone and transmitting it (to where?) via VISA.  The one "consistent" feature is that the Sound I/O is 22.5 kHz, while the VISA I/O is 9600 Baud (which I'm approximating at 1000 bytes/sec).  Oh, I forgot another factor of 2 -- the Sound I/O uses 16-bit integer representation, so you receive 45,000 bytes/sec.

 

LabVIEW's Sound functions, I believe, use 16-bit integer representation.  That's much more compact (by a factor of 4) than Dbl, so you'll gain a nice "speed of transmission and I/O" and save disk space, too, by not wasting time with Dbls.

 

For reading sounds from a microphone and writing them to disk, if you are only doing a single read with one second of data (and acquiring 22,500 samples), it is fine to write this to disk as an array of I32 (or U32, depending), but why are you writing it to VISA, particularly with such a huge amount of data all at once that will take many seconds to be transmitted at 9600 Baud?

 

OK, enough questions.  Think about what you want to do (which, I'm assuming, is not exactly what your code suggests you want to do ...).  Think seriously about writing a VI that reads sound, and one that writes sound.

 

Bob Schor

 

P.S. -- @GerdW just posted Crossrulz's talk about the proper way to handle VISA communication.  Thanks, Gerd!

 

0 Kudos
Message 3 of 8
(897 Views)

Hi Bob Schor,

 

First of all I would like to thank you for your comments. I will explain step by step.

 

  • I've incorporated a test code into my query. You're correct about avoiding a 9600 baud rate; I plan to use higher baud rates later. At the moment, I'm concentrating on retrieving the data I wrote to the serial port. I've converted the array to a string, but I'm uncertain about the process for reconstructing the original array from the string when receiving it on the other end.
  • You are right, I should be running the loop it at 0.04 Hz.
  • I'm writing this data using VISA due to my hardware constraints, as I only have a serial link available for transmitting my voice data. As for why I'm handling both transmission and reception within the same code, it's because I'm developing a GUI that will serve both as a transmitting and receiving station, situated in two different physical locations. Currently, for testing purposes, I'm utilizing a virtual serial port on my laptop. The voice data from the transmitting station will be sent through my GUI to the hardware, which will wirelessly transmit it to the receiving station. The receiving station, equipped with the same GUI, will utilize the serial port configured for receiving the data. I trust this clarifies my inquiry.

 

Please provide guidance on reconstructing an array of voice data at the receiving station, which I can subsequently play using the "Play Waveform" VI.

 

Nisar

0 Kudos
Message 4 of 8
(875 Views)

Hi,

 

Thank you for your reply. Actually, i am facing problem in converting it back to original form at receiving side and need assistance on same, please.

0 Kudos
Message 5 of 8
(867 Views)

Thank you for clarifying your application.  So let's assume that you really are using VISA over a serial line for data transmission (a very strange and poor choice, especially when compared to, say, TCP/IP).  Wait a minute -- VISA means you are communicating over a multi-wire cable, where you have pulses, with a maximum Baud Rate of 115200, which is (roughly) 11520 bytes/sec, or 11.5 kB/s.  Compare this to TCP/IP, where a slow connection (10-BaseT, 10 Mbps = 1.25 MBytes/sec, 100 times faster, and faster than the 22+ kB/sec of the sound processor.

 

Note that if you persist in using VISA for communication, you are going to need to "build your own protocol" (whereas TCP/IP has the "protocol" build-in, so to speak).  What I mean is that if you take a second's worth of data at a sampling rate of 22,500 16-bit samples/sec, you'll have 45,000 samples which you are trying to send over a serial line.  Serial communication can get tricky -- you are transmitting a binary signal with a transmitter and receiver that are running independently of each other, so they need to keep their (independent) clocks synchronized, otherwise they are likely to drift slightly out of phase with each other and make "bit" errors, particularly if the waveform is multiple bytes.  One way of dealing with this is to transmit not 8 bits of data, but 7 bits, with a "parity" bit, so the receiver can tell if the transmission "dropped" a bit, but now you are missing a (data) bit per word, and need to send the two missing bits separately.  And what do you do if there is a transmission error?

 

Go Google TCP/IP, and see how much effort is made when transmitting information to build a Transmission Control Protocol (look at the capitalized letters -- do they look familiar?).

 

Note -- the article on VISA that Gerd and I mentioned to you doesn't apply here.  You are not transmitting "text" data, for which VISA isn't such a bad idea, as with Text, you largely are dealing with 7-bit ASCII data, with <CR> and <LF> available as end-of-transmission signals, but then you need to break your 16-bit data into 4 bytes (three with the 16 bits "coded" as three "printable" ASCII characters and the fourth byte the "Termination" character, <LF> (I think), reassembling the data on the receiving end.  It's a real mess ...

 

Bob Schor

0 Kudos
Message 6 of 8
(843 Views)

@Bob_Schor wrote:

Note -- the article on VISA that Gerd and I mentioned to you doesn't apply here.  You are not transmitting "text" data, for which VISA isn't such a bad idea, as with Text, you largely are dealing with 7-bit ASCII data, with <CR> and <LF> available as end-of-transmission signals, but then you need to break your 16-bit data into 4 bytes (three with the 16 bits "coded" as three "printable" ASCII characters and the fourth byte the "Termination" character, <LF> (I think), reassembling the data on the receiving end.  It's a real mess ...


The second half of the video is dealing with binary data.  It does still apply.  The thing with binary transmission is that you have to provide a data frame to keep the receiver in sync with the transmitted data.  A frame is typically a start byte of some kind (0x2 is very common) followed by a command code (probably not required here if we always assume it is always sound data), a length (probably worth having), the data, and then a checksum of some sorts (a simple U8 addition of all the data bytes is common as is one of the many CRC algorthims).

 


@Bob_Schor wrote:

Thank you for clarifying your application.  So let's assume that you really are using VISA over a serial line for data transmission (a very strange and poor choice, especially when compared to, say, TCP/IP).  Wait a minute -- VISA means you are communicating over a multi-wire cable, where you have pulses, with a maximum Baud Rate of 115200, which is (roughly) 11520 bytes/sec, or 11.5 kB/s.  Compare this to TCP/IP, where a slow connection (10-BaseT, 10 Mbps = 1.25 MBytes/sec, 100 times faster, and faster than the 22+ kB/sec of the sound processor.


I agree Ethernet would be a much better transmission path here, if possible.  But, don't conflate VISA with RS-232/422/485.  VISA can use GPIB or even Ethernet.  VISA is just a communication abstraction layer.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 7 of 8
(818 Views)

@crossrulz wrote:

I agree Ethernet would be a much better transmission path here, if possible.  But, don't conflate VISA with RS-232/422/485.  VISA can use GPIB or even Ethernet.  VISA is just a communication abstraction layer.

Of course!  I'd forgotten that I wrote an earlier program that gathered data from multiple Mettler balances with a VISA interface from a room 5 floors and two corridors away -- the VISA stream went through a 12-port "Serial to Ethernet" device.  The little routine, below, used the Balance number to determine the string for the IP address of the Balance needed for the VISA Open, and if the Interface Type property was 6 (for TCP/IP), I set up the Termination pattern to use 0A (<LF>).

Get Balance IP.pngOpen Balance (VISA over TCP-IP).png

 

Bob Schor

0 Kudos
Message 8 of 8
(807 Views)