|
This seems pointless - you are just confirming what I already know.
And what makes you think I am not certain?
Sorry, not in the mood for exchanging stuff like this here.
Just for kicks - it is used in CRecorder class which does not have any info where it came from.
The class itself has #include <mmsystem.h> and
#pragma comment(lib,"winmm.lib").
Have a nice day anyway.
Grumpy old man Vaclav
|
|
|
|
|
When doing customer support, one always ask the obvious questions !
I'd rather be phishing!
|
|
|
|
|
And the obvious answer in my case - typedef struct _PCMFORMAT.... defining four basic PCM parameters later copied to PCMWAVAE....
Sorry to be so grumpy.
Vaclav
|
|
|
|
|
I don't know where the definition of PCMFORMAT is... but I can tell you what PCM is...
PCM stands for Pulse Code Modulation and is essentially a three step process for a encoding a real life signal into a digital form that can be used within a computer.
1. Sample (sample the analog signal)
2. Quantize (quantize to a level that can be encoded given the number of states you have available)
3. Encode (encode the quantized value into an appropriate numbering scheme)
It's really that simple to understand. Differences come in the variations available for these three variables. For example, your sampling rate could be 33KHz, or 48KHz, or something else. It depends on available hardware and what you expect to the highest frequency of interest. The quantization states are dependent on how many bits you are using and how many distinct possible values they can represent. Obviously, more states equals more values and therefore more fidelity in representing a signal (wider dynamic range). Third, the encoding can be an unsigned integer, a signed integer (common ones)... or can really have any arbitrary encoding a designer wishes.
|
|
|
|
|
I am having problem detecting when the waveOutWrite is finished when I specify number of loops to output. I output 1kHz test tone and it should be about 5 seconds long. The waveOutWrite returns WOM_DONE to the callback function immediately when it is executed.
In debug the code works as expected, the tone is there for 5 seconds.
The WOM_DONE is still returned before the “loop” is done.
Here is the code snippet:
pcm[i].lFreq = Freq;
pcm[i].dDelay = 1;
pcm[i].whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
pcm[i].whdr.dwLoops = 5; // about 5 seconds
if(!pcm[i].C_CreateSinus())
TRACE("\nFailed pcm[i].C_CreateSinus() %i ", i );
mmres = waveOutPrepareHeader(hwout, & pcm[i].whdr, sizeof(WAVEHDR));
if (mmres != MMSYSERR_NOERROR) {ASSERT(0); bOK = FALSE;}
mmres = waveOutWrite(hwout, & pcm[i].whdr, sizeof(WAVEHDR));
Any help would be appreciated.
Cheers
Vaclav
|
|
|
|
|
What does your call to waveOutOpen() look like?
Are you using a callback event?
Are you using a synchronous audio driver?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
David,
the output "device" is PC speaker and here is the
waveOutOpen:
mmres = waveOutOpen(&hwout, WAVE_MAPPER, &wfme,
(DWORD) CallbackWaveOutProc, 0x12345, CALLBACK_FUNCTION);
Correction - it works in "normal" non debug mode ( I got too many threads running amok most of the time) , but still returns WOM_DONE too soon for my app.I am trying to generate several frequencies and need to know when to advance to the next one.
Maybe I should get rid of the WAVE_MAPPER and specify the speaker.
Since it runs in its own thread , could that be the problem??
I am using AfxMessageBox to troubleshoot this and it is not the best way to keep track of timing of things.
|
|
|
|
|
Okay, try something like:
HANDLE Done;
waveOutOpen(&hwout, WAVE_MAPPER, &wfme, (DWORD) Done, CALLBACK_EVENT);
waveOutPrepareHeader(...);
ResetEvent(Done);
waveOutWrite(...);
WaitForSingleObject(Done, INFINITE);
Vaclav_Sal wrote: I am using AfxMessageBox to troubleshoot this and it is not the best way to keep track of timing of things. Very true.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
David, I'll try the event approach. Funny things - I checked the WOM_DONE flag after the write is done and it is not set. But the callback still reports it.
Thanks for you help.
Vaclav
|
|
|
|
|
David, I need some more help.
I cannot get the event HANDLE coded.
I have tryed few things but still getting "Invalid handle" from GetLastError.
I have not found an example on setting the HANDLE, all I found is "event handlers".
Keep in mind I am using MFC.
Thanks for your help.
Vaclav
HANDLE Done = new HANDLE;
//mmres = waveOutOpen(&hwout, WAVE_MAPPER, &wfme, (DWORD) Done, CALLBACK_EVENT);
mmres = waveOutOpen(&hwout, WAVE_MAPPER, &wfme,
(DWORD) &Done, 0x12345, CALLBACK_EVENT);
if (mmres != MMSYSERR_NOERROR)
{
TRACE("\nFailed waveOutOpen...");
return;
}
DWORD dResult = WaitForSingleObject( Done, INFINITE);
|
|
|
|
|
Vaclav_Sal wrote: HANDLE Done = new HANDLE; HANDLE Done;
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
David,
I tried that with same result.
I got it doing what I need with this Mickey Mouse code :
pcm[i].whdr.dwLoops = 5; // works
if(!pcm[i].C_CreateSinus())
TRACE("\nFailed pcm[i].C_CreateSinus() %i ", i );
mmres = waveOutPrepareHeader(hwout, & pcm[i].whdr, sizeof(WAVEHDR));
if (mmres != MMSYSERR_NOERROR) {ASSERT(0); bOK = FALSE;}
mmres = waveOutWrite(hwout, & pcm[i].whdr, sizeof(WAVEHDR));
int mSeconds = 100;
while((pcm[i].whdr.dwFlags & 1) != 1)
{
Sleep(1000);
TRACE("\nWaiting.. %i ",mSeconds );
mSeconds += 100;
}
if((pcm[i].whdr.dwFlags & 1) == WHDR_DONE) // & WHDR_DONE) == WHDR_DONE)
AfxMessageBox("DONE");
It still fights with the other real time thread ( runs audio signal FFT ) , but for testing purpose it will do.
Thanks for your help.
Vaclav
|
|
|
|
|
I am sure some of you will get upset by this OT post, but I am trying to reach coders with knowledge about numerical processing in C/C++.
I am a beginner in this form of computing, presently trying to implement FFT in signal detection and processing.
I am no mathematician and have trouble transferring mathematical formulas to code.
I am presently looking for some reasonable text(book) to learn about the numerical computing.
I have found this source “Numerical Recipes in C” but I am not sure if that is a good starting point for me.
I am not looking for specific processing library, I just want someplace to start learning.
Thanks for understanding
Cheers
Vaclav
|
|
|
|
|
Try the Lounge or Collaboration & Testing.
Veni, vidi, abiit domum
|
|
|
|
|
Hi
I ask for your cooperation
|
|
|
|
|
What?
Veni, vidi, abiit domum
|
|
|
|
|
Yes, "Numerical Recipes in C" is a good starting point, in my opinion.
Veni, vidi, vici.
|
|
|
|
|
Check out the FFTW[^] library... it's open source and you should be able to browse through their code if you're trying to understand how they achieve the FFT math.
If you have any specific questions regarding the math, post somewhere here and I'll see if I can clarify. I work with signals processing regularly.
Good luck!
|
|
|
|
|
Albert,
many thanks for you reply. I was loosing all hope...
It seems that the FFT code is always copied from other sources and never really explained.
The best "explanation " so far - swap and butterflies. (from "Signal and image processing with neural networks " - my "textbook " way over my head for now!)
But my biggest mistake so far was that I did not check the audio source which was set for stereo ( my test source is mono) and the FFT "result" was power spectrum. So I completely missed the actual FFT output (real and img).
Cheers Vaclav
|
|
|
|
|
There should be plenty of sources online regarding the subject, FFT's have been used for quite a long time now and are a very prevalent method of signals analysis.
I would recommend when you're initially making a prototype of a function that is complex, that you start out with developing the algorithm in an environment that is well suited for helping someone understand the problem (versus implementing a solution). I use Matlab for prototyping any algorithms before going on to implement them in C/C++. Alternatively, you can use Octave which is a similar, free open source alternative. The Octave math engine is very good too but the GUIs are all very roughly put together. Their scripting is just as powerful as Matlab's (almost identical syntax).
|
|
|
|
|
Hi, I'm trying to teach myself C++ and was playing with an example from a website. If I only inherit from Derived class, I could change the access level of Identity method from protected to public by declaring public Derived::Identity in class DerivedChild. However, if I have multiple inheritance, I'm not able to access that method. Could someone tell me what I did wrong?
Thanks,
Helen
#include <iostream>
#include <string>
class Base
{
protected:
int m_nValue;
public:
Base(int nValue)
: m_nValue(nValue){}
void Identity() {std::cout << "I am a Base" << std::endl;}
};
class Derived
{
public:
Derived(){};
protected:
void Identity(){
std::cout << "I am a Derived" << std::endl;
};
};
class DerivedChild : public Base, public Derived
{
public:
DerivedChild(int nValue)
: Base(nValue){}
Derived::Identity;
};
int main()
{
DerivedChild cChild(9);
cChild.Base::Identity();
cChild.Derived::Identity();
return 0;
}
|
|
|
|
|
The 'public/protected/private' modifiers can only be used to maintain or reduce the accessibility of a base class's methods, it cannot be used to improve that accessibility.
ie. once a method is declared 'protected' or 'private' its accessibility cannot be improved by a derived class, otherwise this would break the encapsulation of the base class.
The only way to make a base class protected method visible outside of the derived class is for the derived class to override it and call the base class implementation.
I'm sure someone will be able to direct you to the relevant part of the standard but this is my understanding.
|
|
|
|
|
You cannot really change the access type in a derived class.
Consider the situation where Derived derives from Base in your example - class Derived : public Base
In this case, if you create an object of Base , then Identity() would be public .
And if you create an object of Derived , then Identity() would be protected.
This is probably what you want, but this behavior is only because when the Base object is created, the compiler sees Identity() as public and when the Derived object is created the compiler see Identity() as protected .
But if you do this - Base* ptr = new Derived;
And access Identity() like this - ptr->Identity();
You will be able to do this, since Identity() is still public and not changed to protected .
So even though, you're creating an object of Derived , the compiler only checks the class Base since the pointer is of type Base .
|
|
|
|
|
Thank you, .dan.g. and «_Superman_» for explaining. I was reading chapter 11.6 of learncpp.com and the author seems to indicate it's possible to change the access from a derived class. I tried it and it did work for single inheritance, but it doesn't work with multiple inheritance...
|
|
|
|
|
int main()
{
DerivedChild cChild(9);
cChild.Base::Identity();
cChild.Identity();
return 0;
}
You can use both, you would be in trouble if both base classes had Identity as protected because in that case you could put only one of them into to the public namespace of the DerivedChild class.
|
|
|
|