I want save data from LPVOID* to a file

Hi
I gess this one is easy but you know...
I'm using VC++.
I building a resource DLL. I've put a WAV file in it. I want to (when the dll is loaded) save this wav in a file in order to play it.
With the [Find | Load | Lock | Sizeof]Resource I got a LPVOID pointer to my dll data.
(now the question...)
How can I transform this data into a file ?
Here what I have tried :

ofstream  f("CreatedFile.wav", ios::out)
// I have also tried with ios::binary...
LPVOID pWav; //then I do the "stuff"
BYTE* tab = (BYTE *) pWav;
for (i = 0; i < sor; i++)
   f << tab[i];

The file I obtain with this is not to good size and do not contains "wav data".

I you think I should know something about getting the pointer to the wav, feel free to tell me.

Thanks

renam00
renam00Asked:
Who is Participating?
 
mikeblasConnect With a Mentor Commented:
What you want to do is possible and works fine, if you do it right. Instead of contuing this pattern of guessing at what's wrong with your code, I've posted a sample called WRITERES.ZIP which does exactly what you want.  It's at http://www.nwlink.com/~mikeblas/samples/ .  (Note that my samples will eventually move to http://www.mooseboy.com/ )

Please download it and run it and compare it to what you have written yourself.

..B ekiM
0
 
Gandalf32Commented:
instead of using an ofstream, you could use a CFile (if using MFC) or call OpenFile()

Then simply call (if using MFC)
Write(pWav, sor);

or:
Write(hFile, pWav, sor);
0
 
jkrCommented:
Try

ofstream  f("CreatedFile.wav", ios::binary)

f.write ( ( unsigned char*) pWav, sor);
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
chensuCommented:
The following is a function I use for my screen saver installation program. Modify it as needed.

BOOL CSInstallApp::SaveResourceToFile(LPCTSTR lpszSavePath, LPCTSTR lpszRes) const
{
    ASSERT(lpszSavePath != NULL);
    ASSERT(::AfxIsValidString(lpszSavePath));

    HRSRC hRsrc = ::FindResource(::AfxGetResourceHandle(), lpszRes, RT_RCDATA);
    if (hRsrc == NULL)
        return FALSE;

    DWORD dwSize = ::SizeofResource(::AfxGetResourceHandle(), hRsrc);
    HGLOBAL hResData = ::LoadResource(::AfxGetResourceHandle(), hRsrc);
    LPVOID lpData = ::LockResource(hResData);

    if (lpData == NULL)
        return FALSE;

    try
    {
        CFile file(lpszSavePath,
                   CFile::modeCreate | CFile::modeWrite |
                   CFile::shareExclusive);
        file.Write(lpData, dwSize);
    }
    catch (CFileException *pEx)
    {
        pEx->Delete();

        return FALSE;
    }

    return TRUE;
}
0
 
KangaRooCommented:
Fist off, I couldn't find any mention of audio resources in the online. Secondly, the layout of the the resource in memory is probably different from the layout in a disk based file. Bitmaps for instance, should have additional information when stored on disk. Secondly the online has a nasty remark with LockResource:
"Trying to lock a resource by using the handle returned by the FindResource or FindResourceEx function will not work. You will get back a value that is incorrect and points to random data."
0
 
PIGCommented:
If You want  not use MFC try with

FILE* file = fopen("CreatedFile.wav", "w");
fwrite(pWav, sor, sor, file);

You have not need of cast.
0
 
chensuCommented:
>I couldn't find any mention of audio resources in the online.

Playing WAVE Resources
http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/psdk/multimed/wave_3cfo.htm

>the layout of the the resource in memory is probably different from the layout in a disk based file.

The data keeps intact.

>the online has a nasty remark with LockResource "...".

What's wrong?
0
 
Gandalf32Commented:
Of course if you lock a resource using a handle returned by FindResource you will get into trouble. That's what the LoadResource function is for, to load the resource in memory. That is the handle that nust be used.
0
 
