Thread: Compression/Decompression Wave File and MP3

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    28

    Compression/Decompression Wave File and MP3

    Hello, everybody. Sorry to disturb you all.

    Currently, I have a speech recording and playback software developed by Microsoft Visual C++ 6.0. The software is used to train children with speech problem and scores will be calculated and showed at the end of each practice session. The software is able to record and playback real-time.

    Children use this software at home and save their practice records in a single floppy disk. Then, children will bring the floppy disk with practice records inside when they return to our centre. There are 20 wave files that must be saved in a single floppy disk. Due to space insifficiency, one floppy disk is 1.44M in capacity.
    Total size of 20 wave files = 20*188k = 3,760,000 bytes
    Total floppy disk needed = (3,760,000)/1,440,000 = 2.6 floppy disks
    But, I must save all the 20 wave files into a single floppy disk

    Our problem is we are not able to save all 20 wave files in a single floppy disk. We cant afford a CD-RW for each child and we must use floppy disk. The solution is we have to compress the wave file to save the files in a floppy and decompress the files back to wave file in order to listen to how the children practice at home.

    I am totally new to this as the software is written by one of my previous friend who worked together with me in a voluntary speech rehabilitation centre. We need this software to train children in the centre. I work part time there.

    But, my problem is how to call any CODEC dll into correct place into my current project platform without causing any bugs? Please forgive me if I have asked a very silly question, I am sorry. After I have added the cpp and h files into my current project paltform, I dont know what should I do next.

    My final destination is to save all 20 wave files in a single floppy disk. I didnt restrict that I must use compression/decompression methods but I dont know what else should I use.

    Hope you can give me some guidances on how to do it or you please link me to pages that help me to do so. I promise I can learn as independent as possible but I really need your guidance at this very beginning, please.

    Please, I really appreciate all your help.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Convert your wavs to mp3, which is a much more compact audio format.
    http://www.google.com/search?q=wav+to+mp3

    Or maybe this
    http://technology.niagarac.on.ca/cou...ileFormat.html
    Use this to drop the bit rate, number of audio channels or whatever else you can get rid of to reduce the file size.
    Speech doesn't need stereo, and it doesn't need a particularly high bit rate either.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    Maybe you should post a question on the Windows forum. I've tried to find out how to "talk to" a CODEC, and I never found a complete reference. But, I did find some sample code in an SDK... I think it was the DirectX SDK.

    Clearly, there is a standardized Windows-CODEC interface, because most audio programs that can query a CODEC's capabilities.

    I just found this at MSDN.

    There is a ton of documentation in the SDKs, and on MSDN... if you can wade through it and find what you're looking for. You might try downloading the Platform SDK, the Media Format SDK, and the DirectX SDK. The description of the Windows Media SDK seems to imply that it covers only the Windows Media Format (WMA and WMV), but I wonder if you use other CODECs in the same way.

    I am totally new to this as the software is written by one of my previous friend...
    Are you a programmer? If you have never programmed before, you will need some help. (This stuff is not for beginners, and most experienced programmers would have to do some research.) You will also need the program's source code (the C or CPP files) you cannot edit the execuatable (EXE) files.
    Last edited by DougDbug; 04-20-2006 at 05:45 PM.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by Salem
    Convert your wavs to mp3, which is a much more compact audio format.
    http://www.google.com/search?q=wav+to+mp3

    Or maybe this
    http://technology.niagarac.on.ca/cou...ileFormat.html
    Use this to drop the bit rate, number of audio channels or whatever else you can get rid of to reduce the file size.
    Speech doesn't need stereo, and it doesn't need a particularly high bit rate either.

    Hi, Salem, thank you very much for your post, appreciate.
    I cant use third-party software that is 'outside' of my software project platform. I need to call the CODEC dll from my software.
    My problem is I dont know how to call the dll from my software.

    Can you please link me to the page that got tutorial on how to link the dll from my software?
    For your information, I didnt use stereo. I used mono, 16kHz, 16 bits.

    In order to reach my purpose to save all wave files in single floppy, I need to reduce sampling rate from 16k to 8k and ALSO reduce the 16 bits to 8 bits. But, I dont know by reducing 16 bit to 8 bit will influence much on the quantization level and thus influence much on the scores pratice by children.
    That's why I think compression is the only solution for me to save all 20 wave files into single floppy disk.
    Please correct me if I am wrong.

    Can you please link me to the page with tutorials or details on how to call CODEC dll from my software its own? Please really need your help, please, Salem

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by DougDbug
    Maybe you should post a question on the Windows forum. I've tried to find out how to "talk to" a CODEC, and I never found a complete reference. But, I did find some sample code in an SDK... I think it was the DirectX SDK.

    Clearly, there is a standardized Windows-CODEC interface, because most audio programs that can query a CODEC's capabilities.

    I just found this at MSDN.

    There is a ton of documentation in the SDKs, and on MSDN... if you can wade through it and find what you're looking for. You might try downloading the Platform SDK, the Media Format SDK, and the DirectX SDK. The description of the Windows Media SDK seems to imply that it covers only the Windows Media Format (WMA and WMV), but I wonder if you use other CODECs in the same way.


    Are you a programmer? If you have never programmed before, you will need some help. (This stuff is not for beginners, and most experienced programmers would have to do some research.) You will also need the program's source code (the C or CPP files) you cannot edit the execuatable (EXE) files.
    Hi, DougDbug, thanks a lot for replying my post, thanks.
    For your information, I am quite new to programming, but I have learnt the program codes done my friends before, so I think I understand the program flows so far. (if I am not mistake)

    I am so afraid, you mean so far nobody could manage to 'talk' to a codec?

    When you said "Platform SDK, the Media Format SDK, and the DirectX SDK", do you mean I have to use three of them or only one of them? Could you please explain?

    Regarding your last paragraph, I have found several complete source codes from many websites including zip/unzipp and codec, but I just dont know how to call the CODEC dll from my software. I couldnt find a tutorial or details on that.

    Can you please link me to the pages that can guide me? Or if you know how to call with source codes available, can you please teach me? I could attach them here anytime if you want. I promise I will learn as independent as possible, I wont disturb you much, please. I really need some guidance and helps at this beginning stage, please

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I just dont know how to call the CODEC dll from my software.
    I think it's more like instantiating the codec by calling the COM CoCreateInstance to create a codec object.

    Codec programming guide

    BTW, is this application being developed and used by a not-for-profit organization?

  7. #7
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    am so afraid, you mean so far nobody could manage to 'talk' to a codec?
    No! Almost all audio programs (WAV editors, etc.) can interface to any codec. It's just that I don't know how, and I haven't found a reference yet. (Maybe Bob's reference is what I was looking for! )

    When you said "Platform SDK, the Media Format SDK, and the DirectX SDK", do you mean I have to use three of them or only one of them? Could you please explain?
    Sorry, I don't know. I never did find that particular information. I have the Platform SDK and the DirectX SDK. I haven't read everything in them. There is a surprising amount of documentation in the SDKs. But, it seems to be organized more like a tutorial than a reference.... I didn't see organized groups of functions that I could browse through to see which ones I need etc. Hopefully, there are others here who can give you better guidance... I've been fooling around with Windows programming for quite a while, but I'm still just a beginner.

    P.S. I looks like Bob's MSDN link only covers the Windows Media Format... I don't know how much of that applies to other codecs (MP3, etc.). Then again, WMA files might work for you.

    Ooooh! I found something very interesting on MSDN: Using CODEDs to Compress Wave Audio. I hope it's not too outdated... It references Win95 and WinNT.

    P.P.S. Yes, It's outdated... The Platform SDK says that the ACM codecs are "deprecated". It says there are 3 types of codecs:

    ACM (and VCM)
    Direct Show Filters
    DirectX Media Objects (DMOs)

    I found that in the DirectX section of the Platform SDK, and I assume that it's duplicated in the DirectX SDK.
    Last edited by DougDbug; 04-22-2006 at 12:36 PM.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by BobS0327
    I think it's more like instantiating the codec by calling the COM CoCreateInstance to create a codec object.

    Codec programming guide

    BTW, is this application being developed and used by a not-for-profit organization?

    Hi, BobS0327, thank you very much for your reply.

    For your information, this software will be used for children with speech inability or speech problem in our speech rehabilitation centre. I work part time there to help with the rehabilitation process.

    I am sorry, I dont understand. Could you please elaborate on the "COM CoCreateInstance" that you stated above?

    Please, I really need your help in this very beginning. I promised I will be as independent as possible, please.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by DougDbug
    No! Almost all audio programs (WAV editors, etc.) can interface to any codec. It's just that I don't know how, and I haven't found a reference yet. (Maybe Bob's reference is what I was looking for! )

    Sorry, I don't know. I never did find that particular information. I have the Platform SDK and the DirectX SDK. I haven't read everything in them. There is a surprising amount of documentation in the SDKs. But, it seems to be organized more like a tutorial than a reference.... I didn't see organized groups of functions that I could browse through to see which ones I need etc. Hopefully, there are others here who can give you better guidance... I've been fooling around with Windows programming for quite a while, but I'm still just a beginner.

    P.S. I looks like Bob's MSDN link only covers the Windows Media Format... I don't know how much of that applies to other codecs (MP3, etc.). Then again, WMA files might work for you.

    Ooooh! I found something very interesting on MSDN: Using CODEDs to Compress Wave Audio. I hope it's not too outdated... It references Win95 and WinNT.

    P.P.S. Yes, It's outdated... The Platform SDK says that the ACM codecs are "deprecated". It says there are 3 types of codecs:

    ACM (and VCM)
    Direct Show Filters
    DirectX Media Objects (DMOs)

    I found that in the DirectX section of the Platform SDK, and I assume that it's duplicated in the DirectX SDK.
    Hi, DougDbug, thank you very much for your reply. You are very kind.

    I read that link before (Using CODEDs to Compress Wave Audio) and I tried to put it in Microsoft Visual C++ 6.0 and I cant manage to run it without bug. I failed to do so.

    I just dont know how and where should I start now. Please, anyone can help me?

  10. #10
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I read that link before (Using CODEDs to Compress Wave Audio) and I tried to put it in Microsoft Visual C++ 6.0 and I cant manage to run it without bug. I failed to do so.
    All you have to do is write the find_driver function as described in the link and do the two step conversion also described in the link.
    Use the DriverEnumProc as a reference for your find_driver function.
    Code:
    // Command line compile with CL
    #pragma comment( lib, "msacm32.lib" ) 
    #include <windows.h>
    #include <math.h>
    #include <mmsystem.h>
    #include <mmreg.h>  
    #include <msacm.h>    
    #include <stdio.h>
    
    BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
    {
        printf("    %4.4lXH, %s\n", pafd->dwFormatTag, pafd->szFormat);
        return TRUE; // Continue enumerating.
    }
    
    BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport)
    {
        printf(" id: %8.8lxH", hadid);
        printf("  supports:\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC) printf("   async conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) printf("   different format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) printf("   same format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) printf("   filtering\n");
        // Get some details.
        ACMDRIVERDETAILS dd;
        dd.cbStruct = sizeof(dd);
        MMRESULT mmr = acmDriverDetails(hadid, &dd, 0);
        if (mmr) {
            printf("we have an acmDriverDetails error\n");
        } 
        else {
            printf("   Short name: %s\n", dd.szShortName);
            printf("   Long name:  %s\n", dd.szLongName);
            printf("   Copyright:  %s\n", dd.szCopyright);
            printf("   Licensing:  %s\n", dd.szLicensing);
            printf("   Features:   %s\n", dd.szFeatures);
            printf("   Supports %u formats\n", dd.cFormatTags);
            printf("   Supports %u filter formats\n", dd.cFilterTags);
        }
        // Open the driver.
        HACMDRIVER had = NULL;
        mmr = acmDriverOpen(&had, hadid, 0);
        if (mmr) {
            printf("Driver open error\n");
        } 
        else {
            DWORD dwSize = 0;
            mmr = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
            if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); // for MS-PCM
            WAVEFORMATEX* pwf = (WAVEFORMATEX*) malloc(dwSize);
            memset(pwf, 0, dwSize);
            pwf->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
            pwf->wFormatTag = WAVE_FORMAT_UNKNOWN;
            ACMFORMATDETAILS fd;
            memset(&fd, 0, sizeof(fd));
            fd.cbStruct = sizeof(fd);
            fd.pwfx = pwf;
            fd.cbwfx = dwSize;
            fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
            mmr = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);  
            if (mmr) {
                printf("FormatEnum Error\n");
            }
            free(pwf);
            acmDriverClose(had, 0);
        }
        return TRUE; // Continue enumeration.
    }
    
    
    int main(void)
    {
        // Get the ACM version.
        DWORD dwACMVer = acmGetVersion();
        printf("ACM version %u.%.02u build %u",
            HIWORD(dwACMVer) >> 8,
            HIWORD(dwACMVer) & 0x00FF,
            LOWORD(dwACMVer));
        if (LOWORD(dwACMVer) == 0) printf(" (Retail)");
        printf("\n");
    
        // Show some ACM metrics.
        printf("ACM metrics:\n");
    
        DWORD dwCodecs = 0;
        MMRESULT mmr = acmMetrics(NULL, ACM_METRIC_COUNT_CODECS, &dwCodecs);
        if (mmr) {
            printf("We have an acmMetrics error\n");
    
        } 
        else {
            printf("%lu codecs installed\n", dwCodecs);
        }
        // Enumerate the set of enabled drivers.
        printf("Enabled drivers:\n");
        mmr = acmDriverEnum(DriverEnumProc, 0, 0); 
        if (mmr)
            printf("We have an acmDriver Enum error\n");
        return 0;
    }

  11. #11
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    First of all my disclaimer, I have almost no experience doing audio coding. With that in mind, I've coded my interpretation of the CODEC link provide by DougDbug. It's totally up to you to verify whether or not the code is error free and appropriate for your requirements. Obviously, you'll have to make some changes to the output since I used the same parms on input and output and a few other minor changes are also needed.

    Code:
    // Command line compile with CL
    #pragma comment( lib, "msacm32.lib" ) 
    #include <windows.h>
    #include <math.h>
    #include <mmsystem.h>
    #include <mmreg.h>  
    #include <msacm.h>    
    #include <stdio.h>
    
    typedef struct
    {
    	HACMDRIVERID hadid;
    	WORD wFormatTag;
    } FIND_DRIVER_INFO;
    
    // callback function for format enumeration
    BOOL CALLBACK find_format_enum(HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
    {
    	FIND_DRIVER_INFO* pdi = (FIND_DRIVER_INFO*) dwInstance;
    	if (pafd->dwFormatTag == (DWORD)pdi->wFormatTag)
    	{
    		// found it
    		pdi->hadid = hadid;
    		return FALSE; // stop enumerating
    	}
    	return TRUE; // continue enumerating
    }
    
    BOOL CALLBACK find_format_enum2(HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
    {
    	FIND_DRIVER_INFO* pdi = (FIND_DRIVER_INFO*) dwInstance;
    	if (pafd->dwFormatTag == (DWORD)pdi->wFormatTag &&
    		pafd->pwfx->nChannels == 1 &&
    		pafd->pwfx->nSamplesPerSec == 11025)
    	{
    		pdi->hadid = hadid;
    		return FALSE; // stop enumerating
    	}
    	return TRUE; // continue enumerating
    }
    
    BOOL CALLBACK find_driver_enum(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport)
    {
    	FIND_DRIVER_INFO* pdi = (FIND_DRIVER_INFO*) dwInstance;
    	DWORD dwSize = 0;
    	ACMFORMATDETAILS fd;
    
    	// open the driver
    	HACMDRIVER had = NULL;
    	MMRESULT mmr = acmDriverOpen(&had, hadid, 0);
    	WAVEFORMATEX* pwf = NULL;
    	if (mmr) {
    		// some error
    		return FALSE; // stop enumerating
    	}
    	// enumerate the formats it supports
    	mmr = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
    	if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); // for MS-PCM
    	pwf = (WAVEFORMATEX*) malloc(dwSize);
    	memset(pwf, 0, dwSize);
    	pwf->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
    	pwf->wFormatTag = pdi->wFormatTag;
    	memset(&fd, 0, sizeof(fd));
    	fd.cbStruct = sizeof(fd);
    	fd.pwfx = pwf;
    	fd.cbwfx = dwSize;
    	fd.dwFormatTag = pdi->wFormatTag;
    	mmr = acmFormatEnum(had, &fd, find_format_enum, (DWORD)(VOID*)pdi, 0);  
    	free(pwf);
    	acmDriverClose(had, 0);
    	if (pdi->hadid || mmr) {
    		// found it or some error
    		return FALSE; // stop enumerating
    	}
    	return TRUE; // continue enumeration
    }
    
    HACMDRIVERID find_driver(WORD wFormatTag)
    {
    	FIND_DRIVER_INFO fdi;
    	MMRESULT mmr;
    	fdi.hadid = NULL;
    	fdi.wFormatTag = wFormatTag;
    	mmr = acmDriverEnum(find_driver_enum, (DWORD)(VOID*)&fdi, 0); 
    	if (mmr) return NULL;
    	return fdi.hadid;
    }
    
    WAVEFORMATEX* get_driver_format(HACMDRIVERID hadid, WORD wFormatTag)
    {
    	// open the driver
    	DWORD dwSize = 0;
    	HACMDRIVER had = NULL;
    	WAVEFORMATEX* pwf = NULL;
    	ACMFORMATDETAILS fd;
    	MMRESULT mmr = acmDriverOpen(&had, hadid, 0);
    	FIND_DRIVER_INFO fdi;
    
    	if (mmr)
    	{
    		printf("acmDriverOpen failed\n");
    		return NULL;
    	}
    	// allocate a structure for the info
    	mmr = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
    	if (dwSize < sizeof(WAVEFORMATEX)) dwSize = sizeof(WAVEFORMATEX); // for MS-PCM
    	pwf = (WAVEFORMATEX*) malloc(dwSize);
    	memset(pwf, 0, dwSize);
    	pwf->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
    	pwf->wFormatTag = wFormatTag;
    	memset(&fd, 0, sizeof(fd));
    	fd.cbStruct = sizeof(fd);
    	fd.pwfx = pwf;
    	fd.cbwfx = dwSize;
    	fd.dwFormatTag = wFormatTag;
    	// set up a struct to control the enumeration
    	fdi.hadid = NULL;
    	fdi.wFormatTag = wFormatTag;
    	mmr = acmFormatEnum(had, &fd, find_format_enum2, (DWORD)(VOID*)&fdi, 0);  
    	acmDriverClose(had, 0);
    	if ((fdi.hadid == NULL) || mmr) 
    	{
    		printf("acmFormatEnum failed\n");
    		free(pwf);
    		return NULL;
    	}
    	return pwf;
    }
    
    int convert(HACMDRIVERID hadid,WORD wFormatTag)
    {
    	HACMDRIVER had = NULL;
    	HACMSTREAM hstr = NULL;
    	MMRESULT mmr;
    	// First we create a wave that might have been just recorded.
    	// The format is 11.025 kHz, 8 bit mono PCM which is a recording
    	// format available on all machines.
    	// Our sample wave will be 1 second long and will be a sine wave 
    	// of 1kHz, which is exactly 1,000 cycles.
    	WAVEFORMATEX wfSrc;
    	memset(&wfSrc, 0, sizeof(wfSrc));
    	wfSrc.cbSize = 0;
    	wfSrc.wFormatTag = WAVE_FORMAT_PCM; // PCM
    	wfSrc.nChannels = 1; // Mono
    	wfSrc.nSamplesPerSec = 11025; // 11.025 kHz
    	wfSrc.wBitsPerSample = 8; // 8 bit
    	wfSrc.nBlockAlign = wfSrc.nChannels * wfSrc.wBitsPerSample / 8;
    	wfSrc.nAvgBytesPerSec = wfSrc.nSamplesPerSec * wfSrc.nBlockAlign;
    	DWORD dwSrcSamples = wfSrc.nSamplesPerSec;
    	BYTE* pSrcData = new BYTE [dwSrcSamples]; // 1 second duration
    	BYTE* pData = pSrcData;
    	double f = 1000.0;
    	double pi = 4.0 * atan(1.0);
    	double w = 2.0 * pi * f;
    	for (DWORD dw = 0; dw < dwSrcSamples; dw++) {
    		double t = (double) dw / (double) wfSrc.nSamplesPerSec; 
    		*pData++ = 128 + (BYTE)(127.0 * sin(w * t));
    	}
    	// Get the details of the format.
    	// Note: this is just the first of one or more possible formats for the given tag.
    	WAVEFORMATEX* pwfDrv = get_driver_format(hadid, wFormatTag);
    	if (pwfDrv == NULL) {
    		printf("Error getting format info\n");
    		return -1;
    	}
    	printf("Driver format: %u bits, %lu samples per second\n",
    		pwfDrv->wBitsPerSample, pwfDrv->nSamplesPerSec);
    	// Get a PCM format tag the driver supports.
    	// Note: we just pick the first supported PCM format which might not really
    	// be the best choice.
    	WAVEFORMATEX* pwfPCM = get_driver_format(hadid, wFormatTag);
    	if (pwfPCM == NULL) {
    		printf("Error getting PCM format info\n");
    		return -1;
    	}
    	printf("PCM format: %u bits, %lu samples per second\n",
    		pwfPCM->wBitsPerSample, pwfPCM->nSamplesPerSec);
    	// First step
    	/////////////////////////////////////////////////////////////////////////////
    	// Convert the source wave to the PCM format supported by the CODEC.
    	// We use any driver that can do the PCM to PCM conversion.
    	//HACMSTREAM hstr = NULL;
    	mmr  = acmStreamOpen(&hstr,
    		NULL, // Any driver
    		&wfSrc, // Source format
    		pwfPCM, // Destination format
    		NULL, // No filter
    		NULL, // No callback
    		0, // Instance data (not used)
    		ACM_STREAMOPENF_NONREALTIME); // flags
    	if (mmr) {
    		printf("Failed to open a stream to do PCM to PCM conversion\n");
    		return -1;
    	}
    	// Allocate a buffer for the result of the conversion.
    	DWORD dwSrcBytes = dwSrcSamples * wfSrc.wBitsPerSample / 8;
    	DWORD dwDst1Samples = dwSrcSamples * pwfPCM->nSamplesPerSec / wfSrc.nSamplesPerSec;
    	DWORD dwDst1Bytes = dwDst1Samples * pwfPCM->wBitsPerSample / 8;
    	BYTE* pDst1Data = new BYTE [dwDst1Bytes];
    	// Fill in the conversion info.
    	ACMSTREAMHEADER strhdr;
    	memset(&strhdr, 0, sizeof(strhdr));
    	strhdr.cbStruct = sizeof(strhdr);
    	strhdr.pbSrc = pSrcData; // The source data to convert
    	strhdr.cbSrcLength = dwSrcBytes;
    	strhdr.pbDst = pDst1Data;
    	strhdr.cbDstLength = dwDst1Bytes;
    	mmr = acmStreamPrepareHeader(hstr, &strhdr, 0); 
    	printf("Converting to intermediate PCM format...\n");
    	mmr = acmStreamConvert(hstr, &strhdr, 0);
    	if (mmr) {
    		printf("Failed to do PCM to PCM conversion\n");
    		return -1;
    	}
    	printf("Intermediate Converted OK\n");
    
    	// Close the stream.
    	acmStreamClose(hstr, 0);
    
    	//Final step
    	///////////////////////////////////////////////////////////////////////////////////
    	// Convert the intermediate PCM format to the final format.
    
    	// Open the conversion stream.
    	// Note the use of the ACM_STREAMOPENF_NONREALTIME flag. Without this
    	// some software compressors will report error 512 - not possible.
    	hstr = NULL;
    	mmr = acmStreamOpen(&hstr,
    		NULL, // had, // Driver handle
    		pwfPCM, // Source format
    		pwfDrv, // Destination format
    		NULL, // No filter
    		NULL, // No callback
    		0, // Instance data (not used)
    		ACM_STREAMOPENF_NONREALTIME ); // Flags
    	if (mmr) {
    		printf("Failed to open a stream to do PCM to driver format conversion\n");
    		return -1;
    	}
    	// Allocate a buffer for the result of the conversion.
    	// Compute the output buffer size based on the average byte rate
    	// and add a bit for randomness.
    	// The IMA_ADPCM driver fails the conversion without this extra space.
    	DWORD dwDst2Bytes = pwfDrv->nAvgBytesPerSec * dwDst1Samples /
    		pwfPCM->nSamplesPerSec;
    	dwDst2Bytes = dwDst2Bytes * 3 / 2; // add a little room
    	BYTE* pDst2Data = new BYTE [dwDst2Bytes];
    	// Fill in the conversion info.
    	ACMSTREAMHEADER strhdr2;
    	memset(&strhdr2, 0, sizeof(strhdr2));
    	strhdr2.cbStruct = sizeof(strhdr2);
    	strhdr2.pbSrc = pDst1Data; // the source data to convert
    	strhdr2.cbSrcLength = dwDst1Bytes;
    	strhdr2.pbDst = pDst2Data;
    	strhdr2.cbDstLength = dwDst2Bytes;
    	// Prep the header.
    	mmr = acmStreamPrepareHeader(hstr, &strhdr2, 0); 
    	// Convert the data.
    	printf("Converting to final format...\n");
    	mmr = acmStreamConvert(hstr, &strhdr2, 0);
    	if (mmr) {
    		printf("Failed to do PCM to driver format conversion\n");
    		return -1;
    	}
    	printf("Final Step Converted OK\n");
    	// Close the stream and driver.
    	mmr = acmStreamClose(hstr, 0);
    	mmr = acmDriverClose(had, 0);
    	// Show the conversion stats.
    	printf("Source wave had %lu bytes\n", dwSrcBytes);
    	printf("Converted wave has %lu bytes\n", strhdr2.cbDstLengthUsed);
    	printf("Compression ratio is %f\n", (double) dwSrcBytes /
    		(double) strhdr2.cbDstLengthUsed);
    	return 0;
    }
    
    int main(void)
    {
    	WORD wFormatTag = WAVE_FORMAT_PCM;
    	HACMDRIVERID hadid = find_driver(wFormatTag);
    	if (hadid == NULL) {
    		printf("No driver found\n");
    		return -1;
    	}
    	else
    	{
    		printf("Driver found (hadid: %4.4lXH)\n", hadid);
    		return( convert(hadid,wFormatTag));
    	}
    }
    Last edited by BobS0327; 04-24-2006 at 04:51 PM. Reason: typo error

  12. #12
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Hi, BobS0327, thank you very much for your help, I appreciate very much.

    I am trying now on my software and will tell you how I am going.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Hi, BobS0327, sorry, again it's me.

    Sorry to disturb, May I ask?

    I was confused with the acm driver and as a newbie, I really coulndt implement it without any bug after finding the driver and doing the two conversions. I just want to call the third-party software.exe to help me do the compression and decompression part. Do I need to call the dll? Or, Can I just call the .exe from my software?

    Sorry for causing any confusion, I was not clear with dll before I put this thread, after I read the pdf about dll, I think that maybe I dont need to call dll but just call the exe.

    Please forgive me, I apologized for the trouble caused by me.

    Do you think it is possible to call any CODEC software exe from my software? Which one is easier for a newbie like me?

    But, I dont know how can I do so, do you mind to give me some guidance? Please, Please forgive me for my ignorance. I try my best in doing it. Hope you can teach me some. Please.

  14. #14
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Yes, it is easy to call an EXE from your program (no intermediate DLL is required).

    There are a number of audio compression formats you can use, but for your purpose I suggest you consider Speex. It is a free open source format, with command line tools, and is designed specifically for speech.

    - Download Speex here. You want the Windows binaries.
    - You can find examples of the encoding quality here.
    - The command line options can be found here. The simplest command line is: speexenc input.wav output.spx

    Once you have got the command line working, you can ask back here about integrating it into to your program.

    The things you'll need to know when calling the command line from your program:
    - The location of the input file. (ie. Where did your program put the wave file?)
    - The destination path for the output file. (You can ask the user).
    Last edited by anonytmouse; 04-25-2006 at 03:06 AM.

  15. #15
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by anonytmouse
    Yes, it is easy to call an EXE from your program (no intermediate DLL is required).

    There are a number of audio compression formats you can use, but for your purpose I suggest you consider Speex. It is a free open source format, with command line tools, and is designed specifically for speech.

    - Download Speex here. You want the Windows binaries.
    - You can find examples of the encoding quality here.
    - The command line options can be found here. The simplest command line is: speexenc input.wav output.spx

    Once you have got the command line working, you can ask back here about integrating it into to your program.

    Hi, Anonytmouse, thank you very much for your kind post.

    I will study in detail and try to implement it in my own project and will tell you how I am going.

    I am so touched and you and those in this forum are willing to give me some guidance as I am totally down for that past few days, thanks for telling me. I will do my best.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening an MP3 file for bit access
    By gaza2k1 in forum C Programming
    Replies: 13
    Last Post: 02-24-2008, 09:08 PM
  2. mp3 file renamer
    By Loic in forum C++ Programming
    Replies: 6
    Last Post: 10-17-2007, 12:52 PM
  3. MP3 file searching question
    By panfilero in forum C Programming
    Replies: 4
    Last Post: 11-27-2005, 01:19 PM
  4. Edit mp3 File Names
    By willc0de4food in forum C Programming
    Replies: 20
    Last Post: 04-10-2005, 11:45 PM
  5. wave player or mp3 player using C
    By lliero in forum C Programming
    Replies: 5
    Last Post: 02-27-2002, 11:33 AM