renam00
asked on
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
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
Try
ofstream f("CreatedFile.w av", ios::binary)
f.write ( ( unsigned char*) pWav, sor);
ofstream f("CreatedFile.w
f.write ( ( unsigned char*) pWav, sor);
The following is a function I use for my screen saver installation program. Modify it as needed.
BOOL CSInstallApp::SaveResource ToFile(LPC TSTR lpszSavePath, LPCTSTR lpszRes) const
{
ASSERT(lpszSavePath != NULL);
ASSERT(::AfxIsValidString( lpszSavePa th));
HRSRC hRsrc = ::FindResource(::AfxGetRes ourceHandl e(), lpszRes, RT_RCDATA);
if (hRsrc == NULL)
return FALSE;
DWORD dwSize = ::SizeofResource(::AfxGetR esourceHan dle(), hRsrc);
HGLOBAL hResData = ::LoadResource(::AfxGetRes ourceHandl e(), 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;
}
BOOL CSInstallApp::SaveResource
{
ASSERT(lpszSavePath != NULL);
ASSERT(::AfxIsValidString(
HRSRC hRsrc = ::FindResource(::AfxGetRes
if (hRsrc == NULL)
return FALSE;
DWORD dwSize = ::SizeofResource(::AfxGetR
HGLOBAL hResData = ::LoadResource(::AfxGetRes
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;
}
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."
"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."
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.
FILE* file = fopen("CreatedFile.wav", "w");
fwrite(pWav, sor, sor, file);
You have not need of cast.
>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?
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?
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.
ASKER
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
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
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
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
>> 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.
Try it with bitmaps :)
If a file header is required, the data may be intact but in the wrong place in the file.
ASKER
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
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
It is work in app. If You pass instead NULL handle of Your DLL ithink that You have not a problem.
hrsrc = FindResource(NULL,MAKEINTR ESOURCE(ID R_WAV),"WA V");
hgb = (HGLOBAL)LoadResource(NULL ,hrsrc);
size = SizeofResource(NULL,hrsrc) ;
char* bufHGB = new char[size + 1];
memset(bufHGB, 0 , size + 1);
memcpy(bufHGB,(char*)LockR esource(hg b),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);
hrsrc = FindResource(NULL,MAKEINTR
hgb = (HGLOBAL)LoadResource(NULL
size = SizeofResource(NULL,hrsrc)
char* bufHGB = new char[size + 1];
memset(bufHGB, 0 , size + 1);
memcpy(bufHGB,(char*)LockR
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);
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
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
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
I am sorry it is cut/paste misake. But iti is work. Believe me!:-(
Are you sure the data contained in the resource is correct. Maybe you are working with corrupt data to begin with.
> 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
Right. That's why we need to find out what's in the "sor" variable.
..B ekiM
ASKER
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
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
ASKER
Guys, I understand I take lots of your time. So in a very generous move, I'm increasing the points to 150 !
ASKER
Adjusted points to 150
Try if this works:
hrsrc = FindResource(NULL,MAKEINTR ESOURCE(ID R_WAV),"WA V");
hgb = (HGLOBAL)LoadResource(NULL ,hrsrc);
int nSizeTest;
size = SizeofResource(NULL,hrsrc) ;
HANDLE hFile = CreateFile("CreatedFile.wa v", 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.
hrsrc = FindResource(NULL,MAKEINTR
hgb = (HGLOBAL)LoadResource(NULL
int nSizeTest;
size = SizeofResource(NULL,hrsrc)
HANDLE hFile = CreateFile("CreatedFile.wa
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.
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),N ULL,SND_RE SOURCE|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.
PlaySound(MAKEINTRESOURCE(
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.
ASKER
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
renam
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
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
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
ASKER
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
renam
OOps! Fixed it.
..B ekiM
..B ekiM
ASKER
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
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
Then simply call (if using MFC)
Write(pWav, sor);
or:
Write(hFile, pWav, sor);