Extracting SMPTE timecode from audio stream - audio-recording

I'm working on an audio recording system. My task involves extracting the SMPTE time code from audio input stream, generated by a synchronizer device. I'm using ASIO SDK to get the time code of each callback buffer but it's always zero.
Perhaps somebody has experience in ASIO SDK (or any other platform/sdk that can be used to extract SMPTE timecode from audio stream) could help me?
Regards,
Ben

LTC is straightforward, so If nothing else, you could just scan the audio stream for LTC data, as documented on wikipedia. Each 80 bit frame ends with 0011 1111 1111 1101, just scan for that byte sequence to synchronize, then cast the buffer data starting after that sync sequence to be an array of 80 bit struct timecode_t elements. If your buffer is sized as a multiple of 80 your calculations will be easier (but you do need to test for sync lossage, because soundcards lose bits with overruns).
The hard part is that if I am not mistaken, the time code "bits" are not the same of the bits of the sampled audio stream, so you would have to implement logic to detect the bit sequence. This can just be a for loop checking for the proper signal changes and appending bits to the buffer as appropriate (and then calling the function to interpret the buffer when it is full).

Related

Design of compression using OpenCL FPGA ,Memory allocation

I am trying to implement lossy compression algorithms using OpenCL ,I have divided the work into two kernels ,one for implementing the algorithm itself and the other one is used for encoding ,means that ,I am trying to concatenate different sized bytes into the stream of the compressed data ,the problem is that ,I am getting high initiation interval due to inefficient memory accesses ,and it takes too much time for the encoding part ,when I opened HTML report ,I got the following message :
**stallable, 13 reads and 25 writes.
Reduce the number of write accesses or fix banking to make this memory system stall-free. Banking may be improved by using compile-time known indexing on lowest array dimension.
Banked on bits 0, 1 into 4 separate banks.
Private memory implemented in on-chip block RAM
My question is ,how could I improve the allocation of the stream ,the way i do it is as follow :
unsigned char __attribute__((numbanks(4),bankwidth(8))) out[outsize];
but it is inefficient ,is there any technique or way that I can use for better utilization?
The way I do encoding is that ,I am adding byte while monitoring the index of last modified bit and byte ,so I am doing exoring and because sometime I got more than one byte or less than one btye so I work byte by byte

Muxing non-synchronised streams to Haali

