How to convert PCM audio to TrueSpeech using NAudio - naudio

I am trying to convert a PCM 8 bit 8 KHz Mono file to DSP TrueSpeech 1 bit 8 kHz Mono using NAudio, and I get the following error:
A first chance exception of type 'NAudio.MmException' occurred in NAudio.dll
AcmNotPossible calling acmStreamOpen
I understand that there may be an intermediate step that I am missing -- any insight would be appreciated. Here is the code I am using:
WaveFormat outWaveFormat;
outWaveFormat = new TrueSpeechWaveFormat();
Debug.Print("Sample Rate: " + outWaveFormat.SampleRate); //displays "8000"
Debug.Print("Bit Rate: " + outWaveFormat.BitsPerSample); //displays "1"
FileInfo f = new FileInfo(inputFile);
String outputFileName = this.txtDest.Text + #"\" + f.Name;
using (WaveFileReader reader = new WaveFileReader(inputFile))
{
try
{
using (WaveStream convertedStream = new WaveFormatConversionStream (outWaveFormat, reader))
{
WaveFileWriter.CreateWaveFile(outputFileName, convertedStream);
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}

Two reasons this might be happening:
you don't have a TrueSpeech encoder. I don't think newer versions of Windows include TrueSpeech anymore - it is effectively obsolete. You can run the NAudioDemo application to see what ACM codecs are on your machine.
your input format cannot convert to the target format in one step. Are you sure your input is PCM. Also I would expect that the TrueSpeech codec wants 16 bit input not 8 bit.
There is a third reason this can happen, although I don't think it affects TrueSpeech and that is that WaveFileWriter.CreateWaveFile assumes that AverageBytesPerSecond is an exact multiple of BlockAlign, which is not always true.

Related

PLC4X:Exception during scraping of Job

I'm actually developing a project that read data from 19 PLCs Siemens S1500 and 1 modicon. I have used the scraper tool following this tutorial:
PLC4x scraper tutorial
but when the scraper is working for a little amount of time I get the following exception:
I have changed the scheduled time between 1 to 100 and I always get the same exception when the scraper reach the same number of received messages.
I have tested if using PlcDriverManager instead of PooledPlcDriverManager could be a solution but the same problem persists.
In my pom.xml I use the following dependency:
<dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-scraper</artifactId>
<version>0.7.0</version>
</dependency>
I have tried to change the version to an older one like 0.6.0 or 0.5.0 but the problem still persists.
If I use the modicon (Modbus TCP) I also get this exception after a little amount of time.
Anyone knows why is happening this error? Thanks in advance.
Edit: With the scraper version 0.8.0-SNAPSHOT I continue having this problem.
Edit2: This is my code, I think the problem can be that in my scraper I am opening a lot of connections and when it reaches 65526 messages it fails. But since all the processing is happenning inside the lambda function and I'm using a PooledPlcDriverManager, I think the scraper is using only one connection so I dont know where is the mistake.
try {
// Create a new PooledPlcDriverManager
PlcDriverManager S7_plcDriverManager = new PooledPlcDriverManager();
// Trigger Collector
TriggerCollector S7_triggerCollector = new TriggerCollectorImpl(S7_plcDriverManager);
// Messages counter
AtomicInteger messagesCounter = new AtomicInteger();
// Configure the scraper, by binding a Scraper Configuration, a ResultHandler and a TriggerCollector together
TriggeredScraperImpl S7_scraper = new TriggeredScraperImpl(S7_scraperConfig, (jobName, sourceName, results) -> {
LinkedList<Object> S7_results = new LinkedList<>();
messagesCounter.getAndIncrement();
S7_results.add(jobName);
S7_results.add(sourceName);
S7_results.add(results);
logger.info("Array: " + String.valueOf(S7_results));
logger.info("MESSAGE number: " + messagesCounter);
// Producer topics routing
String topic = "s7" + S7_results.get(1).toString().substring(S7_results.get(1).toString().indexOf("S7_SourcePLC") + 9 , S7_results.get(1).toString().length());
String key = parseKey_S7("s7");
String value = parseValue_S7(S7_results.getLast().toString(),S7_results.get(1).toString());
logger.info("------- PARSED VALUE -------------------------------- " + value);
// Create my own Kafka Producer
ProducerRecord<String, String> record = new ProducerRecord<String, String>(topic, key, value);
// Send Data to Kafka - asynchronous
producer.send(record, new Callback() {
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
// executes every time a record is successfully sent or an exception is thrown
if (e == null) {
// the record was successfully sent
logger.info("Received new metadata. \n" +
"Topic:" + recordMetadata.topic() + "\n" +
"Partition: " + recordMetadata.partition() + "\n" +
"Offset: " + recordMetadata.offset() + "\n" +
"Timestamp: " + recordMetadata.timestamp());
} else {
logger.error("Error while producing", e);
}
}
});
}, S7_triggerCollector);
S7_scraper.start();
S7_triggerCollector.start();
} catch (ScraperException e) {
logger.error("Error starting the scraper (S7_scrapper)", e);
}
So in the end indeed it was the PLC that was simply hanging up the connection randomly. However the NiFi integration should have handled this situation more gracefully. I implemented a fix for this particular error ... could you please give version 0.8.0-SNAPSHOT a try (or use 0.8.0 if we happen to have released it already)

Unable to update unidata from .NET

I've been attempting for the last couple of days to update unidata using sample code as a basis using .NET without success. I can read the database successfully and view the raw data within visual studio. The error reported back is a out of range error. The program is attempting to update the unit price of a purchase order.
Error:
{" Error on Socket Receive. Index was outside the bounds of the array.POD"}
[IBMU2.UODOTNET.UniFileException]: {" Error on Socket Receive. Index was outside the bounds of the array.POD"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146232832
InnerException: null
Message: " Error on Socket Receive. Index was outside the bounds of the array.POD"
Source: "UniFile Class"
StackTrace: " at IBMU2.UODOTNET.UniFile.Write()\r\n at IBMU2.UODOTNET.UniFile.Write(String aRecordID, UniDynArray aRecordData)\r\n at ReadXlsToUnix.Form1.TestUpdate(String PO_LINE_SHIP, String price) in c:\Users\xxx\Documents\Visual Studio 2013\Projects\ReadXlsToUnix\ReadXlsToUnix\Form1.cs:line 330"
TargetSite: {Void Write()}
failing Test Code is:
private void TestUpdate(string PO_LINE_SHIP,string price)
{
UniFile pod =null;
UniSession uniSession =null;
//connection string
uniSession = UniObjects.OpenSession("unixMachine", "userid", Properties.Settings.Default.PWD, "TRAIN", "udcs");
//open file
pod = uniSession.CreateUniFile("POD");
//read data
pod.Read(PO_LINE_SHIP);
//locking strategy
pod.UniFileLockStrategy = 1;
pod.UniFileReleaseStrategy = 1;
if (pod.RecordID == ""){
pod.UnlockRecord();
}
//replace existing value with one entered by user
pod.Record.Replace(4, (string)uniSession.Iconv(price, "MD4"));
try
{
pod.Write(pod.RecordID,pod.Record); //RecordId and Record both show correctly hover/immediate window
//pod.Write() fails with same message
}
catch (Exception err)
{
MessageBox.Show("Error" + err);
}
pod.Close();
UniObjects.CloseSession(uniSession);
}
}
Running on HP UX 11.31 unidata 7.2 and using UODOTNET.dll 2.2.3.7377
Any help greatly appreciated.
This is the write record version and have also tried writefield functionality with same error.
Rajan - thanks for the update and link. I have tried unsuccessfully to read/update my unidata tables using the U2 Toolkit. I can however read/update a file I have created within the same account. Does this mean there is a missing entry somewhere VOC, DICT for example.

php-smpp Library not working and fails after two to three SMS

it is very first time i'm messing with sockets , and read many quotes that this is not for newbies.
so problem is i'm using php smpp library for sending SMS which works fine but after delivering two to three SMS delivery fails with following warning
Warning: stream_socket_sendto() [function.stream-socket-sendto]: An existing connection was forcibly closed by the remote host', and to make it work again i need to restart` apache.
Following is write function which throwing exception
public function write($buf) {
$null = null;
$write = array($this->handle_);
// keep writing until all the data has been written
while (strlen($buf) > 0) {
// wait for stream to become available for writing
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable > 0) {
// write buffer to stream
$written = stream_socket_sendto($this->handle_, $buf);
if ($written === -1 || $written === false) {
throw new TTransportException('TSocket: Could not write '.$written.' bytes '.
$this->host_.':'.$this->port_);
}
// determine how much of the buffer is left to write
$buf = substr($buf, $written);
} else if ($writable === 0) {
throw new TTransportException('TSocket: timed out writing '.strlen($buf).' bytes from '.
$this->host_.':'.$this->port_);
} else {
throw new TTransportException('TSocket: Could not write '.strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
}
}
Please anyone can put some light
It was the bug which i won't able to identify/ rectify. then i used an other library from http://www.codeforge.com/read/171085/smpp.php__html and it really saved me.

FFMpeg Out of sync audio/video in iOS application

The app saves the camera output into a mov. file, then turn it to flv format that sent by AVPacket to rtmp server.
It switch every time between two files, one is written by the camera output and the other one is sent.
My problem is that the audio/video is getting out of sync after a while.
The first buffer sent is allways 100% sync but after awhile it get messed.
I belive its a DTS-PTS problem..
if(isVideo)
{
packet->stream_index = VIDEO_STREAM;
packet->dts = packet->pts = videoPosition;
videoPosition += packet->duration = FLV_TIMEBASE * packet->duration * videoCodec->ticks_per_frame * videoCodec->time_base.num / videoCodec->time_base.den;
}
else
{
packet->stream_index = AUDIO_STREAM;
packet->dts = packet->pts = audioPosition;
audioPosition += packet->duration = FLV_TIMEBASE * packet->duration / audioRate;
//NSLog(#"audio position = %lld", audioPosition);
}
packet->pos = -1;
packet->convergence_duration = AV_NOPTS_VALUE;
// This sometimes fails without being a critical error, so no exception is raised
if((code = av_interleaved_write_frame(file, packet)))
{
NSLog(#"Streamer::Couldn't write frame");
}
av_free_packet(packet);
You can research this sample: http://unick-soft.ru/art/files/ffmpegEncoder-vs2008.zip
But this sample is for Windows.
In this sample I use pts only for audio stream:
if (pVideoCodec->coded_frame->pts != AV_NOPTS_VALUE)
{
pkt.pts = av_rescale_q(pVideoCodec->coded_frame->pts,
pVideoCodec->time_base, pVideoStream->time_base);
}
I was experiencing a similar issue when switching out the AVAssetWriters, and noticed that it went way if I only started using the new AVAssetWriter when I got a video sample
https://medium.com/#brandon.kobel/ios-seamless-video-chunks-4383a5a3a874

Adobe Air and Serial Port Communication with Serproxy/Thinkerproxy

I'm using serproxy / thinkerproxy for serial communication in a small Air app.
I have two hardware devices to test it. One is a barcode scanner, it works perfectly.
The other is a custom board. It's kind of working also. The problem is that the characters are unreadable. I think it's a problem of charset (not sure) so I tried something like this in the function that handles the ProgressEvent.SOCKET_DATA event:
var cs:Array = new Array( 'ISO-8859-1',
'ISO-8859-2',
'ISO-8859-3',
'ISO-8859-4',
'ISO-8859-5',
'ISO-8859-6',
'ISO-8859-7',
'ISO-8859-8',
'ISO-8859-9',
'ISO-8859-10',
'ISO-8859-11',
'ISO-8859-12',
'ISO-8859-13',
'ISO-8859-14',
'ISO-8859-15',
'ISO-8859-16',
'ISO-8859-17',
'ISO-8859-18',
'ISO-8859-19',
'ISO-8859-20',
'ASMO-708',
'DOS-720',
'x-mac-arabic',
'windows-1256',
'ibm775',
'windows-1257',
'ibm852',
'x-mac-ce',
'windows-1250',
'gb18030',
'EUC-CN',
'gb2312',
'gb18030',
'hz-gb-2312',
'x-mac-chinesesimp',
'big5',
'x-Chinese-CNS',
'x-Chinese-Eten',
'x-mac-chinesetrad',
'cp866',
'koi8-r',
'koi8-u',
'x-mac-greek',
'windows-1253',
'ibm869',
'DOS-862',
'iso-8859-8-i',
'x-mac-hebrew',
'windows-1255',
'x-EBCDIC-Arabic',
'x-EBCDIC-CyrillicRussian',
'x-EBCDIC-CyrillicSerbianBulgarian',
'x-EBCDIC-DenmarkNorway',
'x-ebcdic-denmarknorway-euro',
'x-EBCDIC-FinlandSweden',
'x-ebcdic-finlandsweden-euro',
'x-ebcdic-finlandsweden-euro',
'x-iscii-as',
'unicode',
'unicodeFFFE',
'utf-7',
'utf-8',
'us-ascii',
'windows-1258',
'x-IA5',
'Windows-1252'
);
for each(var csStr:String in cs){
var info:String = _socket.readMultiByte(_socket.bytesAvailable, csStr);
temp = csStr + ":" + info;
if(info.length > 0)
dispatchEvent(new TextEvent(EVENT_ON_DATA_RECEIVED, false, false, temp) );
}
The only value that contains a value is ISO-8859-1. and and it looks like this:
The custom board is supposed to send something like : 0x40
So, not sure what is the best approach here (I know there are more charset I can try). Any ideas?
Are you trying to guess unknown encoding? Look at raw bytes that board sends to check whether they are bit-shifted.
Have you checked your settings - I'd suspect differing settings for parity bit.