Decoding ogg files to wav in WP8 - c#

I want to convert ogg file to wav and then play it on wp8 devives.
I've already checked many solutions but none of them worked. This looks promising but something doesn't work:
string _audioPath = "/SomeProject;component/Sounds/a_dog.ogg";
var stream = Application.GetResourceStream(new Uri(_audioPath, UriKind.Relative)).Stream;
using (var vorbis = new NVorbis.VorbisReader(stream, true))
{
float[] buf = new float[vorbis.TotalSamples];
vorbis.ReadSamples(buf, 0, (int)vorbis.TotalSamples);
}
When I execute it I see FileNotFoundException at VorbisReader contruction. I also checked if stream is readable and it is. I was able to get the file content using Read method.
Do you have any ideas why it doesn't work? Maybe you know some other library for wp8 which can decode ogg files?
[EDIT] I downloaded source code of NVorbis and used it directly from my project, and when i do this I don't get any FileNotFoundExceptions and everything seems to work. Maybe this exception is caused by missing library? I've got NVorbis reference added...

I think you are running into the same issue as this guy. Short version: I believe your Pack URI should be "pack://application:,,,/SomeProject;Component/Sounds/a_dog.ogg". NVorbis is not actually throwing the exception itself, but is instead causing the resource stream to do so...

Related

Cannot find a way to make tessnet2 work