renam00Author Commented:
Thanks to everybody but...
I've tried (and re-tried) all of your solutions (exept the MFC-ones, but I think I'll have to try those too...) and  I still have an non-audio-wrong-file-size file.
I'll do more test monday with the CFile.

tanks

renam00
0
 
mikeblasCommented:
PIG> If You want  not use MFC try with

 PIG> FILE* file = fopen("CreatedFile.wav", "w");
 PIG> fwrite(pWav, sor, sor, file);  

Er, you want that to be "wb" and not "w", because a WAV file certainly has binary data in it, and shouldn't have cr/lf translation!

 renam00>  I still have an non-audio-wrong-file-size file.

What, specifically, is wrong with the file?  Too long?  Too short? By how many bytes?  What does it look like when you dump it?

..B ekiM
 
0
 
KangaRooCommented:
>> The data keeps intact.
Try it with bitmaps :)

If a file header is required, the data may be intact but in the wrong place in the file.
0
 
renam00Author Commented:
The file I use for my tests is : "The Microsoft Sound.wav" i.e. 135 876 Kb. The file I get is 102 016 Kb (and do not play). I get this with those instr.:

ofstream  f("CrFile.wav", ios::binary);
char* tab = (BYTE *) pWav;
for (i = 0; i < sor; i++)
  f << tab[i];

And with these one :
FILE* file = fopen("CrFile.wav", "bw");
fwrite(pWav, sor, sor, file);
fclose(file);              
I get a 0kb file ! (with "bw", "wb" and "w");

Of course, I get the "pWav" from LockResource (and not from the LoadResouce ... btw those are exacly the same pointer (!?))

I begin to think I can't do this in a simple way, what about you ?

renam00
0
 
PIGCommented:
It is work in app. If You pass instead NULL handle of Your DLL ithink that You have not a problem.

hrsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_WAV),"WAV");
hgb = (HGLOBAL)LoadResource(NULL,hrsrc);
size  = SizeofResource(NULL,hrsrc);
char* bufHGB = new char[size + 1];
memset(bufHGB, 0 , size + 1);
memcpy(bufHGB,(char*)LockResource(hgb),size);
UnlockResource(hgb);
FreeResource(hgb);
FILE* file = fopen("CreatedFile.wav", "w");
fwrite(bufHGB, size, size, file);
fclose(file);
ShellExecute(mHWND, "open", "CreatedFile.wav", NULL, ".\", SW_SHOWNORMAL);
0
 
mikeblasCommented:

 
The file I use for my tests is : "The Microsoft Sound.wav"

 > i.e. 135 876 Kb. The file I get is 102 016 Kb
 > (and do not play). I get this with those instr.:

Certainly, you must mean "b" and not "Kb", right? A file that's 135876 Kilobytes in size is very, very large! Presumably, you've checked in the debugger to make sure that sor shows 135876 bytes, right?

 > And with these one :
 > FILE* file = fopen("CrFile.wav", "bw");

This should be "wb", not "bw".

 > fwrite(pWav, sor, sor, file);

Wrong!  You need to code

   fwrite(pWav, 1, sor, file);

 > fclose(file);                
 > I get a 0kb file ! (with "bw", "wb" and "w");  

Please use "wb".


 > ofstream  f("CrFile.wav", ios::binary);
 > char* tab = (BYTE *) pWav;
 >for (i = 0; i < sor; i++)
     f << tab[i];

It's a mystery to me why you wouldn't use ofstream's write method, here. What you're doing is wrong and inefficient. Instead of that loop, you should code:

      f.write(pWav, sor);

..B ekiM


 
0
 
mikeblasCommented:
PIG> memset(bufHGB, 0 , size + 1);

There's absolutely no reason to make this call.

 PIG> fwrite(bufHGB, size, size, file);

Wow, PIG!  You made the exact same mistake as the person asking the question! This call causes you to write a file that's size*size bytes long; if the starting file is 135000 bytes, the file you're trying to write will be 18225000000 bytes in size. That's waaay too big!

Fortunately, fwrite() will cause an access violation before it writes a file that big, but...

..B ekiM
0
 
PIGCommented:
I am sorry it is cut/paste misake. But iti is work. Believe me!:-(
0
 
Gandalf32Commented:
Are you sure the data contained in the resource is correct. Maybe you are working with corrupt data to begin with.
0
 
mikeblasCommented:
> Maybe you are working with corrupt data to begin with.

Right. That's why we need to find out what's in the "sor" variable.

..B ekiM
0
 
renam00Author Commented:
Ok, you're right the file size I gave you is in byte...

The line : f.write(pWav, sor);
 
give me this error :
error C2664: 'class ostream &__thiscall ostream::write(const char *,int)' : cannot convert parameter 1 from 'void *' to 'const char *'
        Conversion from 'void*' to pointer to non-'void' requires an explicit cast

So I do the mandatory cast :
 f.write((char*)pWav, sor);
And I get a 96 920 byte file.
The file "f" is open with ios::binary.

The resource I'm (trying to) exporting is the right (sor is exacly the size of the original file in byte). And When I export the file from VisualStudio, I get exacly the file I want to...So the're must be a way.

Thanks, renam00

0
 
renam00Author Commented:
Guys, I understand I take lots of your time. So in a very generous move, I'm increasing the points to 150 !
0
 
renam00Author Commented:
Adjusted points to 150
0
 
Gandalf32Commented:
Try if this works:

hrsrc = FindResource(NULL,MAKEINTRESOURCE(IDR_WAV),"WAV");
hgb = (HGLOBAL)LoadResource(NULL,hrsrc);
int nSizeTest;
size  = SizeofResource(NULL,hrsrc);
HANDLE hFile = CreateFile("CreatedFile.wav", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
WriteFile(hFile, LockResource(hgb), size, &nSizeTest, NULL);
CloseHandle(hFile);
UnlockResource(hgb);
FreeResource(hgb);
ShellExecute(mHWND, "open", "CreatedFile.wav", NULL, ".\", SW_SHOWNORMAL);

You can compare nSizeTest to size and see if the bytes written are the same as the total bytes.
0
 
gambisticsCommented:
What's really the problem? You can also play a Soundfile which is placed in a dll or exe as resource without saving it in a wave-file. You can do it this way:
PlaySound(MAKEINTRESOURCE(MY_WAVE),NULL,SND_RESOURCE|SND_SYNC);

That's it. You just have to add #include <mmsystem.h>
and add winmm.lib to the linking options. The resource has to be from the type "WAVE" and the identifier is MY_WAVE. If you want to play the sound from a dll, which you load by LoadLibrary you can use the HMODULE handle you get instead of NULL in PlaySound.

I hope I could help you.
0
 
renam00Author Commented:
I'm pretty sure this is working fine, however It's not what's I'm looking for. Moreover I begin to take this problem "personal"... I can't believe it's that hard to save data to a file when I have a pointer to the data chunk !

renam
0
 
KangaRooCommented:
There are a number of assumptions in the procedure:

1. There is an object which can be considered as a pointer to some chunk of (wave) data
2. The size of this chunk is known
3. The layout of this chunk is identical to the layout of a WAV file

First of all, check the file that is written. Look at the file sizes, look with a hex viewer and compare it to the original (working) wave file. See if you can get any clues from this.
0
 
mikeblasCommented:
We know that all three assumptions are true because renam00 told us so--he added a WAV file to the resources of his DLL.

Data doesn't change format when it ends up in a resource. And, so, writing the resource out to a file, byte-by-byte, is just fine for this case.

..B ekiM
0
 
renam00Author Commented:
Mike , the description of the program WRITERES seems exacly what I<m looking for but the file is not there. (neiter at mooseboy.com) ... I'll try again later.
renam
0
 
mikeblasCommented:
OOps!  Fixed it.

..B ekiM
0
 
renam00Author Commented:
This is exacly what I was looking for ! I think the proplem that I have came from my LockRessource. I pass by a LPVOID and then I cast it to a BYTE*.
Anyway thanks a lot (and I'll bookmark your pages for further help...)
I'll give you the points by thank also to everybody who tried to help me.

renam
0
All Courses

From novice to tech pro — start learning today.