Play AUDIO files (mp3,midi,wav)

Hi everybody,
I'd like to make a program to play/record sounds...
The format I absolutely want to play are wav and midi (because I know there are some functions in windows.h like MidiOut or WaveOut & similars), I know that mp3 are f***in' complicated because of they're compressed, so if it is too hard...nevermind for MP3.

But...the problem is that I don't want just to play them, but I'd like to edit their sound in play-time, that's why i cant simply use "sndPlaySound(fname,mode)"

So if it isn't too complicated I'd like to know how to play them, or if there is already some kind of unit that does it...
It's enough to give me a tutorial or something where it is really WELL explained

//-------------------
I'm sorry for bad english, but I'm Italian and I learnt it at school...
wave files can be played with the waveOut family. Search on MSDN.

IIRC, the general process is like so. Double check this because it's been a very long time and I might have gotten some of it wrong:

To set up:
----------------------
waveOutOpen
waveOutPrepareHeader
waveOutStart


While playing:
----------------------
Keep filling headers with PCM (wave) data and giving them to waveOutWrite


When done:
----------------------
waveOutUnprepareHeader
waveOutClose


Since you provide the PCM data to waveOutWrite, you can manipulate it before it gets output.
I guess it's the same for MIDI files...
but how i get the data to be played???
I mean WAV format is a mess where do i get the frequency, the note, the time, etc..?
I mean WAV format is a mess where do i get the frequency, the note, the time, etc..?


PCM data (wav) doesn't work that way. It's basically a digital representation of a sound wave.

There are X samples per second (typically 44100) each sample represents a "point" on that wave. Imagine if you plot points along an axis, where the Y axis is the sample value and the X axis is time. Then "connect the dots" to form the wave. That's basically what PCM data is.

The "taller" the wave, the louder it is. The "wider" the wave, the lower pitch it is.


MIDI works totally differently. MIDI is basically a "play X note for Y length at Z volume". But I know very little about it since I never work with it.
ok, thanks...so basically in WAV file I just find a serie of data that is the sample to play, right?
and i give what i read to the waveOutWrite function, right?
Yes.
Ok, but what if I want to "edit" the sound to be played..?
How do I change the "wavehdr->lpData" so that the sound will sound different with an effect..?
It depends entirely on what kind of effect you want.

But editing PCM data is practically a whole field of science. It's too much to explain in a forum post. If you really want to learn, you might want to read some ebooks on DSP.

Also, DEFINITELY get a wave editor like SoundForge (or a free alternative, like GoldWave or something) and examine a wave file as it's playing so you can see how it works.

It might also help to start by generating sounds from scratch (which is how I got into it), rather than modifying existing wave files (which are usually extremely complex). For example a simple square wave would look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// square waves alternate between high and low output, forming a "square" output pattern.
//  In an oscilloscope it would look something like this:
//    _   _   _   _
//  _| |_| |_| |_|

// audiobuffer = the buffer we're filling with audio data
// numsamples = the number of samples to write
//  assumes 16-bit signed mono output
void GenerateSquareWave( short* audiobuffer, int numsamples )
{
  static int position = 0;  // our position in the wave
  static const int halfwidth = 200;  // the "half-width" of the wave
  static const short volume = 2000;  // the "height" / volume of the wave

  // fill output samples
  while( numsamples > 0 )
  {
    // output a positive or negative (high or low) output depending on our
    //  position in the wave
    if(position < 0)  *audiobuffer = -volume;
    else              *audiobuffer = volume;

    // increment our position.  Once we reach the halfwidth, reset the position
    //  to -halfwidth so the wave pattern will repeat itself.
    ++position;
    if(position >= halfwidth)
      position = -halfwidth

    // count this sample
    --numsamples;
    ++audiobuffer;
  }
}


This will generate a square wave. Increasing 'volume' will make the wave "taller", which make it louder. Increasing 'halfwidth' will make the wave "wider", which lowers its pitch. Decreasing halfwidth will increase the pitch.

Multiple sound waves can be "mixed"/combined by simply adding the sample streams together.
OkOk I see...
Ok thank you...really!
Topic archived. No new replies allowed.