Use a stream as file? - c#

I am working on a telephony application using a third party library to send audio across the wire.
This third party library only accepts a very specific wav format, and takes in the file as a filename path on disk. Our current audio files are not in this format. I can use NAudio to convert from our legacy format to this new format.
However, I don't really want two sets of audio files floating around.
What I basically want to do is take an NAudio.WaveStream and be able to pass it to the third party library without writing it to disk, because the library takes a path to a filename. If performance is bad, I will be forced to have multiple sets of audio files, but I would like to avoid this. I am not even sure what terms to Google.
Is this a use case for memory mapped files?

Probably not worth your while but if you're absolutely stuck with the 3rd party app and are against writing to disk you could create a virtual drive using a library like http://dokan-dev.net/en/. You could intercept the requests from the 3rd party app and stream the converted files to it as they were needed.
Saying that, I would probably take the hit on writing the files to a normal drive.
If nothing else it'll kick off your searches.

Related

Mux Audio and Video in C#

I'm looking for a way to join separate audio and video streams into a single container.
Specifically I have VP8 video (webm container) and 16-bit PCM audio (wav container), which I'd like to combine into a Matroska container.
So far I can achieve this by saving the streams to files, and calling ffmpeg.exe by using the Process API which produces the result I need, but I'd prefer a solution that doesn't rely on saving the intermediate files to disk or requiring the ffmpeg.exe to be on the server. Any help much appreciated!
You would need a managed Matroska/WebM library, or at least a managed wrapper to some native library if you want to avoid the additional process. I'm not aware of any that exist/are up-to-date. I started writing one a few years ago but never completed it.
On launching the process, it's not actually necessary to "save files to disk", as you can use a named pipe, which "looks like a file on disk", but is in fact just an interface to some in-memory value - so you can share the memory directly with ffmpeg/mkvmerge, by passing them the name of the pipe in place of the regular filename. Can't help with not requiring the binary on the server though - other than just packaging it with your solution.

Create virtual file path from stream

I have a general question concerning C# & Windows API:
My task is loading a file from a document management system (DMS) and create a byte array from this file. From the developer of the DMS I got a dll which provides a method like this:
loadFile(int DocId, string PathToSaveFile);
Unfortunately the given dll does not provide me a method to deliver the requested file as a byte array or any kind of stream. Now my question, is it possible with C# to create some kind of virtual path which does actually not exists on secondary storage. Instead all bits and bytes written to this path are forwarded to me in a stream? The goal of my intention is to increase the performance as I don't have to write data to a hard drive.
I already searched a lot, but actually don't know the keywords I have to look for. Perhaps someone can give me a hint or just tell me that it is not possible at all.
It will depend somewhat on how the library will open the file and read the file. If it is using CreateFile then there is the potential that you could provide access via a named pipe. The path to a named pipe can be specified using \\.\pipe\PipeNameHere. In C# you can use NamedPipeServerStream.
However, I think the odds of the client application being compatible with this are relatively slim and would suggest creating a RAM drive that will be easier to implement and is more likely to work. A RAM drive will appear as a normal disk drive. You can save and load files to it, but it is all done in memory.

How to play non-PCM file or convert it to PCM on the fly ?