I have created a console application.
Added a reference to tessnet2_32.
Ocr ocr = new Ocr();
using (Bitmap bmp = new Bitmap(filename))
{
tessnet2.Tesseract tessocr = new tessnet2.Tesseract();
tessocr.Init(#"C:\temp\tessdata", "eng", false);
...
I also tried changing "C:\temp\tessdata" to
C:\work\ConsoleApplication3\ConsoleApplication3
C:\work\ConsoleApplication3\ConsoleApplication3\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\bin\debug
C:\work\ConsoleApplication3\ConsoleApplication3\bin
C:\work\ConsoleApplication3\ConsoleApplication3\bin\debug\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\bin\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\debug\tessdata
C:\work\ConsoleApplication3\tessdata
C:\work\ConsoleApplication3\
The tessdata folder itself contained 9 failed and was added to all of these locations:
eng.cube.bigrams
eng.cube.fold
eng.cube.lm
eng.cube.bigrams
eng.cube.params
eng.cube.size
eng.cube.word-freq
eng.tesseract_cube.nn
eng.traineddata
But it just always exists at that .Init line with a message:
The file 'z:\dev\interne\cs\tesseract-ocr-svn\dotnet\tessnet2.cpp' does not exist.
I cannot imagine why it is trying to access some Z disk while I only have C. Or I just completely misunderstand the error.
Can someone be kind enough to post step by step telling what to do and/or what I am doing wrong? I feel completely lost even after reading 30+ google links.
You use the wrong version of language data file; what you have is for Tesseract 3.0x. tessnet2 is .NET wrapper for Tesseract 2.04, so you will need to load compatible data file.
Try download tesseract-2.00.eng.tar.gz from https://sourceforge.net/projects/tesseract-ocr-alt/files/.

File IO in Windows 8

I have been trying to read a file, and calculate the hash of the contents to find duplicates. The problem is that in Windows 8 (or WinRT or windows store application or however it is called, I'm completely confused), System.IO has been replaced with Windows.Storage, which behaves differently, and is very confusing. The official documentation is not useful at all.
First I need to get a StorageFile object, which in my case, I get from browsing a folder from a file picker:
var picker = new Windows.Storage.Pickers.FolderPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;
picker.FileTypeFilter.Add("*");
var folder = await picker.PickSingleFolderAsync();
var files = await folder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName);
Now in files I have the list of files I need to index. Next, I need to open that file:
foreach (StorageFile file in files)
{
var filestream = file.OpenAsync(Windows.Storage.FileAccessMode.Read);
Now is the most confusing part: getting the data from the file. The documentation was useless, and I couldn't find any code example. Apparently, Microsoft thought getting pictures from the camera is more important than opening a file.
The file stream has a member ReadAsync which I think reads the data. This method needs a buffer as a parameter and returns another buffer (???). So I create a buffer:
var buffer = new Windows.Storage.Streams.Buffer(1024 * 1024 * 10); // 10 mb should be enough for an mp3
var resultbuffer = await filestream.ReadAsync(buffer, 1024 * 1024 * 10, Windows.Storage.Streams.InputStreamOptions.ReadAhead);
I am wondering... what happens if the file doesn't have enough bytes? I haven't seen any info in the documentation.
Now I need to calculate the hash for this file. To do that, I need to create an algorithm object...
var alg = Windows.Security.Criptography.Core.HashAlgorithmProvider.OpenAlgorithm("md5");
var hashbuff = alg.HashData(resultbuffer);
// Cleanup
filestream.Dispose();
I also considered reading the file in chunks, but how can I calculate the hash like that? I looked everywhere in the documentation and found nothing about this. Could it be the CryptographicHash class type with it's 'append' method?
Now I have another issue. How can I get the data from that weird buffer thing to a byte array? The IBuffer class doesn't have any 'GetData' member, and the documentation, again, is useless.
So all I could do now is wonder about the mysteries of the universe...
// ???
}
So the question is... how can I do this? I am completely confused, and I wonder why did Microsoft choose to make reading a file so... so... so... impossible! Even in Assembly I could figure it out easier than.... this thing.
WinRT or Windows Runtime should not be confused with .NET as it is not .NET. WinRT has access to only a subset of the Win32 API but not to everything like the .NET is. Here is a pretty good article on what are the rules and restrictions in WinRT.
The WinRT in general does not have access to the file system. It works with capabilities and you can allow file access capability but this would restrict your app's access only to certain areas. Here is a good example of how do to file access via WinRT.

Apparent bug in Silverlight 4 Resource Streams or Json Xml Dictionary Reader

I've encountered what feels like a bug in Silverlight 4, because I can't find anything in the MSDN docs that says this shouldn't work, but it's crashing my application:
var info = Application.GetResourceStream(DocumentUri);
using (var stream = info.Stream)
using (var reader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max))
{
// Content doesn't matter, could be empty.
}
The end result of this block is a NotSupportedException from MS.Internal.InternalMemoryStream.Flush. Stream.Flush is a bit under documented, but it would imply that the enclosing reader should call Stream.CanSeek and/or Stream.CanWrite before calling Flush.
If anyone else has run into this issue, I'd appreciate any references you have.
EDIT: I've uploaded a minimal project that's crashing here: http://sdrv.ms/x9GLNR
I've now been able to reproduce your error. I agree with you in that this is a bug in Silverlight. Quite simply, there's no other reasonable explanation for a NotSupportedException being thrown from deep within classes under the MS or System namespaces.
Nonetheless, I found that your code worked if I changed the Build Action of your document.json file to Resource instead of Content, and changed the URI used to read the file as follows:
var info = Application.GetResourceStream(new Uri("/HelloApp;component/document.json", UriKind.Relative));

can't Get stream of mp3 file in wp7 application

i'm building a wp7 application for a game using silverlight & XNA
i have an mp3 file called "Punch1.mp3" (Build action : resource ) stored inside a folder called "SoundEffects" inside the project folder
and i want to play the file using this code
StreamResourceInfo info;
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
punch is defined in the code here :
public static SoundEffect punch1;
the problem is that it raises a nullreference exception in the third line claiming that info is null
and that's true in the debugging mode , i found that the resource stream info is null
i think this is because the it can't read the file although the uri is correct
You can try two things
- Clean and rebuild the project
- Try appending project name in URI "/PhoneApp1;component/SoundEffects/Punch.mp3"
Since you're using the XNA assembly anyway, you can use TitleContainer.OpenStream instead (with a relative URI) and have the audio file build set as Content.
I agree with Haris Haqsan that your URI string is bad.
Uri myuri = new Uri("/PhoneBoxing;component/SoundEffects/Punch1.mp3", UriKind.Relative);
But you should also consider switching to using content files instead embedding them at resources as it can help your application start up time. Depending on the amount of files we are talking about, it can make a big difference.
Set your Build Action to content and your code should look like:
FileStream stream = new FileStream("/SoundEffects/Punch1.mp3", FileMode.Open, FileAccess.Read);
in the following code :
Uri myuri = new Uri("/SoundEffects/Punch1.mp3", UriKind.Relative);
info = App.GetResourceStream (myuri);
punch1 = SoundEffect.FromStream(info.Stream ) ;
SoundEffect.FromStream() expects a wave file stream not an MP3 as shown here : http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.audio.soundeffect.fromstream.aspx .
so solution to find a mp3 > wav convertor or just find another way to load mp3 to WP7
considering the picture this is normal URI in normal cases can't evaluate expression of isfile .
I was experiencing the same issue on my machine, the InvalidOperationException is a little confusing. All I had to do was re-encode the wav file to the specifications listed on MSDN.
After I did that, it worked perfectly.

What is the best way to determine if WPF can load an image file?

Is there any way to determine if WPF will be able to load an image file without attempting to construct a BitmapImage and catching the exception if it fails?
I'm creating an image browser that attempts to show previews of all the images on a removable drive. There could be a lot of files that aren't images and catching an exception for each one seems somewhat inefficient but I can't think of a way that isn't prone to error.
Any suggestions?
Thanks,
Mark
I recently asked a very similar question and got an excellent answer here.
Basically, you find all the codecs on a user's machine which BitmapImage can use to open various image formats. From these codecs, you build a list of the file extensions that these can open.
Then, when your program tries to open a file, check the extension of that file against this list.
WPF uses WIC to handle images. It contains a core set of codecs that handle common image formats, and I believe you can hard-code the extensions of these from here. WIC is also extensible, so, for example, camera manufacturers can incorporate custom image formats into WIC. The code in the answer above searches your computer for these extra codecs, and provides the corresponding file extensions for these.
This method assumes that the file extensions are correct for a file. This is usually a fair assumption in most cases though - even Windows Explorer is happy to assume this. Still, I would wrap the BitmapImage construction in a try-catch, should the odd rogue file appear where the extension appears to be an image, but it still won't open.
EDIT: I have also wrapped this functionality into a class you can copy-paste into your own project here.
WPF uses WIC, what you want is demonstrated in C++ in the MSDN but the decompiled sources of the framework show that IWICImagingFactory::CreateComponentEnumerator isn't even exposed in the internal class of the framework.
Your best solution would be to create a static list of extensions supported (The formats that WIC support out-of-the box are on MSDN) and use it.
First, you can try to check the image file extension to verify if your application is able to read it.
Then you have to read Validate image from file in C#
and here Getting image dimensions without reading the entire file
I found the answer to this in another question on StackOverflow, but I don't remember the question I got it from. In any event, here's some code I wrote based on what one of the answerws to that question said:
public static string GetImageFileExtension( byte[] plateImage ) {
string imageFileExtension = String.Empty;
using ( Stream ms = new MemoryStream( plateImage ) ) {
BitmapDecoder decoder = BitmapDecoder.Create( ms, BitmapCreateOptions.None, BitmapCacheOption.None );
if ( decoder is BmpBitmapDecoder ) imageFileExtension = ".bmp";
else if ( decoder is GifBitmapDecoder ) imageFileExtension = ".gif";
else if ( decoder is IconBitmapDecoder ) imageFileExtension = ".ico";
else if ( decoder is JpegBitmapDecoder ) imageFileExtension = ".jpg";
else if ( decoder is PngBitmapDecoder ) imageFileExtension = ".png";
else if ( decoder is TiffBitmapDecoder ) imageFileExtension = ".tiff";
else if ( decoder is WmpBitmapDecoder ) imageFileExtension = ".wmp";
}
return imageFileExtension;
}
This works well in production code.

Categories