Convert g722 audio to WAV using NAudio - naudio

I'm starting to write a Windows Service that will convert G.722 audio files into WAV files and I'm planning on using the NAudio library.
After looking at the NAudio demos, I've found that I will need to use the G722Codec to decode the audio data from the file but I'm having trouble figuring out how to read the G722 file. Which reader should I use?\
The G722 files are 7 kHz.
I'm working my way through the Pluralsight course for NAudio but it would be great to get a small code sample.

I got it working with the RawSourceWaveStreambut then tried to simply read the bytes of the file, decode using the G722 Codec and write the bytes out to a wave file. It worked.
private readonly G722CodecState _state = new G722CodecState(64000, G722Flags.SampleRate8000);
private readonly G722Codec _codec = new G722Codec();
private readonly WaveFormat _waveFormat = new WaveFormat(8000, 1);
public MainWindow()
{
InitializeComponent();
var data = File.ReadAllBytes(#"C:\Recordings\000-06Z_chunk00000.g722");
var output = Decode(data, 0, data.Length);
using (WaveFileWriter waveFileWriter = new WaveFileWriter(#"C:\Recordings\000-06Z_chunk00000.wav", _waveFormat))
{
waveFileWriter.Write(output, 0, output.Length);
}
}
private byte[] Decode(byte[] data, int offset, int length)
{
if (offset != 0)
{
throw new ArgumentException("G722 does not yet support non-zero offsets");
}
int decodedLength = length * 4;
var outputBuffer = new byte[decodedLength];
var wb = new WaveBuffer(outputBuffer);
int decoded = _codec.Decode(_state, wb.ShortBuffer, data, length);
return outputBuffer;
}

Related

Custom USQL extractor - How to process more than 4 MB json object

We use a custom USQL extractor to flatten a json structure. The below sample code works fine if line(json object) of json is less than 4 MB. If the line size is above 4 MB, then we get error "A record in the input file is longer than 4194304 bytes." The similar code is tried in C# stand alone application for lines higher than 4 MB, it works fine. Do we have any restriction on json size with usql custom extractor? How do we handle json messages with size more than 4 MB?
The error is thrown from the highlighted line in below code
string line = lineReader.ReadToEnd();
Custom extractor Sample code
using Microsoft.Analytics.Interfaces;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.Analytics.Types.Sql;
using Newtonsoft.Json;
namespace Company.DataLakeAnalytics
{
[SqlUserDefinedExtractor(AtomicFileProcessing = false)]
public class CustomJSONExtractor : IExtractor
{
private readonly Encoding _encoding;
private readonly byte[] _row_delim;
private string DELIMITER = "~";
public CustomJSONExtractor(Encoding encoding = null, string row_delim = "\r\n")
{
_encoding = Encoding.UTF8;
_row_delim = _encoding.GetBytes(row_delim);
}
//Every json line in the raw file is transformed to a flat structure
public override IEnumerable Extract(IUnstructuredReader input, IUpdatableRow output)
{
//Read the input line by line
foreach (Stream current in input.Split(_row_delim))
{
using (StreamReader lineReader = new StreamReader(current, this._encoding))
{
//reads the entire line
string line = lineReader.ReadToEnd();
//break the line to multiple variables
output.Set(1, "A~1");
yield return output.AsReadOnly();
}
}
}
}
}
sample USQL code
DECLARE #INPUT_FILE="sample-data.txt";
#jsonDatafile = EXTRACT key string, jsonObjStr string FROM #INPUT_FILE USING new Damen.DataLakeAnalytics.CustomJSONExtractor(null,row_delim:"\n") ;
#dataJsonObject = SELECT jsonObjStr AS rawData FROM #dataAsStrings;
OUTPUT #dataJsonObject TO #flattenedOutputFile USING Outputters.Text(outputHeader:false,quoting: false,delimiter:'~');
The max size is indeed 4MB for rows and 128KB for a string. What you can do is using the solution provided in this similar answer:
What is the maximum allowed size for String in U-SQL?

What is the RabbitMQ message max size can stored?

We are uploading 23 mb text file RabbitMQ. We will convert that file to filestream and then we will bind that message to JSONObject.
var path = Server.MapPath("~/App_Data/" + fileName);
var excelFile = new FileInfo(path);
FileStream stream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read);
// Added Code for CommandComponent changes Start
byte[] fileMessage = new byte[stream.Length];
stream.Read(fileMessage, 0, fileMessage.Length);
stream.Close();
TempData["FileMessage"] = fileMessage;
TempData["FileType"] = fileType;
System.IO.File.Delete(path);
// Added Code for CommandComponent changes End
return Json(new { Result = true }, JsonRequestBehavior.AllowGet);
By AMQP specification there is not limit. The body is a buffer where you can put what you prefer.
Obviously there is the network between your application and RabbitMQ and you can't send a big-file just with a simple send.
you have to implement some kind of the streaming

Differences between emulator's SD Card and real phone's SD Card

My target is to read a file in SD Card and then process it in my program.
All THINGS WORKS FINE IN ANDROID EMULATOR!!!!
Unfortunately, when I work on my smartphone it didn't work at all!
public void receiveVideoRawData() throws IOException{
byte[] buf_rcv = new byte[153600];
File file = new File("/mnt/sdcard/Bluetooth/ardrone.raw");
ByteArrayOutputStream ous = new ByteArrayOutputStream();
InputStream ios = new FileInputStream(file);
int read = 0;
while ( (read = ios.read(buf_rcv)) != -1 ) {
ous.write(buf_rcv, 0, read);
}
ous.close();
ios.close();
ReadRawFileImage readMyRawData=new ReadRawFileImage();
image = readMyRawData.readUINT_RGBImage(buf_rcv);
File outputfile = new File("/mnt/sdcard/Bluetooth/ardroneCVT1.jpg");
OutputStream _outStream = new FileOutputStream(outputfile);
Bitmap pBitmap = image ;
pBitmap.compress(Bitmap.CompressFormat.JPEG, 90, _outStream);
_outStream.flush();
_outStream.close();
}
}
You are not supposed to hardcode the path to external storage directly because this may differ between devices, instead use getExternalStorageDirectory():
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath(), filename);