The following code works with some wav files, but with others I get, "InvalidOperationException was unhandled. Message=Sound API only supports playing PCM wave files."
var webClient = new WebClient();
webClient.DownloadFile(url, fileName);
var fileSound = new SoundPlayer(fileName);
fileSound.PlaySync();
Is there a way to programmatically check if a wav file is "bad" (not a PCM wave file) and then convert it as necessary?
What is odd is that the code works in the legacy Delphi app - all of the wav files play just fine. Here's the Delphi code:
filename := GetEnvironmentVariable('TEMP')+'\archieAndDingbat.wav';
URLDownloadToFile(nil, PChar(url), PChar(filename), 0, nil);
PlaySound(filename);
I looked at the properties of the two files in Explorer, and I see that there is, indeed, a difference. For the file that does play, its audio format is PCM; the one that won't play is CCITT u-Law.
So...I either need a way to convert from CCITT u-Law to PCM on the fly after downloading these files (they are download from an url and then played locally) OR perhaps a different way of playing these files than PlaySync() ...
Look at audiolab library from mitov. It works great
So, do you want to PLAY the file or CONVERT it ? What is the primary goal ? Do you play it as a prove you can convert it, or do you convert it because you don't know how to play not-converted file ?
http://www.catb.org/esr/faqs/smart-questions.html#goal
Your question's title claims "convert" but the body claims "Play"
This answer is about playing files.
You also may try to use FFDShow codecs directly without DirectX intermediate.
http://en.wikipedia.org/wiki/Libavcodec and http://libav.org/ and http://ffmpeg.org/ (they recently had a schism)
Googling for "FFDShow dotnet", "libav dotnet", "ffmpeg dotnet" shows a bunch of libraries to use it, such as
https://github.com/ermau/libav.net
Controlling ffdshow from .Net
Solid FFmpeg wrapper for C#/.NET
There is also BASS library. It is targeted as sound playback during gaming, so it probably has less range of formats and not much for re-coding. Still many music players are built on top of it. Some says it is the most simple API to use. So it worth considering. http://www.un4seen.com/
http://MediaInfo.sf.net is a library (native win32/win64 DLL) allowing to check most multimedia formats content.
I don't know if using tis C or C++ APis is easy from C# side.
The way to do it is to use newkie's code at: http://www.codeproject.com/Articles/175030/PlaySound-A-Better-Way-to-Play-Wav-Files-in-C?msg=4366037#xx4366037xx
In my case, at least, I had to change all of the lowercase x's to uppercase x's, though, to get it to work.

How to get sound portion of an MP4 (video file)?

I am developing a windows phone 7 application and it does video recording. I would like to get the sound portion of the video file (MP4) and do some enhancements on the sound. I believe sound is saved as AAC frames in MP4. (Right?) How can I extract sound of a videa MP4 file?
Since this is a video file, it can be huge file. So uploading to cloud and processing there is not a good option. Since this WP7 application I cannot use unmaged dlls :( Is there a way to do in pure C#? Any open source tools/samples?
Thanks!
MP4 is a container format and realistically the sound portion isn't always AAC. It could be MP3 or any other number of different audio formats. You may be thinking of M4A, which I believe requires either AAC or ALAC.
On the subject of audio extraction, it should be possible to extract the audio from an MP4 using just managed code. You'll have to read up on the MP4 format (here, for example - this question is also worth reading) and then search through the file for the location of the audio and then either copy it to its own buffer or do your manipulations in chunks. Even then, you'll have to be able to recognize when it isn't an audio format that your app won't support.
It's possible that there already exists a .net library that can do all of this but I don't know of any. It's probably not very popular because managed code is definitely not the best angle to approach this from, but considering this is Windows Phone, it is, as you noted, your only avenue of approach.
Good luck!

Best way to implement audio playback

I'm working on an application that will read in file paths and play audio files. I'm trying to keep this as simple as possible--by using existing codecs and free/open utilities. I'd like some suggestions on the best way to do this. I've had two ideas, both involving FFmpeg:
Create a simple GUI that allows the user to read pass in file(s) to be played, and then a ffplay.exe process is run in the background to play the file(s).
Go more in-depth by just using libavcodec and basing my project off the functionality available with that.
There are only a few main goals I have for this.
Be able to read in and play multiple files without breaks between them
Start playback at an arbitrary spot (based on a percent of total duration) within the track
Stop playback after an arbitrary amount of time, and move to the next track
Which of my two methods seem the most practical for this project? Is there a better--or perhaps less feature-intensive--alternative to FFmpeg that you would suggest.
This is for a Windows application written in C#.
Edit: One of the reasons that I started with FFmpeg is that it can handle many file types, notably MP3, AAC, Flac.
Edit2: If the use of libavcode.dll is the best option, it would also be helpful to get some info on implementing that in C#.
The BASS audio library has C# bindings and works very well with common audio formats (e.g. MP3) with plug-ins for other formats (e.g. AAC).
However, for commercial development, you require a license to use BASS.

Categories