I have 2 input streams of data that are being passed to a Haali Muxer (mp4 format).
Currently I stream these to Haali directly in a DirectShow graph without a clock. I wondered if I should be trying to write these to the muxer synchronised, or whether it happily accepts a stream of audio data that stops before the video data stream stops. (I have issues with the output file not playing audio after seeking, and I'm not sure why this could occur)
I can't find much in the way of documentation for muxing with the Haali muxer, does anyone know the best place to look for info on this filter?
To have the streams multiplexed into single MP4 file you need single instance of multiplexer (Haali, GDCL, commercial, wrapper over mp4v2 library, over Media Foundation sink etc) with two (or more) input pins on it connected to respective sources, which in turn are going to be written as tracks.
Filter graph clock does not matter. Clock is for presentation, and file writers accept incoming data and write it as soon as possible anyway. It is more accurate to remove the clock, as you seem to already be doing, but having standard clock is not going to be different.
Data is synchronized using time stamps on individual media samples, parts of media streams. Multiplexer builds internal queues for every stream and then consumes data from the streams to build single file, in a sort of way that original stream data is interleaved. If one stream supplies too much data, that is, if data is available too early while another stream supplies data slowly, multiplexer blocks further data reception on this particular stream by not returning from respective processing call (IPin::Receive) expecting that during this wait the slow stream provides additional input. Eventually, what multiplexer looks at when matching data from different streams is data time stamps.
To obtain synchronized data in resulting MP4 file you, thus, need to make sure the payload data is properly time stamped. Multiplexer will take care of the rest.
This also includes that the time stamps should be monotonously increasing within a stream, and key frames/splice points are respectively indicated. Otherwise some multiplexers might issue a failure immediately, other would produce the output file but it might have playback issues (esp. seeking).

Add to QByteArray with 1 byte the 9-th bit

I have a situation right now when I have after reading the byte stream from COM port in object of QByteArray type exactly and only 1 byte of data. BUT one very non-friendly protocol requires to have 9 bits of data after reading data from COM port.
But according to win32API function: ReadFile(....) I can read from the COM stream ONLY bytes= 1,2,3.....
So - That's why I am reading only 8 bits=1 byte with help of this function and with help of some operations with parity bit I am calculating the value of the 9th bit of generalized data...
So on one hand I have 1 byte (8 bits) of proper(real) data - on another hand I have a value of this 9th bit (0 or 1); 2 objects which in sum must create the value of generalized data.
How I can combine these objects into one & final QByteArray object? Because the global function ReadComData can and must return only QByteArray object.
UARTs cannot "write" 9-bit data. On the wire, your (typically 8-bit) data are usually framed between a start-bit and a stop-bit, so you have 10 bits transmitted for every byte you send. If you have a parity bit, it is transmitted after the last data bit, but before the stop bit. But this is generated by the sending UART, not part of a protocol. A data bus for a typical UART 16550 is only 8-bits wide (you can actually send 5-, 6-, 7-, or 8-bit data).
On the receiving end, the UART has to be configured based on what is on the wire. If your sender is using a parity bit, then you program the UART (via the "COM" port settings) accordingly. The parity bit is just to help check for errors on the wire. It is based on the data bits -- you cannot put another data bit in a parity bit. The receiving UART can be used to check for parity errors (read via the line status register (LSR)), and this can be passed up to you via system calls.
It is possible your protocol is splitting up the data across multiple bytes. If that's the case, then convert two bytes into one 16-bit word and mask the 6 bits you don't want to use.

How to use streaming audio data from microphone for ASR in Qt

I'm working on a speech recognition project and my program can recognize words from audio files. Now I need to work with the audio stream coming from microphone. I'm using QAudio for getting sound data from mic and QAudio has a function to start the process. This start(* QBuffer) function writes the data into a QBuffer(inherited from QByteArray) object. When I'm not dealing with continuous stream, I can stop recording from mic anytime I want and copy the whole data from QBuffer into a QByteArray and I can do whatever I wanna do with the data. But in continuous stream QBuffer's size increases by time and becomes 100Mb in 15 mins.
So I need to use some kind of circular buffer but I can't figure out how to do that especially with this start(*QBuffer) function. I also avoid of cutting the streaming sound at a point where the speech continues.
What is the basic way to handle streaming audio data for speech recognition?
Is it possible to change the start(*QBuffer) function into start(*QByteArray) and make the function to overwrite on that QByteArray to build and circular buffer?
Thanks in advance
boost.com is offering a circular buffer
http://www.boost.org/doc/libs/1_37_0/libs/circular_buffer/doc/circular_buffer.html#briefexample
It should meet what you need
Alain

Start Bit vs Start Byte

I know in a lot of asynchronous communication, the packet begins starts with a start bit.
But a start bit is just a 1 or 0. How do you differentiate a start bit from the end bit from the last packet?
Ex.
If I choose my start bit to be 0 and my end bit to be 1.
and I receive 0 (data stream A) 1 0 (data stream B) 1,
what's there to stop me from assuming there is a data stream C which contains the same contents of "(data stream A) 1 0 (data stream B)" ?
Isn't it more convenient to have a start BYTE and then check the data stream for that combination of bits? That will reduce the possibility of a confusing between the start/end bit.
Great question! Most asynchronous communication also specifies a stop bit, which is the complement of the start bit, ensuring each new symbol begins with a stop-to-start transition.
Example: let's transmit the characters ABC, which are ASCII 65, 66, and 67:
A = 65 = 0x41 = 0100 0001
B = 66 = 0x42 = 0100 0010
C = 67 = 0x43 = 0100 0011
Let's also assume (arbitrarily) that the start bit is 0 and the stop bit is 1, and the data is transmitted from MSB to LSB. The transmitter will be in the stop (1) state when no data is transmitted. So the receiver might see this:
Data: ....1111 0010000011 111 0010000101 0010000111 11111....
(quiet) ^ A $ ^ B $ ^ C $ (quiet)
With apologies for the ASCII graphics, the data consists of a series of stop (1) bits while the channel is idle. When the transmitter is ready to send a character, it sends a start (0) bit (marked with ^), followed by the character code, and ending with a stop (1) bit (marked with $). It continues to send stop bits until the next character is transmitted, beginning with another start bit.
The reason we use start bits instead of bytes is efficiency. The scheme above requires 10 bits (1start + 8data + 1stop) to transmit 8 bits of data, resulting in an overhead of (10 - 8) / 8 = 1/4 = 25%. If we used start and stop bytes, we'd need to transmit 3 bytes for each byte of data, which would be an overhead of (3 - 1)/1 = 2 = 200%. If the start, data, and stop bytes were each 8 bits, we'd have to transmit 24 bits instead of 10 for each character, so it would take almost 2 1/2 times as long to send the data!
One can always define a start byte as an indication that a message is beginning (and the ASCII SOH, STX, and ETX codes were intended for such purposes). However, the standard hardware and protocols for connection to data-transmission equipment (RS232C and later) operate at a lower level, and it is generally neither possible nor desirable to alter that arrangement (especially via software).
High performance synchronous data transmission schemes, such as those used on local-area networks and wide-area transmission systems do use elaborate frame markers. The frame marker is a distinct pattern of bits that never occurs in the stream for message data. There is typically a special rewriting rule that essentially "escapes" any in-data occurrence of a similar bit pattern so that transmission equipment will not see it as a frame marker. These escaped patterns are reconstructed by the recipient so the sender and receiver never have to pay attention to this. These arrangements make specialized hardware even more important, such as in the typical Network Interface Card (these days, motherboard chip) on personal computers.
BACKGROUND ON ASYNCHRONOUS SERIAL COMMUNICATION
It is useful to think of asynchronous serial transmissions as asynchronous between character/data frames and synchronous within the span of the character frame (including the start bits and initial stop/fill).
With this scheme, there is a constant fill signal between the frames and it is usually at least one data-bit wide, although some arrangements require a 1.5-bit or two-bit stop/fill. The stop "bit" uses the same signal level and can be considered the minimum fill period before another start bit will arrive.
When a frame is arriving, it is necessary to synchronize with the predetermined number of bits it is expected to carry. The transition from the fill to an opposite level signal is accomplished by the start bit which is always opposite to the stop/fill level. The sampling of the bits can be timed to happen in the middle of subsequent bit-arrival periods.
Technically, if frames were being sent at the maximum rate, it would not be necessary to send any stop/fill, proceeding to the start bit of the next frame immediately. However, counting on at least one bit worth of fill before the start-bit transition helps to keep the sender and receiver synchronized.
If you think of the asynchronous streams as being encoded from key depressions using a keyboard, you can see the importance of allowing arbitrary fill between character frames. Once it is known what frame to send next, it can be inserted immediately, with its start bit, at the agreed bit rate, after there has been at least one bit worth of preceding stop/fill.
It is also useful to notice that, in typical low-speed asynchronous transmissions, there are only two kinds of bits/levels, so the only way the presence of data as opposed to fill can be distinguished is by a marker scheme like this where the start of the frame is uniquelly detectable and the end of frame is predetermined (unless there is a more-sophisticated variable-length frame structure generally not used in asynchronous serial communication). It is actually rather difficult for a receiver to discover the bit rate of a transmitter without some additional agreement, such as looking for a recognizable data sequence from which one can estimate the bit rate which would have it arrive correctly when it arrives in incorrect form.
Even though high-speed modems now transmit complex analog signals that aren't described in terms of two simple signal levels, the RS232C (and later-mode) digital communication between a computer UART and the data coupling on the modem is pretty much as described.
High-speed modems also have additional capabilities for synchronizing with a distant end-point, as you can tell by listening to the signal audio while a connection starts up. In addition, There are separate signal lines in the serial cable to the computer that are used for pacing between the computer and the modem so that the sending party does not transmit new data frames faster than the receiving party (either computer or modem) can accept them. But a frame, once started, is always started at the agreed synchronous speed.
Wikipedia has a good description of asynchronous serial communication, what computer serial ports use.
There is a common over-simplification that suggests the stop bit determines the length of the data. That's not the case. The stop bit looks just like a level for another data bit. The way the stop bit and the period until the next start bit, are recognized is by knowing the bit rate at which in-frame data and start/stop bits are being transmitted and knowing how many bits a frame contains. Otherwise, there is no way to distinguish a stop bit from just another bit of that polarity as part of the data frame.
Here is the way start and stop bits usually work:
A start bit is sent, say 1. This indicates to the receiver that a specified number of bits of data will be transmitted, say 8.
8 bits of data are sent.
A stop bit is sent, say 0. This indicates that the 8 bits of data have been sent.
If more data is to be sent, each byte must be initiated with a start bit and terminated with a stop bit. The transmitter and receiver must agree on how many bits of data are sent for each start bit so the receiver will be able to distinguish the stop bit from the data. Sometimes the start bit is actually multiple bits or even a byte, but the idea is the same. The receiver recognizes the end of the data frame when it sees the stop bit after receiving the pre-specified number of data bits. Sometimes a parity bit is sent before the stop bit to provide a simple error-detecting mechanism.
It is all protocol dependent. You can say that after start symbol you will expect N symbols or you will read until you encounter the stop symbol.
Where symbol colud be any n-bit sequence (including bit and byte.)
Indeed, your example with bits exactly apply to a protocol which uses bytes instead of bits.
Say you send 00000000 stream A 11111111 00000000 stream B 11111111. In this case you may still confuse it with stream C = stream A 11111111 00000000 stream B.
Usually a start bit is used because a voltage level change can trigger an event (See edge triggering in flip flops.) On the other hand a start symbol with multiple bits will be used to synchronize clocks of two systems in addition to triggering an event. An example of it would be a PAL signal.
The start and stop bits come from the days of the teletypes. They essentially were pulses that took up time to sort of let the mechanical hardware set. Dos text file lines are ended with CR LF which literally caused the carriage to return to column 1, and the platen to advance one line. I think it is in the order because it takes longer for the CR to occur, and the LF can effectively happen in parallel.
Detecting it is a little bit harder. You sort of have to watch the bit stream go by.
Over time you ought to be able to detect it, as the data is normally ASCII with the start/stop bits around it. Normally this isn't an issue, because it is handled by the UART which runs the COM port.

Resources