Uploading to an FTP server

I am working on a tiny tiny application that just uploads a file to the FTP server. I have reviewed my code, but I am quite unable to locate the problem. Here is the code,
#include "stdafx.h"
using namespace System;
#include "iostream"
#include <conio.h>
using namespace System;
void UploadFiles(String ^_FileName, String ^_UploadPath, String ^_FTPUser, String ^_FTPPass);
int main ()
{
// Upload file using FTP
UploadFiles("c:\\test.html", "ftp://playbabe.tk/public_html/test.html", "xxxxxx", "xxxxxx");
return 0;
}
void UploadFiles(System::String ^_FileName, System::String ^_UploadPath, System::String ^_FTPUser, System::String ^_FTPPass)
{
System::IO::FileInfo ^_FileInfo = gcnew System::IO::FileInfo(_FileName);
// Create FtpWebRequest object from the Uri provided
System::Net::FtpWebRequest ^_FtpWebRequest = safe_cast<System::Net::FtpWebRequest^>(System::Net::FtpWebRequest::Create(gcnew Uri(_UploadPath)));
// Provide the WebPermission Credintials
_FtpWebRequest->Credentials = gcnew System::Net::NetworkCredential(_FTPUser, _FTPPass);
// By default KeepAlive is true, where the control connection is not closed
// after a command is executed.
_FtpWebRequest->KeepAlive = false;
// set timeout for 20 seconds
_FtpWebRequest->Timeout = 20000;
// Specify the command to be executed.
_FtpWebRequest->Method =System::Net::WebRequestMethods::Ftp.UploadFile;
// Specify the data transfer type.
_FtpWebRequest->UseBinary = true;
// Notify the server about the size of the uploaded file
_FtpWebRequest->ContentLength = _FileInfo->Length;
// The buffer size is set to 2kb
int buffLength = 2048;
array<System::Byte> ^buff = gcnew array<System::Byte>(buffLength);
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
System::IO::FileStream ^_FileStream = _FileInfo->OpenRead();
try
{
// Stream to which the file to be upload is written
System::IO::Stream ^_Stream = _FtpWebRequest->GetRequestStream();
// Read from the file stream 2kb at a time
int contentLen = _FileStream->Read(buff, 0, buffLength);
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
_Stream->Write(buff, 0, contentLen);
contentLen = _FileStream->Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
_Stream->Close();
delete _Stream;
_FileStream->Close();
delete _FileStream;
}
catch (Exception ^ex)
{
//MessageBox::Show(ex->Message, "Upload Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
std::cout<<"error";
}
getch();
}
It gives two errors in Visual C++ 2010 Express,
Error 1 error C2275: 'System::Net::WebRequestMethods::Ftp' : illegal use of this type as an expression C:\Users\Me\documents\visual studio 2010\Projects\test1\test1\test1.cpp 70
Error 2 error C2228: left of '.UploadFile' must have class/struct/union C:\Users\Me\documents\visual studio 2010\Projects\test1\test1\test1.cpp 70
I am not sure what is going wrong here.
I don't know C++/CLI, but the following statement is certainly wrong:
_FtpWebRequest->Method = System::Net::WebRequestMethods::Ftp.UploadFile;
System::Net::WebRequestMethods::Ftp is a type and, as the error message indicates (you could have given us the line number!) you're trying to use it as an expression.
Are you trying to obtain a pointer to a static member function?
Did you thus mean the following?
_FtpWebRequest->Method = System::Net::WebRequestMethods::Ftp::UploadFile;

SlimDX Recording(OK) then playing (Problem!)

I'm currently getting a float array using directsound to record audio.
Now I would like to play that float array using XAudio2 (SlimDX also), but I'm not sure what to do since the sample example from SlimDX plays a .wav file.
here is how they do this:
XAudio2 device = new XAudio2();
MasteringVoice masteringVoice = new MasteringVoice(device);
var s = System.IO.File.OpenRead(fileName);
WaveStream stream = new WaveStream(s);
s.Close();
AudioBuffer buffer = new AudioBuffer();
buffer.AudioData = stream;
buffer.AudioBytes = (int)stream.Length;
buffer.Flags = BufferFlags.EndOfStream;
SourceVoice sourceVoice = new SourceVoice(device, stream.Format);
sourceVoice.SubmitSourceBuffer(buffer);
sourceVoice.Start();
// loop until the sound is done playing
while (sourceVoice.State.BuffersQueued > 0)
{
if (GetAsyncKeyState(VK_ESCAPE) != 0)
break;
Thread.Sleep(10);
}
// wait until the escape key is released
while (GetAsyncKeyState(VK_ESCAPE) != 0)
Thread.Sleep(10);
// cleanup the voice
buffer.Dispose();
sourceVoice.Dispose();
stream.Dispose();
Basically, what I would like to know is how to play a float array using slimDX?
Thanks in advance
I'm not an expert on audio stuff, but I do know that you can create a WaveFormat of IeeeFloat. Fill in all the other information, and then write your data to a DataStream and give that to the AudioBuffer. Then you can call Submit as normal.