- First version of ReactOS Sound Record Application by Marco Pagliaricci (IRC: rendar)
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 30 Nov 2009 18:54:41 +0000 (18:54 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 30 Nov 2009 18:54:41 +0000 (18:54 +0000)
svn path=/trunk/; revision=44331

31 files changed:
reactos/base/applications/sndrec32/audio_def.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_format.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_format.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_membuffer.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_membuffer.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_producer.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_producer.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_receiver.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_receiver.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_resampler_acm.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_resampler_acm.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_wavein.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_wavein.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_waveout.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/audio_waveout.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/bitmap1.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/but_end.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/but_play.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/but_rec.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/but_start.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/but_stop.bmp [new file with mode: 0644]
reactos/base/applications/sndrec32/kkaudio.hpp [new file with mode: 0644]
reactos/base/applications/sndrec32/reactOS_sndrec32.ico [new file with mode: 0644]
reactos/base/applications/sndrec32/resource.h [new file with mode: 0644]
reactos/base/applications/sndrec32/small.ico [new file with mode: 0644]
reactos/base/applications/sndrec32/sndrec32.cpp [new file with mode: 0644]
reactos/base/applications/sndrec32/sndrec32.h [new file with mode: 0644]
reactos/base/applications/sndrec32/sndrec32.rbuild [new file with mode: 0644]
reactos/base/applications/sndrec32/sndrec32.rc [new file with mode: 0644]
reactos/base/applications/sndrec32/stdafx.h [new file with mode: 0644]
reactos/base/applications/sndrec32/targetver.h [new file with mode: 0644]

diff --git a/reactos/base/applications/sndrec32/audio_def.hpp b/reactos/base/applications/sndrec32/audio_def.hpp
new file mode 100644 (file)
index 0000000..da57f3f
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _AUDIO_DEF__H_
+#define _AUDIO_DEF__H_
+
+
+#include <iostream>
+
+//
+// Defaults
+//
+
+#define _AUDIO_DEFAULT_FORMAT A44100_16BIT_STEREO
+#define _AUDIO_DEFAULT_WAVEINBUFFERS 8
+#define _AUDIO_DEFAULT_WAVEINBUFSECS 0.1f
+#define _AUDIO_DEFAULT_WAVEOUTBUFFERS 8
+#define _AUDIO_DEFAULT_WAVEOUTBUFSECS 0.1f
+#define _AUDIO_DEFAULT_BUFSECS 1.0f
+
+
+//
+// Namespace stuff
+//
+
+#define _AUDIO_NAMESPACE_START_ namespace snd {
+#define _AUDIO_NAMESPACE_END_ };
+//
+// Platform depend stuff
+//
+
+#include <windows.h>
+#include <mmsystem.h> //Windows MultiMedia (WINMM) audio apis
+#include <mmreg.h> //codecs stuff
+#include <Msacm.h> //codecs stuff
+
+#endif //ifdef _AUDIO_DEF__H_
diff --git a/reactos/base/applications/sndrec32/audio_format.cpp b/reactos/base/applications/sndrec32/audio_format.cpp
new file mode 100644 (file)
index 0000000..316f54b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_format.cpp
+ * PURPOSE:         Audio Format
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+
+#include "stdafx.h"
+#include "audio_format.hpp"
+
+_AUDIO_NAMESPACE_START_
+
+//
+// Standard audio formats (declared as
+// externs in `audio_format.hpp')
+//
+
+audio_format UNNKOWN_FORMAT( 0, 0, 0);
+audio_format A44100_16BIT_STEREO( 44100, 16, 2 );
+
+_AUDIO_NAMESPACE_END_
+
diff --git a/reactos/base/applications/sndrec32/audio_format.hpp b/reactos/base/applications/sndrec32/audio_format.hpp
new file mode 100644 (file)
index 0000000..1f620b2
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef _AUDIOFORMAT__H_
+#define _AUDIOFORMAT__H_
+
+
+
+#include "audio_def.hpp"
+
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+
+
+
+
+class audio_format
+{
+       protected:
+       
+
+               unsigned int samples_psec;
+               unsigned short int bits_psample;
+               unsigned short int chan;
+
+
+       public:
+               
+               
+               //
+               // Ctors
+               //
+
+               audio_format( unsigned int samples_per_second, 
+                       unsigned short int bits_per_sample, unsigned short int channels )
+
+                       : samples_psec( samples_per_second ), bits_psample( bits_per_sample ),
+                       chan( channels )
+
+               {     }
+
+
+
+
+
+
+
+               //
+               // Dtor
+               //
+
+               virtual ~audio_format( void )
+               { }
+
+
+
+
+
+
+
+               //
+               // Operators
+               //
+
+               bool operator==( audio_format & eq ) const
+               {
+                       //
+                       // The same audio format is when samples per second,
+                       // bit per sample, and channels mono/stereo are equal.
+                       //
+
+                       return (( samples_psec == eq.samples_psec ) 
+                               && ( bits_psample == eq.bits_psample ) && ( chan == eq.chan ));
+               }
+
+
+
+
+
+
+
+
+               //
+               // Public Functions
+               //
+
+               unsigned int sample_rate( void ) const
+               { return samples_psec; }
+
+
+               unsigned short int bits( void ) const
+               { return bits_psample; }
+
+
+               unsigned short int channels( void ) const
+               { return chan; }
+
+
+               unsigned int byte_rate( void ) const
+               { return ( samples_psec * chan * ( bits_psample / 8 )); }
+
+
+               unsigned int block_align( void ) const
+               { return ( chan * ( bits_psample / 8 )); }
+
+
+
+               unsigned int samples_in_seconds( float seconds ) const
+               {
+
+                       return ( unsigned int )
+                               ((( float )samples_psec * ( float ) chan ) * seconds );
+
+               }
+
+               unsigned int samples_in_bytes ( unsigned int bytes ) const
+               {
+
+                       return ( bytes / (( bits_psample / 8 ) * chan ));
+
+               }
+
+};
+
+
+
+
+extern audio_format UNKNOWN_FORMAT;
+extern audio_format A44100_16BIT_STEREO;
+
+
+
+
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+
+
+
+#endif //ifdef _AUDIOFORMAT__H_
diff --git a/reactos/base/applications/sndrec32/audio_membuffer.cpp b/reactos/base/applications/sndrec32/audio_membuffer.cpp
new file mode 100644 (file)
index 0000000..0f6580e
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_membuffer.cpp
+ * PURPOSE:         Audio MemBuffer
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+#include "stdafx.h"
+#include "audio_membuffer.hpp"
+
+_AUDIO_NAMESPACE_START_
+
+
+void 
+    audio_membuffer::alloc_mem_( unsigned int bytes )
+{
+
+    //
+    // Some checking
+    //
+
+    if ( bytes == 0 )
+        return;
+
+
+
+
+
+    //
+    // Checks previsiously alloc'd memory
+    // and frees it.
+    //
+
+    if ( audio_data )
+        delete[] audio_data;
+
+
+
+    //
+    // Allocs new memory and zeros it.
+    //
+
+    audio_data = new BYTE[ bytes ];
+
+
+    memset( audio_data, 0, bytes * sizeof( BYTE ));
+
+
+
+    //
+    // Sets the correct buffer size
+    //
+
+    buf_size = bytes;
+
+
+    init_size = bytes;
+
+
+
+}
+
+
+void
+    audio_membuffer::free_mem_( void )
+{
+
+    if ( audio_data )
+        delete[] audio_data;
+
+    buf_size = 0;
+    audio_data = 0;
+
+}
+
+
+void
+    audio_membuffer::resize_mem_( unsigned int new_size )
+{
+
+
+    if ( new_size == 0 )
+        return;
+
+
+    //
+    // The new_size, cannot be <= of the
+    // `bytes_received' member value of the
+    // parent class `audio_receiver'.
+    // We cannot touch received audio data,
+    // so we have to alloc at least
+    // bytes_received+1 bytes.
+    //
+    // But we can truncate unused memory, so
+    // `new_size' can be < of `buf_size'.
+    //
+
+    if ( new_size <= bytes_received )
+        return;
+
+
+
+
+    BYTE * new_mem;
+
+
+
+    //
+    // Allocs new memory and zeros it.
+    //
+
+
+    new_mem = new BYTE[ new_size ];
+
+    memset( new_mem, 0, new_size * sizeof( BYTE ));
+
+
+
+    if ( audio_data )
+    {
+
+
+        //
+        // Copies received audio data, and discard
+        // unused memory.
+        //
+
+        memcpy( new_mem, audio_data, bytes_received );
+
+
+
+        //
+        // Frees old memory.
+        //
+
+        delete[] audio_data;
+
+
+
+
+
+        //
+        // Commit new memory.
+        //
+
+        audio_data = new_mem;
+        buf_size = new_size;
+
+
+
+
+    } else {
+
+        audio_data = new_mem;
+        buf_size = new_size;
+    }
+
+
+    if ( buffer_resized )
+        buffer_resized( new_size );
+
+}
+
+
+
+
+void 
+    audio_membuffer::truncate_( void )
+{
+
+    //
+    // If `buf_size' is already = to the
+    // `bytes_received' of audio data, then
+    // this operation is useless; simply return.
+    //
+
+    if ( bytes_received == buf_size )
+        return;
+
+
+
+    if ( audio_data )
+    {
+
+
+        //
+        // Allocs a new buffer.
+        //
+
+        BYTE * newbuf = new BYTE[ bytes_received ];
+
+
+
+
+        //
+        // Copies audio data.
+        //
+
+        memcpy( newbuf, audio_data, bytes_received );
+
+
+
+        //
+        // Frees old memory.
+        //
+
+        delete[] audio_data;
+
+
+
+        //
+        // Commit the new buffer.
+        //
+
+        audio_data = newbuf;
+        buf_size = bytes_received;
+
+
+
+        //
+        // Buffer truncation successfull.
+        // Now the buffer size is exactly big
+        // as much audio data was received.
+        //
+
+
+    }
+
+
+}
+
+
+
+
+
+
+//////////////////////////////////////
+/////// Public Functions   ///////////
+//////////////////////////////////////
+
+
+
+
+void
+    audio_membuffer::clear( void )
+{
+
+    free_mem_();
+
+    bytes_received = 0;
+}
+
+
+
+void 
+    audio_membuffer::reset( void )
+{
+
+
+    //
+    // Frees memory and reset
+    // to initial state.
+    //
+
+    clear();
+
+
+
+    //
+    // Alloc memory of size specified
+    // at the constructor.
+    //
+
+    alloc_mem_( init_size );
+
+
+}
+
+void 
+    audio_membuffer::alloc_bytes( unsigned int bytes )
+{
+
+    alloc_mem_( bytes );
+
+}
+
+
+
+
+void 
+    audio_membuffer::alloc_seconds( unsigned int secs )
+{
+
+    alloc_mem_( aud_info.byte_rate() * secs );
+
+}
+
+
+void 
+    audio_membuffer::alloc_seconds( float secs )
+{
+
+    alloc_mem_(( unsigned int )(( float ) aud_info.byte_rate() * secs ));
+
+}
+
+
+
+
+void 
+    audio_membuffer::resize_bytes( unsigned int bytes )
+{
+
+    resize_mem_( bytes );
+
+}
+
+
+
+void 
+    audio_membuffer::resize_seconds( unsigned int secs )
+{
+
+    resize_mem_( aud_info.byte_rate() * secs );
+
+}
+
+
+void 
+    audio_membuffer::resize_seconds( float secs )
+{
+
+    resize_mem_(( unsigned int )
+        (( float )aud_info.byte_rate() * secs )
+        );
+
+}
+
+
+
+
+
+
+///////////////////////////////////////
+///////  Inherited Functions  /////////
+///////////////////////////////////////
+
+
+
+
+
+
+
+void 
+    audio_membuffer::audio_receive
+    ( unsigned char * data, unsigned int size )
+{
+
+
+    //
+    // If there isn't a buffer, allocs memory for
+    // it of size*2, and copies audio data arrival.
+    //
+
+    if (( audio_data == 0 ) || ( buf_size == 0 ))
+    {
+        alloc_mem_( size * 2 );
+
+        memcpy( audio_data, data, size );
+
+        return;
+
+    }
+
+
+
+
+
+    //
+    // If buffer's free memory is < of `size',
+    // we have to realloc buffer memory of
+    // buf_size*2, while free memory is enough
+    // to contain `size' bytes.
+    //
+    // In this case free memory is represented
+    // by `buf_size - bytes_recorded'.
+    //
+
+    unsigned int tot_mem = buf_size,
+        free_mem = buf_size - bytes_received;
+
+
+    if ( free_mem < size )
+    {
+
+        //
+        // Calcs new buffer size.
+        // TODO: flags for other behaviour?
+
+        while ( free_mem < size )
+        {
+            tot_mem *= 2;
+
+            free_mem = tot_mem - bytes_received;
+        }
+
+
+
+        //
+        // Resize buffer memory.
+        //
+
+        resize_mem_( tot_mem );
+
+    }
+
+
+    //
+    // Now we have enough free space in the
+    // buffer, so let's copy audio data arrivals.
+    //
+
+    memcpy( audio_data + bytes_received, data, size );
+
+
+
+
+    if ( audio_arrival )
+        audio_arrival( aud_info.samples_in_bytes( size ));
+
+
+
+}
+
+
+unsigned int 
+    audio_membuffer::read( BYTE * out_buf, unsigned int bytes )
+{
+
+    //
+    // Some checking
+    //
+
+    if ( !audio_data )
+        return 0;
+
+
+    if ( bytes_played_ >= bytes_received )
+        return 0;
+
+
+
+    unsigned int to_play =  
+        bytes_received - bytes_played_;
+
+
+    unsigned int to_copy = 
+        bytes > to_play ? to_play : bytes;
+
+
+    //
+    // Copies the audio data out.
+    //
+
+    if (( out_buf ) && ( to_copy ) && ( audio_data ))
+        memcpy( out_buf, audio_data + bytes_played_, to_copy );
+
+
+    //
+    // Increments the number of total bytes
+    // played (audio data gone out from the
+    // `audio_producer' object).
+    //
+
+    bytes_played_ += bytes;
+
+
+    if ( audio_arrival )
+        audio_arrival( aud_info.samples_in_bytes( bytes ));
+
+
+    //
+    // Returns the exact size of audio data
+    // produced.
+    //
+
+    return to_copy;
+}
+
+
+bool
+    audio_membuffer::finished( void ) 
+{
+    if ( bytes_played_ < bytes_received )
+        return false;
+    else
+        return true;
+}
+
+_AUDIO_NAMESPACE_END_
diff --git a/reactos/base/applications/sndrec32/audio_membuffer.hpp b/reactos/base/applications/sndrec32/audio_membuffer.hpp
new file mode 100644 (file)
index 0000000..4dd2721
--- /dev/null
@@ -0,0 +1,338 @@
+#ifndef _AUDIOMEMBUFFER__H_
+#define _AUDIOMEMBUFFER__H_
+
+
+
+#include "audio_def.hpp"
+#include "audio_receiver.hpp"
+#include "audio_format.hpp"
+#include "audio_producer.hpp"
+
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+class audio_membuffer : public audio_receiver, public audio_producer
+{
+
+
+       
+
+
+       protected:
+
+               BYTE * audio_data;
+               audio_format aud_info;
+               unsigned int buf_size;
+               unsigned int init_size;
+
+
+
+               //
+               // Protected Functions
+               //
+
+
+               //allocs N bytes for the audio buffer.
+               void alloc_mem_( unsigned int );
+
+
+               //frees memory
+               void free_mem_( void );
+
+
+               //resizes memory, and copies old
+               //audio data to new-size memory
+               void resize_mem_( unsigned int );
+
+
+               //truncates and discards unused memory.
+               //`buf_size' will be the same as `bytes_received'.
+               void truncate_( void );
+
+
+
+
+       public:
+
+               
+               void ( * audio_arrival )( unsigned int );
+               void ( * buffer_resized ) ( unsigned int );
+
+               
+               //
+               // Ctors
+               //
+
+               audio_membuffer( void )
+                       : audio_data( 0 ), aud_info( _AUDIO_DEFAULT_FORMAT ),
+                       buf_size( 0 ), init_size( 0 )
+               {  
+                       
+                       //
+                       // Allocs memory for at least 1 or some seconds
+                       // of recording.
+                       //
+                       init_size = ( unsigned int )
+                               (( float )aud_info.byte_rate() * _AUDIO_DEFAULT_BUFSECS );
+
+
+                       alloc_mem_( init_size );
+
+               
+               }
+
+
+
+               audio_membuffer( audio_format aud_fmt )
+                       : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ),
+                       init_size( 0 )
+               {  
+               
+                       //
+                       // Allocs memory for at least 1 or some seconds
+                       // of recording.
+                       //
+                       init_size = ( unsigned int )
+                               (( float )aud_info.byte_rate() * _AUDIO_DEFAULT_BUFSECS );
+
+
+                       alloc_mem_( init_size );
+               
+               }
+
+
+
+
+               audio_membuffer( audio_format aud_fmt, unsigned int seconds )
+                       : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ),
+                       init_size( 0 )
+               {  
+                       
+                       //
+                       // Allocs memory for audio recording
+                       // the specified number of seconds.
+                       //
+                       init_size = aud_info.byte_rate() * seconds;
+                       alloc_mem_( init_size );
+               
+               }
+
+
+
+               audio_membuffer( audio_format aud_fmt, float seconds )
+                       : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ),
+                       init_size( 0 )
+               {  
+                       
+                       //
+                       // Allocs memory for audio recording
+                       // the specified number of seconds.
+                       //
+                       init_size = ( unsigned int )(( float ) aud_info.byte_rate() * 
+                               seconds <= 0 ? 1 : seconds );
+
+
+                       alloc_mem_( init_size );
+               
+               }
+
+
+
+
+               audio_membuffer( unsigned int bytes )
+                       : audio_data( 0 ), aud_info( _AUDIO_DEFAULT_FORMAT ),
+                       buf_size( 0 ), init_size( 0 )
+               {  
+               
+                       //
+                       // Allocs memory for the specified bytes
+                       //
+                       init_size = bytes;
+                       alloc_mem_( init_size );
+               
+               }
+
+
+
+
+               //
+               // Dtor
+               //
+
+               virtual ~audio_membuffer( void )
+               { 
+               
+                       //
+                       // Frees memory and reset values.
+                       //
+
+                       clear();
+               
+               }
+
+
+
+
+
+
+
+
+
+               //
+               // Public functions
+               //
+
+
+
+               //returns the audio buffer size in bytes.
+               unsigned int mem_size( void ) const
+               { return buf_size; }
+
+
+               //returns how many audio data has been
+               //received, in bytes.
+               unsigned int bytes_recorded( void ) const
+               { return bytes_received; }
+
+
+               //returns the integer number of seconds
+               //that the buffer can record
+               unsigned int seconds_total( void ) const
+               { return buf_size / aud_info.byte_rate(); }
+
+
+               //returns the integer number of seconds
+               //that the buffer can record
+               unsigned int seconds_recorded( void ) const
+               { return bytes_received / aud_info.byte_rate(); }
+
+
+               //returns the float number of seconds
+               //that the buffer can record
+               float fseconds_total( void ) const
+               { return ( float )(( float ) buf_size / 
+                                               ( float ) aud_info.byte_rate()); }
+
+
+               //returns the float number of seconds
+               //that has been recorded
+               float fseconds_recorded( void ) const
+               { return ( float )(( float ) bytes_received / 
+                                               ( float ) aud_info.byte_rate()); }
+
+
+               unsigned int total_samples( void ) const
+               {
+
+                       return ( aud_info.samples_in_seconds( fseconds_total() ));
+
+               }
+
+
+               unsigned int samples_received( void ) const
+               {
+
+
+                       return ( aud_info.samples_in_bytes( bytes_received ));
+
+               }
+
+
+
+               //returns a pointer to the audio buffer
+               BYTE * audio_buffer( void ) const
+               { return audio_data; }
+
+
+
+               //frees memory and resets values.
+               void clear( void );
+
+
+               audio_format & audinfo( void ) { return aud_info; }
+
+
+               //discard audio data, resets values,
+               //but, instead of clear() which frees memory,
+               //reset the memory to the initial size, ready
+               //for receiving "new" audio data.
+               void reset( void );
+
+
+               //truncates and discards unused memory.
+               //`buf_size' will be the same as `bytes_received'.
+               void truncate( void )
+               { truncate_( ); }//TODO: fare truncate N bytes
+
+
+               //if there is a buffer, discards current buffer
+               //memory and realloc a new memory buffer with a 
+               //new size expressed in bytes.
+               void alloc_bytes( unsigned int );
+
+
+
+               //if there is a buffer, discards current buffer
+               //memory and realloc a new memory buffer with a 
+               //new size expressed in seconds, integer and float.
+               void alloc_seconds( unsigned int );
+               void alloc_seconds( float );
+
+
+
+               //resizes in bytes the current buffer, 
+               //without discarding previsiously audio data received.
+               void resize_bytes( unsigned int );
+
+
+               //resizes in seconds the current buffer, 
+               //without discarding previsiously audio data received.
+               void resize_seconds( unsigned int );
+               void resize_seconds( float );
+
+
+
+
+
+
+
+               
+               
+               //
+               // Inherited Functions from `audio_receiver'
+               //
+
+               void audio_receive( unsigned char *, unsigned int );
+
+
+
+               
+               //
+               // Inherited Functions from `audio_buffer'
+               //
+
+
+               unsigned int read( BYTE *, unsigned int );
+               bool finished( void );
+               
+
+
+};
+
+
+
+
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+
+#endif //ifdef _AUDIOMEMBUFFER__H_
diff --git a/reactos/base/applications/sndrec32/audio_producer.cpp b/reactos/base/applications/sndrec32/audio_producer.cpp
new file mode 100644 (file)
index 0000000..6afcbb4
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_producer.cpp
+ * PURPOSE:         Audio Format
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+
+#include "StdAfx.h"
+#include "audio_producer.hpp"
+
diff --git a/reactos/base/applications/sndrec32/audio_producer.hpp b/reactos/base/applications/sndrec32/audio_producer.hpp
new file mode 100644 (file)
index 0000000..8fe5348
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef _AUDIOAUDBUF__H_
+#define _AUDIOAUDBUF__H_
+
+
+
+#include "audio_def.hpp"
+
+
+_AUDIO_NAMESPACE_START_
+
+
+class audio_producer
+{
+
+
+       protected:
+               
+               
+               unsigned int bytes_played_;
+
+
+
+
+
+       public:
+
+
+               //
+               // Ctors
+               //
+
+               audio_producer ( ) : bytes_played_( 0 )
+               {  }
+
+
+               
+
+
+
+
+
+               
+               //
+               // Dtor
+               //
+
+               virtual ~audio_producer( void )
+               {  }
+
+
+
+
+               //
+               // Public Functions
+               //
+
+
+               //reads N bytes from the buffer
+               virtual unsigned int read( BYTE *, unsigned int ) = 0;
+
+               virtual bool finished ( void ) = 0;
+
+
+
+
+               unsigned int bytes_played( void ) const
+               {
+                       return bytes_played_;
+               }
+
+
+               void set_position( unsigned int pos )
+               {
+                       bytes_played_ = pos;
+               }
+
+               void set_position_start( void )
+               {
+                       bytes_played_ = 0 ;
+               }
+
+
+
+               void forward( unsigned int bytes )
+               {
+                       bytes_played_ += bytes ;
+               }
+
+
+               void backward( unsigned int bytes )
+               {
+                       bytes_played_ += bytes ;
+               }
+
+               void ( * play_finished )( void );
+
+
+
+
+};
+
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+
+
+#endif //ifdef _AUDIOAUDBUF__H_
diff --git a/reactos/base/applications/sndrec32/audio_receiver.cpp b/reactos/base/applications/sndrec32/audio_receiver.cpp
new file mode 100644 (file)
index 0000000..77b7c3f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_producer.cpp
+ * PURPOSE:         Audio Format
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+#include "stdafx.h"
+#include "audio_receiver.hpp"
+
+
+
+
+_AUDIO_NAMESPACE_START_
+
+_AUDIO_NAMESPACE_END_
diff --git a/reactos/base/applications/sndrec32/audio_receiver.hpp b/reactos/base/applications/sndrec32/audio_receiver.hpp
new file mode 100644 (file)
index 0000000..6d6e693
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef _AUDIORECEIVER_DEF__H_
+#define _AUDIORECEIVER_DEF__H_
+
+
+
+#include "audio_def.hpp"
+
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+
+//TODO: differenziare audio_receiver da audio_sink?
+//TODO: creare un audio_receiver Tee
+
+
+
+
+
+class audio_receiver
+{
+
+               //
+               // The `audio_wavein' class, while is
+               // recording audio, has to access to 
+               // protected members of `audio_receiver'
+               // such as `bytes_received' protected
+               // variable.
+               //
+
+               friend class audio_wavein;
+
+
+
+
+
+
+       protected:
+
+
+               unsigned int bytes_received;
+               unsigned int status;
+
+
+
+       public:
+               
+               
+               //
+               // Ctors
+               //
+
+               audio_receiver( void )
+                       : bytes_received( 0 )
+               {  }
+
+
+
+
+
+               //
+               // Dtor
+               //
+
+               virtual ~audio_receiver( void )
+               {  }
+
+
+
+               
+               //
+               // Public Functions
+               //
+
+               virtual void audio_receive( unsigned char *, unsigned int ) = 0;
+               
+               //virtual void start_rec( void ) = 0;
+               //virtual void stop_rec( void ) = 0;
+
+
+
+               void set_b_received( unsigned int r )
+               { bytes_received = r; }
+};
+
+
+
+
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+
+
+
+#endif //ifdef _AUDIORECEIVER_DEF__H_
diff --git a/reactos/base/applications/sndrec32/audio_resampler_acm.cpp b/reactos/base/applications/sndrec32/audio_resampler_acm.cpp
new file mode 100644 (file)
index 0000000..fa2617a
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_resampler_acm.cpp
+ * PURPOSE:         Audio Resampler
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+#include "stdafx.h"
+#include "audio_resampler_acm.hpp"
+
+_AUDIO_NAMESPACE_START_
+
+
+    /////////////////////////////////////////
+    ///////     Private Functions    ////////
+    /////////////////////////////////////////
+
+
+    void
+    audio_resampler_acm::init_( void )
+{
+
+
+
+    //
+    // Zeroing structures
+    //
+
+    ZeroMemory( &acm_header, sizeof( ACMSTREAMHEADER ));
+    ZeroMemory( &wformat_src, sizeof( WAVEFORMATEX ));
+    ZeroMemory( &wformat_dst, sizeof( WAVEFORMATEX ));
+
+
+
+
+    //
+    // Setting structures sizes
+    //
+
+    acm_header.cbStruct = sizeof( ACMSTREAMHEADER );
+    wformat_src.cbSize = sizeof( WAVEFORMATEX );
+    wformat_dst.cbSize = sizeof( WAVEFORMATEX );
+
+
+
+
+    //
+    // Setting WAVEFORMATEX structure parameters
+    // according to `audio_format' in/out classes
+    //
+
+    wformat_src.wFormatTag = WAVE_FORMAT_PCM;
+    wformat_src.nSamplesPerSec = audfmt_in.sample_rate();
+    wformat_src.nChannels = audfmt_in.channels();
+    wformat_src.wBitsPerSample = audfmt_in.bits();
+    wformat_src.nAvgBytesPerSec =  audfmt_in.byte_rate();
+    wformat_src.nBlockAlign = audfmt_in.block_align();
+
+
+    wformat_dst.wFormatTag = WAVE_FORMAT_PCM;
+    wformat_dst.nSamplesPerSec = audfmt_out.sample_rate();
+    wformat_dst.nChannels = audfmt_out.channels();
+    wformat_dst.wBitsPerSample = audfmt_out.bits();
+    wformat_dst.nAvgBytesPerSec =  audfmt_out.byte_rate();
+    wformat_dst.nBlockAlign = audfmt_out.block_align();
+
+
+
+    //
+    // Init acm structures completed successfull
+    //
+}
+
+
+
+
+
+
+
+
+
+
+
+/////////////////////////////////////////
+///////     Public Functions     ////////
+/////////////////////////////////////////
+
+
+
+
+void
+    audio_resampler_acm::open( void )
+{
+
+
+    MMRESULT err;
+
+
+    //
+    // Opens ACM stream
+    //
+
+    err = acmStreamOpen( &acm_stream, 0, &wformat_src, &wformat_dst, 
+        0, 0, 0, ACM_STREAMOPENF_NONREALTIME );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+        //TODO: throw error
+        printf("acmOpen error: %i\n", err);
+
+    }
+
+
+
+    //
+    // Calcs source buffer lenght
+    //
+
+    src_buflen = ( unsigned int )
+        (( float )audfmt_in.byte_rate() * ( float )buf_secs );
+
+
+
+
+
+
+    //
+    // Calcs destination source buffer lenght
+    // with help of ACM apis
+    //
+
+    err = acmStreamSize( acm_stream, 
+        src_buflen, &dst_buflen, ACM_STREAMSIZEF_SOURCE );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+        //TODO: throw error
+        printf("acmSize error\n");
+
+    }
+
+
+
+    //
+    // Initialize ACMSTREAMHEADER structure,
+    // and alloc memory for source and destination
+    // buffers.
+    //
+
+    acm_header.fdwStatus = 0;
+    acm_header.dwUser = 0;
+
+
+    acm_header.pbSrc = ( LPBYTE ) new BYTE [ src_buflen ];
+    acm_header.cbSrcLength = src_buflen;
+    acm_header.cbSrcLengthUsed = 0;
+    acm_header.dwSrcUser = src_buflen;
+
+
+    acm_header.pbDst = ( LPBYTE ) new BYTE [ dst_buflen ];
+    acm_header.cbDstLength = dst_buflen;
+    acm_header.cbDstLengthUsed = 0;
+    acm_header.dwDstUser = dst_buflen;
+
+
+
+
+    //
+    // Give ACMSTREAMHEADER initialized correctly to the
+    // driver.
+    //
+
+    err = acmStreamPrepareHeader( acm_stream, &acm_header, 0L );
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+        //TODO: throw error
+        printf("prep. header error\n");
+    }
+
+
+
+
+    //
+    // ACM stream successfully opened.
+    //
+
+    stream_opened = true;
+
+}
+
+
+
+
+void
+    audio_resampler_acm::close( void )
+{
+
+
+    MMRESULT err;
+
+
+    if ( acm_stream )
+    {
+
+        if ( acm_header.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED )
+        {
+
+            acm_header.cbSrcLength = src_buflen;
+            acm_header.cbDstLength = dst_buflen;
+
+            err = acmStreamUnprepareHeader( acm_stream, &acm_header, 0L );
+
+
+            if ( err != MMSYSERR_NOERROR )
+            {
+
+                //
+                // Free buffer memory
+                //
+
+                if ( acm_header.pbSrc != 0 )
+                    delete[] acm_header.pbSrc;
+
+                if ( acm_header.pbDst != 0 )
+                    delete[] acm_header.pbDst;
+
+
+                //
+                // Re-init structures
+                //
+
+                init_();
+
+                //
+                // Updating status
+                //
+
+                stream_opened = false;
+
+
+                //TODO: throw error
+
+            }
+        }
+
+
+        err = acmStreamClose( acm_stream, 0 );
+        acm_stream = 0;
+
+        if ( err != MMSYSERR_NOERROR )
+        {
+
+            //
+            // Free buffer memory
+            //
+
+            if ( acm_header.pbSrc != 0 )
+                delete[] acm_header.pbSrc;
+
+            if ( acm_header.pbDst != 0 )
+                delete[] acm_header.pbDst;
+
+
+            //
+            // Re-init structures
+            //
+
+            init_();
+
+
+            //
+            // Updating status
+            //
+
+            stream_opened = false;
+
+
+            //TODO: throw error!
+
+        }
+
+
+    }//if acm_stream != 0
+
+
+
+
+
+
+    //
+    // Free buffer memory
+    //
+
+    if ( acm_header.pbSrc != 0 )
+        delete[] acm_header.pbSrc;
+
+    if ( acm_header.pbDst != 0 )
+        delete[] acm_header.pbDst;
+
+
+    //
+    // Re-init structures
+    //
+
+    init_();
+
+
+    //
+    // Updating status
+    //
+
+    stream_opened = false;
+
+
+
+    //
+    // ACM sream successfully closed.
+    //
+
+
+}
+
+
+
+
+void 
+    audio_resampler_acm::audio_receive( unsigned char * data, unsigned int size )
+{
+
+    MMRESULT err;
+
+    //
+    // Checking for acm stream opened
+    //
+
+    if ( stream_opened )
+    {
+
+
+        //
+        // Copy audio data from extern to
+        // internal source buffer
+        //
+
+        memcpy( acm_header.pbSrc, data, size );
+
+
+        acm_header.cbSrcLength = size;
+        acm_header.cbDstLengthUsed = 0;
+
+        err = acmStreamConvert( acm_stream, &acm_header, ACM_STREAMCONVERTF_BLOCKALIGN );
+
+        if ( err != MMSYSERR_NOERROR )
+        {
+            //TODO: throw error
+            printf("acm convert error\n");
+
+        }
+
+
+        //
+        // Wait for sound conversion
+        //
+
+        while(( ACMSTREAMHEADER_STATUSF_DONE & acm_header.fdwStatus ) == 0 );
+
+
+        printf("Processed successfully %lu bytes of audio.\n", acm_header.cbDstLengthUsed );
+
+
+
+        //
+        // Copy resampled audio, to destination buffer.
+        //
+
+        //memcpy( pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed );
+
+
+    }
+
+}
+
+_AUDIO_NAMESPACE_END_
diff --git a/reactos/base/applications/sndrec32/audio_resampler_acm.hpp b/reactos/base/applications/sndrec32/audio_resampler_acm.hpp
new file mode 100644 (file)
index 0000000..bce7b32
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef _AUDIORESAMPLERACM__H_
+#define _AUDIORESAMPLERACM__H_
+
+
+
+#include "audio_def.hpp"
+#include "audio_receiver.hpp"
+#include "audio_format.hpp"
+
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+//TODO: inherit from a base resampler?
+class audio_resampler_acm : public audio_receiver
+{
+
+       private:
+               void init_( void );
+
+
+       protected:
+
+
+               HACMSTREAM acm_stream;
+               ACMSTREAMHEADER acm_header;
+               DWORD src_buflen;
+               DWORD dst_buflen;
+               bool stream_opened;
+
+               audio_format audfmt_in;
+               audio_format audfmt_out;
+
+               float buf_secs;
+
+               WAVEFORMATEX wformat_src;
+               WAVEFORMATEX wformat_dst;
+
+
+
+
+       public:
+
+
+               //
+               // Ctors
+               //
+
+               audio_resampler_acm( audio_format fmt_in, audio_format fmt_out )
+                       : acm_stream( 0 ), src_buflen( 0 ), dst_buflen( 0 ),
+                       stream_opened( false ), audfmt_in( fmt_in ), audfmt_out( fmt_out ),
+                       buf_secs( _AUDIO_DEFAULT_BUFSECS )
+
+               {   
+               
+
+                       init_();
+               
+               
+               }
+
+
+
+               
+               
+               //
+               // Dtor
+               //
+
+               ~audio_resampler_acm( void )
+               {   }
+
+
+
+               //
+               // Public functions
+               //
+
+               void open( void );
+               void close( void );
+
+
+
+               void audio_receive( unsigned char *, unsigned int );
+
+
+
+};
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+#endif //ifdef _AUDIORESAMPLERACM_H_
diff --git a/reactos/base/applications/sndrec32/audio_wavein.cpp b/reactos/base/applications/sndrec32/audio_wavein.cpp
new file mode 100644 (file)
index 0000000..4d92f24
--- /dev/null
@@ -0,0 +1,880 @@
+/*
+* PROJECT:         ReactOS Sound Record Application
+* LICENSE:         GPL - See COPYING in the top level directory
+* FILE:            base/applications/sndrec32/audio_wavein.cpp
+* PURPOSE:         Audio WaveIn
+* PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+*/
+
+#include "stdafx.h"
+#include "audio_wavein.hpp"
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+    void
+    audio_wavein::init_( void )
+{
+    ZeroMemory(( LPVOID ) &wave_format, 
+        sizeof( WAVEFORMATEX ));
+
+    wave_format.cbSize = sizeof( WAVEFORMATEX );
+
+    wavein_handle = 0;
+    recthread_id = 0;
+    wakeup_recthread = 0;
+
+    buf_secs = _AUDIO_DEFAULT_WAVEINBUFSECS;
+
+
+    status = WAVEIN_NOTREADY;
+}
+
+
+void
+    audio_wavein::alloc_buffers_mem_( unsigned int buffs, float secs )
+{
+
+
+    unsigned int 
+        onebuf_size = 0, tot_size = 0;
+
+
+    //
+    // Release old memory
+    //
+
+    if ( main_buffer )
+        delete[] main_buffer;
+
+
+    if ( wave_headers )
+        delete[] wave_headers;
+
+
+
+    //
+    // Calcs size of the buffers
+    //
+
+    onebuf_size = ( unsigned int )
+        (( float )aud_info.byte_rate() * secs ); 
+
+
+    tot_size = onebuf_size * buffs;
+
+
+
+
+    //
+    // Allocs memory for the audio buffers
+    //
+
+    main_buffer = new BYTE [ tot_size ];
+
+
+
+    //
+    // Allocs memory for the `WAVEHDR' structures.
+    //
+
+    wave_headers = ( WAVEHDR * ) 
+        new BYTE [ sizeof( WAVEHDR ) * buffs ];
+
+
+
+    //
+    // Zeros memory.
+    //
+
+    ZeroMemory( main_buffer, tot_size );
+
+    ZeroMemory( wave_headers, 
+        sizeof( WAVEHDR ) * buffs );
+
+
+    //
+    // Updates total size of the buffers.
+    //
+
+    mb_size = tot_size;
+
+}
+
+
+void 
+    audio_wavein::free_buffers_mem_( void )
+{
+
+
+    //
+    // Frees memory
+    //
+
+    if ( main_buffer )
+        delete[] main_buffer;
+
+
+    if ( wave_headers )
+        delete[] wave_headers;
+
+
+    main_buffer = 0;
+    wave_headers = 0;
+
+}
+
+
+void 
+    audio_wavein::init_headers_( void )
+{
+
+
+
+    //
+    // If there is no memory for memory or
+    // headers, simply return.
+    //
+
+    if (( !wave_headers ) || ( !main_buffer ))
+        return;
+
+
+    //
+    // This is the size for one buffer
+    //
+
+    DWORD buf_sz = mb_size / buffers;
+
+
+
+    //
+    // This is the base address for one buffer
+    //
+
+    BYTE * buf_addr = main_buffer;
+
+
+    //
+    // Initializes headers.
+    //
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        wave_headers[ i ].dwBufferLength = mb_size / buffers;
+        wave_headers[ i ].lpData = ( LPSTR ) buf_addr;
+
+        buf_addr += buf_sz;
+    }
+
+}
+
+
+void 
+    audio_wavein::prep_headers_( void )
+{
+    MMRESULT err;
+    bool error = false;
+
+
+    //
+    // If there is no memory for memory or
+    // headers, throw error.
+    //
+
+    if (( !wave_headers ) 
+        || ( !main_buffer ) || ( !wavein_handle ))
+    {} //TODO: throw error!
+
+
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        err = waveInPrepareHeader( wavein_handle, 
+            &wave_headers[ i ], sizeof( WAVEHDR ));
+
+
+        if ( err != MMSYSERR_NOERROR )
+            error = true;
+
+    }
+
+
+    if ( error )
+        MessageBox( 0, TEXT("waveInPrepareHeader Error."), 0, 0 );
+
+
+
+}
+
+void 
+    audio_wavein::unprep_headers_( void )
+{
+    MMRESULT err;
+    bool error = false;
+
+
+
+    //
+    // If there is no memory for memory or
+    // headers, throw error.
+    //
+
+    if (( !wave_headers ) 
+        || ( !main_buffer ) || ( !wavein_handle ))
+    {} //TODO: throw error!
+
+
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        err = waveInUnprepareHeader( wavein_handle, 
+            &wave_headers[ i ], sizeof( WAVEHDR ));
+
+
+        if ( err != MMSYSERR_NOERROR )
+            error = true;
+
+    }
+
+
+    if ( error )
+        MessageBox( 0, TEXT("waveInUnPrepareHeader Error."), 0, 0 );
+
+}
+
+
+void 
+    audio_wavein::add_buffers_to_driver_( void )
+{
+    MMRESULT err;
+    bool error = false;
+
+
+
+    //
+    // If there is no memory for memory or
+    // headers, throw error.
+    //
+
+    if (( !wave_headers ) 
+        || ( !main_buffer ) || ( !wavein_handle ))
+    {} //TODO: throw error!
+
+
+
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        err = waveInAddBuffer( wavein_handle, 
+            &wave_headers[ i ], sizeof( WAVEHDR ));
+
+
+        if ( err != MMSYSERR_NOERROR )
+            error = true;
+
+    }
+
+
+    if ( error )
+        MessageBox( 0, TEXT("waveInAddBuffer Error."), 0, 0 );
+
+}
+
+
+
+void
+    audio_wavein::close( void ) 
+{
+
+
+
+
+    //
+    // If wavein object is already in the status
+    // NOTREADY, nothing to do. 
+    //
+
+    if ( status == WAVEIN_NOTREADY )
+        return;
+
+
+
+    //
+    // If the wavein is recording,
+    // then stop recording and close it.
+    //
+
+    if ( status == WAVEIN_RECORDING )
+        stop_recording();
+
+
+    //
+    // Updating status.
+    //
+
+    status = WAVEIN_NOTREADY;
+
+
+
+
+    //
+    // Wakeing up recording thread, so it
+    // can receive the `MM_WIM_CLOSE' message
+    // then dies.
+    //
+    if ( wakeup_recthread )
+        SetEvent( wakeup_recthread );
+
+
+
+    //
+    // Closing wavein stream
+    //
+
+    while (( waveInClose( wavein_handle )) 
+        != MMSYSERR_NOERROR ) Sleep( 1 );
+
+
+
+    //
+    // Release buffers memory.
+    //
+
+    free_buffers_mem_();
+
+
+    //
+    // Re-initialize variables to the
+    // initial state.
+    //
+
+    init_();
+
+}
+
+
+void
+    audio_wavein::open( void )
+{
+
+    MMRESULT err;
+    HANDLE recthread_handle = 0;
+
+
+    //
+    // Checkin the status of the object
+    //
+
+    if ( status != WAVEIN_NOTREADY )
+    {} //TODO: throw error
+
+
+
+    //
+    // Creating the EVENT object that will be signaled
+    // when the recording thread has to wake up.
+    //
+
+    wakeup_recthread = 
+        CreateEvent( 0, FALSE, FALSE, 0 );
+
+
+    data_flushed_event = 
+        CreateEvent( 0, FALSE, FALSE, 0 );
+
+
+
+    if (( !wakeup_recthread ) || ( !data_flushed_event ))
+    {
+
+
+        status = WAVEIN_ERR;
+
+        MessageBox( 0, TEXT("Thread Error."), 0, 0 );
+
+        //TODO: throw error
+    }
+
+
+
+    //
+    // Inialize buffers for recording audio 
+    // data from the wavein audio line.
+    //
+
+    alloc_buffers_mem_( buffers, buf_secs );
+    init_headers_();
+
+
+
+
+
+
+    //
+    // Sound format that will be captured by wavein
+    //
+
+    wave_format.wFormatTag = WAVE_FORMAT_PCM;
+
+    wave_format.nChannels = aud_info.channels();
+    wave_format.nSamplesPerSec = aud_info.sample_rate();
+    wave_format.wBitsPerSample = aud_info.bits();
+    wave_format.nBlockAlign = aud_info.block_align();
+    wave_format.nAvgBytesPerSec = aud_info.byte_rate();
+
+
+
+    //
+    // Creating the recording thread
+    //
+
+    recthread_handle = 
+        CreateThread( NULL, 
+        0, 
+        audio_wavein::recording_procedure, 
+        ( PVOID ) this, 
+        0, 
+        &recthread_id 
+        );
+
+
+
+    //
+    // Checking thread handle
+    //
+
+    if ( !recthread_handle )
+    {
+
+        //
+        // Updating status
+        //
+
+        status = WAVEIN_ERR;
+
+        MessageBox( 0, TEXT("Thread Error."), 0, 0 );
+        //TODO: throw error
+
+    }
+
+
+    //
+    // We don't need the thread handle anymore,
+    // so we can close it from now. (We'll just
+    // need the thread ID for the `waveInOpen' API)
+    //
+
+    CloseHandle( recthread_handle );
+
+
+
+    //
+    // Opening audio line wavein
+    //
+
+    err = waveInOpen( &wavein_handle, 
+        0, 
+        &wave_format, 
+        recthread_id, 
+        0, 
+        CALLBACK_THREAD 
+        );
+
+
+    if ( err != MMSYSERR_NOERROR ) 
+    {
+
+
+        //
+        // Updating status
+        //
+
+        status = WAVEIN_ERR;
+
+        if ( err == WAVERR_BADFORMAT )
+            MessageBox( 0, TEXT("waveInOpen Error"), 0, 0 );
+
+
+        //TODO: throw error
+    }
+
+
+    //
+    // Update object status
+    //
+
+    status = WAVEIN_READY;
+
+
+
+    //
+    // Now `audio_wavein' object is ready
+    // for audio recording!
+    //
+}
+
+
+
+void
+    audio_wavein::start_recording( void )
+{
+
+    MMRESULT err;
+    BOOL ev;
+
+
+
+    if (( status != WAVEIN_READY ) 
+        && ( status != WAVEIN_STOP ))
+    {} //TODO: throw error
+
+
+
+
+    //
+    // Updating to the recording status
+    //
+
+    status = WAVEIN_RECORDING;
+
+
+
+
+    //
+    // Let's prepare header of type WAVEHDR that
+    // we will pass to the driver with our
+    // audio informations, and buffer informations.
+    //
+
+    prep_headers_();
+
+
+
+    //
+    // The waveInAddBuffer function sends an input buffer 
+    // to the given waveform-audio input device. 
+    // When the buffer is filled, the application is notified.
+    //
+
+    add_buffers_to_driver_();
+
+
+
+
+
+    //
+    // Signaling event for waking up
+    // the recorder thread.
+    //
+
+    ev = SetEvent( wakeup_recthread );
+
+
+    if ( !ev ) 
+    {
+
+
+        MessageBox( 0, TEXT("Event Error."), 0, 0 );
+
+    }
+
+
+    //
+    // Start recording
+    //
+
+
+    err = waveInStart( wavein_handle );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+
+        //
+        // Updating status
+        //
+
+        status = WAVEIN_ERR;
+
+        MessageBox( 0, TEXT("waveInStart Error."), 0, 0 );
+
+
+        //TODO: throw error
+
+    }
+
+}
+
+
+
+void
+    audio_wavein::stop_recording( void )
+{
+
+
+    MMRESULT err;
+    DWORD wait;
+
+
+    if ( status != WAVEIN_RECORDING )
+        return;
+
+
+
+    status = WAVEIN_FLUSHING;
+
+
+    if ( data_flushed_event )
+        wait = WaitForSingleObject( 
+        data_flushed_event, INFINITE 
+        );
+
+
+
+    //
+    // waveInReset will make all pending buffer as done.
+    //
+
+    err = waveInReset( wavein_handle );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+
+        //TODO: throw error
+
+        MessageBox( 0, TEXT("waveInReset Error."), 0, 0 );
+
+
+
+    }
+
+
+
+    //
+    // Stop recording.
+    //
+
+    err = waveInStop( wavein_handle );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+
+        //TODO: throw error
+
+        MessageBox( 0, TEXT("waveInStop Error."), 0, 0 );
+
+
+
+    }
+
+
+    //
+    // The waveInUnprepareHeader function cleans up the 
+    // preparation performed by the waveInPrepareHeader function. 
+    //
+
+    unprep_headers_();
+
+
+
+
+
+
+
+
+
+
+
+    status = WAVEIN_STOP;
+
+}
+
+
+
+DWORD WINAPI 
+    audio_wavein::recording_procedure( LPVOID arg )
+{
+
+
+    MSG msg;
+    WAVEHDR * phdr;
+    DWORD wait;
+    audio_wavein * _this = ( audio_wavein * ) arg;
+
+
+
+
+    //
+    // Check the arg pointer
+    //
+
+    if ( _this == 0 )
+        return 0;
+
+
+
+    //
+    // The thread can go to sleep for now.
+    // It will be wake up only when there is audio data
+    // to be recorded.
+    //
+
+    if ( _this->wakeup_recthread )
+        wait = WaitForSingleObject( 
+        _this->wakeup_recthread, INFINITE 
+        );
+
+
+
+
+
+
+    //
+    // If status of the `audio_wavein' object 
+    // is not ready or recording the thread can exit.
+    //
+
+    if (( _this->status != WAVEIN_READY ) && 
+        ( _this->status != WAVEIN_RECORDING ))
+        return 0;
+
+
+
+
+
+
+
+    //
+    // Entering main polling loop
+    //
+
+    while ( GetMessage( &msg, 0, 0, 0 ))       
+    {  
+
+        switch ( msg.message )
+        {
+
+        case MM_WIM_DATA:
+
+            phdr = ( WAVEHDR * ) msg.lParam;
+
+            if (( _this->status == WAVEIN_RECORDING ) 
+                || ( _this->status == WAVEIN_FLUSHING ))
+            {
+
+                //
+                // Flushes recorded audio data to 
+                // the `audio_receiver' object.
+                //
+
+                _this->audio_rcvd.audio_receive(
+                    ( unsigned char * )phdr->lpData, 
+                    phdr->dwBytesRecorded 
+                    );
+
+
+                //
+                // Updating `audio_receiver' total
+                // bytes received _AFTER_ calling
+                // `audio_receive' function.
+                //
+
+                _this->audio_rcvd.bytes_received += 
+                    phdr->dwBytesRecorded;
+
+
+
+
+                //
+                // If status is not flushing data, then
+                // we can re-add the buffer for reusing it.
+                // Otherwise, if we are flushing pending data,
+                // we cannot re-add buffer because we don't need
+                // it anymore
+                //
+
+                if ( _this->status != WAVEIN_FLUSHING )
+                {
+
+                    //
+                    // Let the audio driver reuse the buffer
+                    //
+
+                    waveInAddBuffer( _this->wavein_handle, 
+                        phdr, sizeof( WAVEHDR ));
+
+
+                } else {
+
+                    //
+                    // If we are flushing pending data, we have
+                    // to prepare to stop recording.
+                    // Set WAVEHDR flag to 0, and fires the event
+                    // `data_flushed_event', that will wake up
+                    // the main thread that is sleeping into
+                    // wavein_in::stop_recording() member function,
+                    // waiting the last `MM_WIM_DATA' message that
+                    // contain pending data.
+                    //
+
+
+
+
+                    phdr->dwFlags = 0;
+
+                    SetEvent( _this->data_flushed_event );
+
+
+                    //
+                    // The recording is gooing to stop, so the
+                    // recording thread can go to sleep!
+                    //
+
+                    wait = WaitForSingleObject( 
+                        _this->wakeup_recthread, INFINITE );
+
+                }
+
+
+            }//if WAVEIN_RECORDING || WAVEIN_FLUSHING
+
+            break;
+
+
+
+
+
+
+
+
+
+        case MM_WIM_CLOSE:
+
+            //
+            // The thread can exit now.
+            //
+
+            return 0;
+
+            break;
+
+
+
+        }  //end switch( msg.message )
+
+    }  //end while( GetMessage( ... ))
+
+    return 0;                          
+}
+
+
+
+
+
+
+_AUDIO_NAMESPACE_END_
diff --git a/reactos/base/applications/sndrec32/audio_wavein.hpp b/reactos/base/applications/sndrec32/audio_wavein.hpp
new file mode 100644 (file)
index 0000000..3c73077
--- /dev/null
@@ -0,0 +1,271 @@
+#ifndef _AUDIOWAVEIN_H_
+#define _AUDIOWAVEIN_H_
+
+
+
+#include "audio_def.hpp"
+#include "audio_format.hpp"
+#include "audio_receiver.hpp"
+
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+
+enum audio_wavein_status { WAVEIN_NOTREADY, WAVEIN_READY, 
+                                                  WAVEIN_RECORDING, WAVEIN_ERR,
+                                                  WAVEIN_STOP, WAVEIN_FLUSHING
+                                               
+                                                 };
+
+
+
+
+
+class audio_wavein
+{
+       private:
+
+
+
+               //
+               // The new recording thread sends message to this procedure
+               // about open recording, close, and sound data recorded
+               //
+
+               static DWORD WINAPI recording_procedure( LPVOID );
+
+               //
+               // When this event is signaled, then the previsiously created
+               // recording thread will wake up and start recording audio
+               // and will pass audio data to an `audio_receiver' object.
+               //
+
+               HANDLE wakeup_recthread;
+               HANDLE data_flushed_event;
+
+
+
+
+       protected:
+
+
+//TODO: puts these structs in private?!
+
+
+
+
+               //
+               // Audio wavein device stuff
+               //
+
+               WAVEFORMATEX   wave_format;
+               WAVEHDR        * wave_headers;
+               HWAVEIN        wavein_handle;
+
+
+
+       
+
+               audio_format aud_info;
+               
+               audio_receiver & audio_rcvd;
+
+
+               
+               //
+               // Audio Recorder Thread id
+               //
+
+               DWORD     recthread_id;
+
+
+               
+
+               //
+               // Object status
+               //
+
+               audio_wavein_status status;
+
+
+
+
+
+
+
+               //
+               // How many seconds of audio
+               // can record the internal buffer
+               // before flushing audio data 
+               // to the `audio_receiver' class?
+               //
+
+               float buf_secs;
+
+
+               //
+               // The temporary buffers for the audio
+               // data incoming from the wavein device
+               // and its size, and its total number.
+               //
+
+               BYTE * main_buffer;
+               unsigned int mb_size;
+
+               unsigned int buffers;
+
+
+
+
+
+               //
+               // Protected Functions
+               //
+
+
+               //initialize all structures and variables.
+               void init_( void );
+
+               void alloc_buffers_mem_( unsigned int, float );
+               void free_buffers_mem_( void );
+
+               void init_headers_( void );
+               void prep_headers_( void );
+               void unprep_headers_( void );
+               void add_buffers_to_driver_( void );
+
+
+
+
+
+
+
+       public:
+
+
+               //
+               // Ctors
+               //
+
+               audio_wavein(
+                       const audio_format & a_info, audio_receiver & a_receiver )
+
+                       : wave_headers( 0 ),
+                       aud_info( a_info ), audio_rcvd( a_receiver ), 
+                       status( WAVEIN_NOTREADY ), main_buffer( 0 ), mb_size( 0 ),
+                       buffers( _AUDIO_DEFAULT_WAVEINBUFFERS )
+               {
+
+                       //
+                       // Initializing internal wavein data
+                       //
+                       
+                       
+                       init_();
+
+                       aud_info = a_info;
+               }
+
+
+
+
+
+
+
+               //
+               // Dtor
+               //
+
+               ~audio_wavein( void )
+               {
+                       
+                       //close(); TODO!
+
+               }
+
+
+
+               //
+               // Public functions
+               //
+
+               void open( void );
+               void close ( void );
+
+
+               void start_recording( void );
+               void stop_recording( void );
+
+
+
+               audio_wavein_status current_status ( void ) const
+               {
+                       return status;
+               }
+
+               float buffer_secs( void ) const
+               { return buf_secs; }
+
+
+               void buffer_secs( float bsecs )
+               { 
+                       //
+                       // Some checking
+                       //
+
+                       if ( bsecs <= 0 )
+                               return;
+
+
+                       //
+                       // Set seconds lenght for each
+                       // buffer.
+                       //
+
+                       buf_secs = bsecs; 
+               }
+
+
+               unsigned int total_buffers( void ) const
+               { return buffers; }
+
+
+
+               void total_buffers( unsigned int tot_bufs )
+               {
+
+                       //
+                       // Some checking
+                       //
+
+                       if ( tot_bufs == 0 )
+                               return;
+
+                       
+                       //
+                       // Sets the number of total buffers.
+                       //
+
+                       buffers = tot_bufs;
+               }
+
+
+               audio_format format( void ) const
+               { return aud_info; }
+
+
+       
+};
+
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+#endif //ifdef _AUDIOWAVEIN_H_
diff --git a/reactos/base/applications/sndrec32/audio_waveout.cpp b/reactos/base/applications/sndrec32/audio_waveout.cpp
new file mode 100644 (file)
index 0000000..18405b3
--- /dev/null
@@ -0,0 +1,889 @@
+/*
+ * PROJECT:         ReactOS Sound Record Application
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            base/applications/sndrec32/audio_waveout.cpp
+ * PURPOSE:         Audio WaveOut
+ * PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+ */
+
+
+#include "stdafx.h"
+#include "audio_waveout.hpp"
+
+
+_AUDIO_NAMESPACE_START_
+
+
+
+void
+audio_waveout::init_( void )
+{
+
+    ZeroMemory(( LPVOID ) &wave_format, 
+                    sizeof( WAVEFORMATEX ));
+
+    wave_format.cbSize = sizeof( WAVEFORMATEX );
+
+    waveout_handle = 0;
+
+    playthread_id = 0;
+    wakeup_playthread = 0;
+
+    buf_secs = _AUDIO_DEFAULT_WAVEOUTBUFSECS;
+
+
+    status = WAVEOUT_NOTREADY;
+
+}
+
+
+
+
+void 
+audio_waveout::alloc_buffers_mem_( unsigned int buffs, float secs )
+{
+
+
+    unsigned int 
+        onebuf_size = 0, tot_size = 0;
+
+
+    //
+    // Release old memory
+    //
+
+    if ( main_buffer )
+        delete[] main_buffer;
+
+
+    if ( wave_headers )
+        delete[] wave_headers;
+
+
+
+    //
+    // Calcs size of the buffers
+    //
+
+    onebuf_size = ( unsigned int )
+        (( float )aud_info.byte_rate() * secs ); 
+
+
+    tot_size = onebuf_size * buffs;
+
+    
+    
+    
+    //
+    // Allocs memory for the audio buffers
+    //
+
+    main_buffer = new BYTE [ tot_size ];
+
+
+
+    //
+    // Allocs memory for the `WAVEHDR' structures.
+    //
+
+    wave_headers = ( WAVEHDR * ) 
+        new BYTE [ sizeof( WAVEHDR ) * buffs ];
+
+
+
+    //
+    // Zeros memory.
+    //
+
+    ZeroMemory( main_buffer, tot_size );
+
+    ZeroMemory( wave_headers, 
+        sizeof( WAVEHDR ) * buffs );
+
+
+    //
+    // Updates total size of the buffers.
+    //
+
+    mb_size = tot_size;
+}
+
+
+void 
+audio_waveout::init_headers_( void )
+{
+
+
+
+    //
+    // If there is no memory for memory or
+    // headers, simply return.
+    //
+
+    if (( !wave_headers ) || ( !main_buffer ))
+        return;
+
+
+    //
+    // This is the size for one buffer
+    //
+
+    DWORD buf_sz = mb_size / buffers;
+
+
+
+    //
+    // This is the base address for one buffer
+    //
+    
+    BYTE * buf_addr = main_buffer;
+
+
+
+    ZeroMemory( wave_headers, sizeof( WAVEHDR ) * buffers );
+
+
+    //
+    // Initializes headers.
+    //
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        
+        //
+        // Sets the correct base address and 
+        // lenght for the little buffer.
+        //
+
+        wave_headers[ i ].dwBufferLength = mb_size / buffers;
+        wave_headers[ i ].lpData = ( LPSTR ) buf_addr;
+
+        //
+        // Unsets the WHDR_DONE flag.
+        //
+
+        wave_headers[ i ].dwFlags &= ~WHDR_DONE;
+
+
+        
+        //
+        // Sets the WAVEHDR user data with an
+        // unique little buffer ID#
+        //
+
+        wave_headers[ i ].dwUser = ( unsigned int ) i;
+
+        
+        
+        //
+        // Increments little buffer base address.
+        //
+
+        buf_addr += buf_sz;
+    }
+
+}
+
+
+void 
+audio_waveout::prep_headers_( void )
+{
+    MMRESULT err;
+    bool error = false;
+
+
+    //
+    // If there is no memory for memory or
+    // headers, throw error.
+    //
+
+    if (( !wave_headers ) 
+        || ( !main_buffer ) || ( !waveout_handle ))
+    {} //TODO: throw error!
+
+
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        err = waveOutPrepareHeader( waveout_handle, 
+                    &wave_headers[ i ], sizeof( WAVEHDR ));
+
+
+        if ( err != MMSYSERR_NOERROR )
+            error = true;
+
+    }
+    
+
+    if ( error )
+    {} //TODO: throw error indicating which
+      //header i-th is errorneous
+
+
+
+}
+
+void 
+audio_waveout::unprep_headers_( void )
+{
+    MMRESULT err;
+    bool error = false;
+
+
+
+    //
+    // If there is no memory for memory or
+    // headers, throw error.
+    //
+
+    if (( !wave_headers ) 
+        || ( !main_buffer ) || ( !waveout_handle ))
+    {} //TODO: throw error!
+
+
+
+    for ( unsigned int i = 0; i < buffers; ++i )
+    {
+        err = waveOutUnprepareHeader( waveout_handle, 
+                    &wave_headers[ i ], sizeof( WAVEHDR ));
+
+
+        if ( err != MMSYSERR_NOERROR )
+            error = true;
+
+    }
+    
+
+    if ( error )
+    {} //TODO: throw error indicating which
+      //header i-th is errorneous
+
+}
+
+
+
+
+
+
+
+
+
+void 
+audio_waveout::free_buffers_mem_( void )
+{
+
+
+
+    //
+    // Frees memory
+    //
+
+    if ( main_buffer )
+        delete[] main_buffer;
+
+
+    if ( wave_headers )
+        delete[] wave_headers;
+
+
+    main_buffer = 0;
+    wave_headers = 0;
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void 
+audio_waveout::open( void )
+{
+
+    MMRESULT err;
+    HANDLE playthread_handle = 0;
+
+
+    //
+    // Checkin the status of the object
+    //
+
+    if ( status != WAVEOUT_NOTREADY )
+    {} //TODO: throw error
+
+
+    //
+    // Creating the EVENT object that will be signaled
+    // when the playing thread has to wake up.
+    //
+
+    wakeup_playthread = 
+        CreateEvent( 0, FALSE, FALSE, 0 );
+
+    if ( !wakeup_playthread )
+    {
+
+
+        status = WAVEOUT_ERR;
+
+        //TODO: throw error
+    }
+
+
+
+    //
+    // Inialize buffers for recording audio 
+    // data from the wavein audio line.
+    //
+
+    alloc_buffers_mem_( buffers, buf_secs );
+    init_headers_();
+
+
+
+
+
+
+    //
+    // Sound format that will be captured by wavein
+    //
+
+    wave_format.wFormatTag = WAVE_FORMAT_PCM;
+
+    wave_format.nChannels = aud_info.channels();
+    wave_format.nSamplesPerSec = aud_info.sample_rate();
+    wave_format.wBitsPerSample = aud_info.bits();
+    wave_format.nBlockAlign = aud_info.block_align();
+    wave_format.nAvgBytesPerSec = aud_info.byte_rate();
+
+
+
+    //
+    // Creating the recording thread
+    //
+
+    playthread_handle = 
+        CreateThread( NULL, 
+                      0, 
+                      audio_waveout::playing_procedure, 
+                      ( PVOID ) this, 
+                      0, 
+                      &playthread_id 
+            );
+
+    
+
+    //
+    // Checking thread handle
+    //
+
+    if ( !playthread_handle )
+    {
+
+        //
+        // Updating status
+        //
+
+        status = WAVEOUT_ERR;          
+        //TODO: throw error
+
+    }
+
+
+    //
+    // We don't need the thread handle anymore,
+    // so we can close it from now. (We'll just
+    // need the thread ID for the `waveInOpen' API)
+    //
+
+    CloseHandle( playthread_handle );
+
+
+
+    //
+    // Reset the `audio_source' to the start
+    // position.
+    //
+
+    audio_buf.set_position_start();
+
+
+
+
+    //
+    // Opens the WAVE_OUT device.
+    //
+
+    err = waveOutOpen( 
+                &waveout_handle, 
+                WAVE_MAPPER, 
+                &wave_format, 
+                playthread_id, 
+                0, 
+                CALLBACK_THREAD | WAVE_ALLOWSYNC 
+            );
+
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+        MessageBox(0, _T("waveOutOpen Error"), 0, 0);
+        //TODO: throw error
+
+    }
+
+
+
+
+    status = WAVEOUT_READY;
+
+
+}
+
+
+
+void 
+audio_waveout::play( void )
+{
+
+
+    MMRESULT err;
+    unsigned int i;
+    BOOL ev;
+
+
+    if ( !main_buffer )
+    { return; } //TODO; throw error, or assert
+
+
+
+
+    //
+    // If the status is PAUSED, we have to
+    // resume the audio playing.
+    //
+    if ( status == WAVEOUT_PAUSED )
+    {
+
+        //
+        // Updates status.
+        //
+
+        status = WAVEOUT_PLAYING;
+
+
+        //
+        // Tells to the driver to resume
+        // audio playing.
+        //
+
+        waveOutRestart( waveout_handle );
+        
+
+        //
+        // Wakeup playing thread.
+        //
+
+        ev = SetEvent( wakeup_playthread );
+
+        return;
+
+    } //if status == WAVEOUT_PAUSED
+
+
+
+
+
+    if ( status != WAVEOUT_READY ) 
+        return;
+    
+
+
+
+    //
+    // Prepares WAVEHDR structures.
+    //
+
+    prep_headers_();
+
+
+
+    //
+    // Sets correct status.
+    //
+
+    status = WAVEOUT_PLAYING;
+    
+    
+
+    //
+    // Reads the audio from the start.
+    //
+
+    audio_buf.set_position_start();
+
+    
+
+    
+    //
+    // Reads the first N bytes from the audio
+    // buffer, where N = the total size of all
+    // little buffers.
+    //
+
+    audio_buf.read( main_buffer, mb_size );
+
+    
+
+
+
+    
+    //
+    // Wakeup the playing thread.
+    //
+
+    ev = SetEvent( wakeup_playthread );
+
+
+
+
+    //
+    // Sends all the little buffers to the
+    // audio driver, so it can play the sound 
+    // data.
+    //
+
+    for ( i = 0; i < buffers; ++ i )
+    {
+
+        
+        err = waveOutWrite( waveout_handle, &wave_headers[ i ], sizeof( WAVEHDR ));
+
+        if ( err != MMSYSERR_NOERROR )
+        {
+        
+
+            MessageBox(0, _T("waveOutWrite Error"), 0, 0);
+                                
+            //TODO: throw error
+        }
+
+    }
+
+}
+
+
+void 
+audio_waveout::pause( void )
+{
+
+    MMRESULT err;
+
+
+    //
+    // If the waveout object is not playing audio,
+    // do nothing.
+    //
+    
+    if ( status == WAVEOUT_PLAYING )
+    {
+
+        //
+        // Updating status.
+        //
+
+        status = WAVEOUT_PAUSED;
+
+
+        //
+        // Tells to audio driver to pause audio.
+        //
+
+        err = waveOutPause( waveout_handle );
+
+
+        if ( err != MMSYSERR_NOERROR )
+        {
+
+            MessageBox(0, _T("waveOutPause Error"), 0, 0);
+            //TODO: throw error
+
+        }
+
+    }
+
+}
+
+
+void 
+audio_waveout::stop( void )
+{
+
+    MMRESULT err;
+
+
+    status = WAVEOUT_STOP;
+
+
+    err = waveOutReset( waveout_handle );
+
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+
+        MessageBox(0, _T("err waveout reset.\n"),_T("ERROR"), 0);
+        //TODO: throw error
+
+    }
+
+
+
+    //
+    // Sets the start position of the audio
+    // buffer.
+    //
+
+    audio_buf.set_position_start();
+
+
+    unprep_headers_();
+
+
+    init_headers_();
+
+
+    status = WAVEOUT_READY;
+
+}
+
+void
+audio_waveout::close( void )
+{
+
+    MMRESULT err;
+
+
+    //
+    // If the `wave_out' object is playing audio,
+    // or it is in paused state, we have to call
+    // the `stop' member function, to flush 
+    // pending buffers.
+    //
+    
+    if (( status == WAVEOUT_PLAYING ) 
+                    || ( status== WAVEOUT_PAUSED ))
+    {
+    
+        stop();
+
+    }
+
+
+
+    //
+    // When we have flushed all pending buffers,
+    // the wave out handle can be successfully closed.
+    //
+
+    err = waveOutClose( waveout_handle );
+
+
+    if ( err != MMSYSERR_NOERROR )
+    {
+
+        MessageBox(0, _T("waveOutClose Error"), 0, 0);
+        //TODO: throw error
+
+    }
+
+    free_buffers_mem_();
+
+}
+
+
+DWORD WINAPI 
+audio_waveout::playing_procedure( LPVOID arg )
+{
+    MSG msg;
+    WAVEHDR * phdr;
+    DWORD wait;
+    MMRESULT err;
+    audio_waveout * _this = ( audio_waveout * ) arg;
+    unsigned int read_size;
+    
+
+
+    //
+    // Check the arg pointer
+    //
+
+    if ( _this == 0 )
+        return 0;
+
+    
+    
+    //
+    // The thread can go to sleep for now.
+    // It will be wake up only when there is audio data
+    // to be recorded.
+    //
+
+    if ( _this->wakeup_playthread )
+        wait = WaitForSingleObject( 
+                        _this->wakeup_playthread, INFINITE 
+                    );
+
+
+
+    //
+    // Entering main polling loop
+    //
+
+    while ( GetMessage( &msg, 0, 0, 0 ))       
+    {  
+
+        switch ( msg.message )
+        {
+
+            case MM_WOM_DONE:
+            
+                phdr = ( WAVEHDR * ) msg.lParam;
+
+
+                //
+                // If the status of the `wave_out' object
+                // is different than playing, then the thread
+                // can go to sleep.
+                //
+
+                if (( _this->status != WAVEOUT_PLAYING ) 
+                                && ( _this->wakeup_playthread ))
+                {
+                
+                    wait = WaitForSingleObject( 
+                                    _this->wakeup_playthread, 
+                                    INFINITE 
+                                );
+                }
+                
+                //TODO: quando il thread si risveglia, deve
+                //entrare nel prossimo if o no? o metter un else { ?
+
+
+                
+                if ( phdr->dwFlags & WHDR_DONE )
+                {
+                        
+                    read_size = 
+                        _this->audio_buf.read(
+                                        ( BYTE * ) phdr->lpData, 
+                                        phdr->dwBufferLength 
+                                    );
+
+                        
+                    if ( read_size )
+                    {
+                        phdr->dwBufferLength = read_size;
+
+                        phdr->dwFlags &= ~WHDR_DONE;
+
+                        err = waveOutWrite( 
+                                    _this->waveout_handle, 
+                                    phdr, 
+                                    sizeof( WAVEHDR )
+                                );
+
+                        if ( err != MMSYSERR_NOERROR )
+                        {
+                                MessageBox(0, _T("waveOutWrite Error"), 0, 0);
+                                //TODO: throw error
+                        }
+
+
+                    } else {
+
+                        //
+                        // Here `read_sizep' is 0
+                        //
+
+                        if ( phdr->dwUser == ( _this->buffers - 1 ))
+                        {
+
+                            //
+                            // Here `read_size' and the buffer user
+                            // data, that contain a buffer ID#,
+                            // is equal to the number of the total
+                            // buffers - 1. This means that this is the
+                            // _LAST_ little buffer that has been played
+                            // by the audio driver. We can STOP the
+                            // `wave_out' object now, or restart the
+                            // sound playing, if we have a infinite loop.
+                            //
+
+
+                            _this->stop();
+                            
+                            //
+                            // Let the thread go to sleep.
+                            //
+
+                            if ( _this->audio_buf.play_finished )
+                                _this->audio_buf.play_finished();
+                            
+
+                            if ( _this->wakeup_playthread )
+                                    wait = WaitForSingleObject( 
+                                                    _this->wakeup_playthread, 
+                                                    INFINITE 
+                                                );
+
+                        }
+
+                    }  //if read_size != 0
+
+                }  //( phdr->dwFlags & WHDR_DONE )
+                    
+
+                break; // end case
+
+
+
+            case MM_WOM_CLOSE:
+                //
+                // The thread can exit now.
+                //
+
+                return 0;
+
+                break;
+
+
+            case MM_WOM_OPEN:
+                
+                //
+                // Do nothing.
+                //
+
+                break;
+
+
+        }  //end switch( msg.message )
+        
+    }  //end while( GetMessage( ... ))
+
+    return 0;                          
+}
+
+_AUDIO_NAMESPACE_END_
diff --git a/reactos/base/applications/sndrec32/audio_waveout.hpp b/reactos/base/applications/sndrec32/audio_waveout.hpp
new file mode 100644 (file)
index 0000000..fd8debe
--- /dev/null
@@ -0,0 +1,186 @@
+#ifndef _AUDIOWAVEOUT__H_
+#define _AUDIOWAVEOUT__H_
+
+
+#include "audio_def.hpp"
+#include "audio_format.hpp"
+#include "audio_producer.hpp"
+
+
+
+_AUDIO_NAMESPACE_START_
+
+enum audio_waveout_status { WAVEOUT_NOTREADY, WAVEOUT_READY, 
+                                                   WAVEOUT_PLAYING, WAVEOUT_ERR,
+                                                   WAVEOUT_PAUSED, WAVEOUT_STOP
+                                               
+                                                  };
+
+
+class audio_waveout
+{
+
+       friend class audio_buffer;
+
+
+
+       private:
+
+
+               static DWORD WINAPI playing_procedure( LPVOID );
+
+
+               
+               HANDLE wakeup_playthread;
+
+               
+
+
+       protected:
+
+               
+               WAVEFORMATEX   wave_format;
+               WAVEHDR        * wave_headers;
+               HWAVEOUT       waveout_handle;
+
+               
+               
+
+               
+               const audio_format & aud_info;
+               audio_producer & audio_buf;
+
+
+               
+
+
+
+               //
+               // Audio Playing Thread id
+               //
+
+               DWORD     playthread_id;
+
+
+
+
+
+               audio_waveout_status status;
+
+
+
+
+               float buf_secs;
+
+
+
+               //
+               // The temporary buffers for the audio
+               // data outgoing to the waveout device
+               // and its size, and its total number.
+               //
+
+
+               //base address for entire memory
+               BYTE * main_buffer;
+
+               //size in bytes for the entire memory
+               unsigned int mb_size;
+
+               //number of little buffers
+               unsigned int buffers;
+
+
+               
+
+
+
+               //
+               // Protected Functions
+               //
+
+               void init_( void );
+               void alloc_buffers_mem_( unsigned int, float );
+               void free_buffers_mem_( void );
+
+
+               void init_headers_( void );
+               void prep_headers_( void );
+               void unprep_headers_( void );
+
+
+
+               
+
+
+
+       public:
+
+               //
+               // Ctors
+               //
+
+               audio_waveout( const audio_format & aud_fmt,
+                                                               audio_producer & a_buf )
+
+                       : wave_headers( 0 ), aud_info( aud_fmt ),
+                       audio_buf( a_buf ),  status( WAVEOUT_NOTREADY ), 
+                       main_buffer( 0 ), mb_size( 0 ),
+                       buffers( _AUDIO_DEFAULT_WAVEOUTBUFFERS )
+               {
+
+                       //
+                       // Initializing internal wavein data
+                       //
+                       
+                       
+                       init_();
+
+               }
+
+               
+
+
+
+               
+               //
+               // Dtor
+               //
+
+               ~audio_waveout( void )
+               {  }
+
+
+
+
+               //
+               // Public Functions
+               //
+
+               void open  ( void );
+               void play  ( void );
+               void pause ( void );
+               void stop  ( void );
+               void close ( void );
+
+
+               audio_waveout_status current_status( void )
+               { return status; }
+
+
+
+
+
+
+
+
+};
+
+
+
+_AUDIO_NAMESPACE_END_
+
+
+
+
+#endif //ifdef _AUDIOWAVEOUT__H_
diff --git a/reactos/base/applications/sndrec32/bitmap1.bmp b/reactos/base/applications/sndrec32/bitmap1.bmp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/reactos/base/applications/sndrec32/but_end.bmp b/reactos/base/applications/sndrec32/but_end.bmp
new file mode 100644 (file)
index 0000000..036ccb1
Binary files /dev/null and b/reactos/base/applications/sndrec32/but_end.bmp differ
diff --git a/reactos/base/applications/sndrec32/but_play.bmp b/reactos/base/applications/sndrec32/but_play.bmp
new file mode 100644 (file)
index 0000000..112c571
Binary files /dev/null and b/reactos/base/applications/sndrec32/but_play.bmp differ
diff --git a/reactos/base/applications/sndrec32/but_rec.bmp b/reactos/base/applications/sndrec32/but_rec.bmp
new file mode 100644 (file)
index 0000000..3e7249d
Binary files /dev/null and b/reactos/base/applications/sndrec32/but_rec.bmp differ
diff --git a/reactos/base/applications/sndrec32/but_start.bmp b/reactos/base/applications/sndrec32/but_start.bmp
new file mode 100644 (file)
index 0000000..b63ea1d
Binary files /dev/null and b/reactos/base/applications/sndrec32/but_start.bmp differ
diff --git a/reactos/base/applications/sndrec32/but_stop.bmp b/reactos/base/applications/sndrec32/but_stop.bmp
new file mode 100644 (file)
index 0000000..bfb13f1
Binary files /dev/null and b/reactos/base/applications/sndrec32/but_stop.bmp differ
diff --git a/reactos/base/applications/sndrec32/kkaudio.hpp b/reactos/base/applications/sndrec32/kkaudio.hpp
new file mode 100644 (file)
index 0000000..285b1d3
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _AUDIO__H_
+#define _AUDIO__H_
+
+
+#include "audio_def.hpp"
+#include "audio_wavein.hpp"
+#include "audio_waveout.hpp"
+#include "audio_resampler_acm.hpp"
+#include "audio_format.hpp"
+#include "audio_membuffer.hpp"
+#include "audio_producer.hpp"
+#include "audio_receiver.hpp"
+
+
+
+
+#endif //ifdef _KKAUDIO__H_
+
diff --git a/reactos/base/applications/sndrec32/reactOS_sndrec32.ico b/reactos/base/applications/sndrec32/reactOS_sndrec32.ico
new file mode 100644 (file)
index 0000000..d92d91e
Binary files /dev/null and b/reactos/base/applications/sndrec32/reactOS_sndrec32.ico differ
diff --git a/reactos/base/applications/sndrec32/resource.h b/reactos/base/applications/sndrec32/resource.h
new file mode 100644 (file)
index 0000000..d73e558
--- /dev/null
@@ -0,0 +1,44 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by reactOS_sndrec32.rc
+//
+#define IDC_MYICON                      2
+#define IDD_REACTOS_SNDREC32_DIALOG     102
+#define IDS_APP_TITLE                   103
+#define IDD_ABOUTBOX                    103
+#define IDM_ABOUT                       104
+#define IDI_REACTOS_SNDREC32            107
+#define IDI_REACTOS_SNDREC32LL          107
+#define IDI_SMALL                       108
+#define IDC_REACTOS_SNDREC32            109
+#define IDR_MAINFRAME                   128
+#define IDB_BITMAP1                     132
+#define IDB_BITMAP_REC                  132
+#define IDB_BITMAP2_START               133
+#define IDB_BITMAP2_END                 134
+#define IDB_BITMAP2_PLAY                135
+#define IDB_BITMAP2_STOP                136
+#define IDB_BITMAP2_REC                 137
+#define IDI_ICON1                       138
+#define IDR_MENU1                       139
+#define ID_FILE_NEW                     32771
+#define ID_FILE_OPEN                    32772
+#define ID_FILE_SAVE                    32773
+#define ID_FILE_SAVEAS                  32774
+#define ID_FILE_EXIT                    32775
+#define ID__ABOUT                       32776
+#define ID_EXIT                         32777
+#define ID_NEW                          32778
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        140
+#define _APS_NEXT_COMMAND_VALUE         32779
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           110
+#endif
+#endif
diff --git a/reactos/base/applications/sndrec32/small.ico b/reactos/base/applications/sndrec32/small.ico
new file mode 100644 (file)
index 0000000..160edc0
Binary files /dev/null and b/reactos/base/applications/sndrec32/small.ico differ
diff --git a/reactos/base/applications/sndrec32/sndrec32.cpp b/reactos/base/applications/sndrec32/sndrec32.cpp
new file mode 100644 (file)
index 0000000..b1b6a30
--- /dev/null
@@ -0,0 +1,1042 @@
+/*
+* PROJECT:         ReactOS Sound Record Application
+* LICENSE:         GPL - See COPYING in the top level directory
+* FILE:            base/applications/sndrec32/sndrec32.cpp
+* PURPOSE:         Application Startup
+* PROGRAMMERS:     Marco Pagliaricci <ms_blue (at) hotmail (dot) it>
+*/
+
+
+
+#include "stdafx.h"
+#include "sndrec32.h"
+
+#include "kkaudio.hpp"
+
+
+
+HINSTANCE hInst;                                                               
+TCHAR szTitle[MAX_LOADSTRING];                                 
+TCHAR szWindowClass[MAX_LOADSTRING];                   
+
+
+ATOM                           MyRegisterClass(HINSTANCE hInstance);
+BOOL                           InitInstance(HINSTANCE, int);
+LRESULT CALLBACK       WndProc(HWND, UINT, WPARAM, LPARAM);
+INT_PTR CALLBACK       About(HWND, UINT, WPARAM, LPARAM);
+
+
+
+HWND main_win;
+HWND slider;
+HWND buttons[5];
+HBITMAP butbmps[5];
+WNDPROC buttons_std_proc;
+
+BOOL butdisabled[5];
+BOOL stopped_flag;
+BOOL isnew;
+
+
+DWORD slider_pos;
+WORD slider_min;
+WORD slider_max;
+
+long long samples_max;
+
+OPENFILENAME ofn;
+TCHAR file_path[MAX_PATH];
+BOOL path_set;
+
+using snd::audio_membuffer;
+using snd::audio_wavein;
+using snd::audio_waveout;
+
+audio_membuffer * AUD_BUF;
+audio_waveout * AUD_OUT;
+audio_wavein * AUD_IN;
+
+
+BOOL s_recording;
+
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+    HINSTANCE hPrevInstance,
+    LPTSTR    lpCmdLine,
+    int       nCmdShow)
+{
+
+    UNREFERENCED_PARAMETER(hPrevInstance);
+    UNREFERENCED_PARAMETER(lpCmdLine);
+
+
+    MSG msg;
+    HACCEL hAccelTable;
+
+    InitCommonControls();
+
+
+
+
+
+
+
+
+    butbmps[0] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_START ));
+    butbmps[1] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_END ));
+    butbmps[2] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_PLAY ));
+    butbmps[3] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_STOP ));
+    butbmps[4] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_REC ));
+
+
+
+
+
+
+    snd::audio_membuffer AUD_buffer( snd::A44100_16BIT_STEREO );
+    snd::audio_waveout AUD_waveout( snd::A44100_16BIT_STEREO, AUD_buffer );
+    snd::audio_wavein AUD_wavein( snd::A44100_16BIT_STEREO, AUD_buffer );
+
+    AUD_buffer.play_finished = l_play_finished;
+    AUD_buffer.audio_arrival = l_audio_arrival;
+    AUD_buffer.buffer_resized = l_buffer_resized;
+
+    AUD_buffer.alloc_seconds( INITIAL_BUFREC_SECONDS );
+
+    AUD_IN = &AUD_wavein;
+    AUD_OUT = &AUD_waveout;
+    AUD_BUF = &AUD_buffer;
+
+
+
+    slider_pos = 0;
+    slider_min = 0;
+    slider_max = 32767;
+
+
+    stopped_flag = FALSE;
+    path_set = FALSE;
+    isnew = TRUE;
+
+
+
+    samples_max = AUD_buffer.total_samples();
+
+
+
+
+    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
+    LoadString(hInstance, IDC_REACTOS_SNDREC32, szWindowClass, MAX_LOADSTRING);
+    MyRegisterClass(hInstance);
+
+
+    if (!InitInstance (hInstance, nCmdShow))
+    {
+        MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0);
+        return FALSE;
+    }
+
+    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_REACTOS_SNDREC32));
+
+
+
+
+
+
+    s_recording = false;
+
+
+
+
+    AUD_wavein.open();
+    AUD_waveout.open();
+
+
+
+
+
+
+    while (GetMessage(&msg, NULL, 0, 0))
+    {
+        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+    }
+
+    AUD_waveout.close();
+    AUD_wavein.close();
+
+    AUD_buffer.clear();
+
+
+    return (int) msg.wParam;
+}
+
+
+
+
+ATOM MyRegisterClass(HINSTANCE hInstance)
+{
+    WNDCLASSEX wcex;
+
+    wcex.cbSize = sizeof(WNDCLASSEX);
+
+    wcex.style                 = CS_HREDRAW | CS_VREDRAW;
+    wcex.lpfnWndProc   = WndProc;
+    wcex.cbClsExtra            = 0;
+    wcex.cbWndExtra            = 0;
+    wcex.hInstance             = hInstance;
+    wcex.hIcon                 = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_REACTOS_SNDREC32LL));
+    wcex.hCursor               = LoadCursor(NULL, IDC_ARROW);
+    wcex.hbrBackground = (HBRUSH)(16);
+    wcex.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
+    wcex.lpszClassName = szWindowClass;
+    wcex.hIconSm               = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_REACTOS_SNDREC32LL));
+
+
+    return RegisterClassEx(&wcex);
+}
+
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+    HWND hWnd;
+
+    hInst = hInstance;
+
+    hWnd = CreateWindow(
+        szWindowClass, 
+        szTitle, 
+        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
+        CW_USEDEFAULT, 
+        CW_USEDEFAULT, 
+        MAINWINDOW_W, 
+        MAINWINDOW_H, 
+        NULL, NULL, 
+        hInstance, NULL
+        );
+
+    if (!hWnd)
+    {
+        return FALSE;
+    }
+
+    ShowWindow(hWnd, nCmdShow);
+    UpdateWindow(hWnd);
+
+    main_win = hWnd;
+
+
+    return TRUE;
+}
+
+
+//
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    int wmId, wmEvent;
+    RECT rect;
+    PAINTSTRUCT ps;
+    HDC hdc;
+
+
+    //
+    // Checking for global pointers to buffer and
+    // io audio devices.
+    //
+
+    if (( !AUD_IN ) || ( !AUD_OUT ) || ( !AUD_BUF ))
+    {
+        MessageBox( 0, TEXT("Buffer Error"), 0, 0 );
+        return 1;
+    }
+
+
+    switch (message)
+    {
+
+
+    case WM_CREATE:
+
+
+
+        //
+        // Creating ALL the buttons
+        //
+
+        for ( int i = 0; i < 5; ++ i )
+        {
+
+            buttons[i] = CreateWindow( 
+                TEXT("button"), 
+                TEXT(""), 
+                WS_CHILD|WS_VISIBLE| BS_BITMAP, 
+                BUTTONS_CX + ( i * (BUTTONS_W+((i == 0)?0:BUTTONS_SPACE))), 
+                BUTTONS_CY, BUTTONS_W, BUTTONS_H, hWnd, 
+                (HMENU)i, hInst, 0
+                );
+
+            if ( !buttons[i] )
+            {
+                MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0);
+                return FALSE;
+
+            }
+
+            butdisabled[ i ] = TRUE;
+
+
+
+            //
+            // Realize the button bmp image
+            //
+
+            SendMessage(buttons[i], BM_SETIMAGE, ( WPARAM )IMAGE_BITMAP, ( LPARAM )butbmps[i]);
+
+
+            UpdateWindow( buttons[i] );
+
+        }
+
+
+        //
+        // Creating the SLIDER window
+        //
+
+        slider = CreateWindow( 
+            TRACKBAR_CLASS, 
+            TEXT(""), 
+            WS_CHILD|WS_VISIBLE|TBS_NOTICKS|TBS_HORZ|TBS_ENABLESELRANGE, 
+            SLIDER_CX, SLIDER_CY, SLIDER_W, SLIDER_H, hWnd, 
+            (HMENU)SLIDER_ID, hInst, 0
+            );
+
+
+        if ( !slider )
+        {
+            MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0);
+            return FALSE;
+
+        }
+
+
+        //
+        // Sets slider limits
+        //
+
+        //slider_min = 0;
+        //slider_max = 100;
+
+        SendMessage( 
+            slider, 
+            TBM_SETRANGE,
+            (WPARAM)TRUE, 
+            (LPARAM)MAKELONG(slider_min,slider_max)
+            );
+
+
+        UpdateWindow( slider );
+
+
+        //
+        // Enables REC button.
+        //
+
+        butdisabled[ BUTREC_ID ] = FALSE;
+
+
+
+
+        break;
+
+
+
+        //
+        // Implements slider logic
+        //
+
+    case WM_HSCROLL :
+        {
+            switch( LOWORD( wParam ))
+            {
+
+            case SB_ENDSCROLL:
+                break;
+
+            case SB_PAGERIGHT:
+            case SB_PAGELEFT:
+            case TB_THUMBTRACK:
+                slider_pos = SendMessage(slider, TBM_GETPOS, 0, 0); 
+                break;
+
+            }
+
+            break;
+        }
+
+
+
+
+
+
+    case WM_COMMAND:
+
+        wmId    = LOWORD(wParam);
+        wmEvent = HIWORD(wParam);
+
+        if (( wmId >= 0 ) && ( wmId < 5 ) && (butdisabled[wmId] == TRUE))
+            break;
+
+        switch (wmId)
+        {
+
+        case ID_NEW:
+
+            if ( !isnew )
+            {
+
+                if ( AUD_IN->current_status() == snd::WAVEIN_RECORDING )
+                    AUD_IN->stop_recording();
+
+
+                if (( AUD_OUT->current_status() == snd::WAVEOUT_PLAYING ) ||
+                    ( AUD_OUT->current_status() == snd::WAVEOUT_PAUSED ))
+                    AUD_OUT->stop();
+
+
+                AUD_BUF->reset();
+
+                butdisabled[ BUTREC_ID   ] = FALSE;
+                butdisabled[ BUTSTART_ID ] = TRUE;
+                butdisabled[ BUTEND_ID   ] = TRUE;
+                butdisabled[ BUTSTOP_ID  ] = TRUE;
+                butdisabled[ BUTPLAY_ID  ] = TRUE;
+
+                samples_max = AUD_BUF->total_samples();
+                slider_pos = 0;
+
+                SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos);
+
+            }
+
+
+
+            break;
+
+
+
+
+        case ID_FILE_OPEN:
+
+            ZeroMemory( &ofn, sizeof( ofn ));
+
+            ofn.lStructSize = sizeof( ofn );
+            ofn.hwndOwner = hWnd;
+            ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0");
+            ofn.lpstrFile = file_path;
+            ofn.nMaxFile = MAX_PATH;
+            ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+            ofn.lpstrDefExt = TEXT("wav");
+
+            if( GetOpenFileName( &ofn ))
+            {
+                open_wav( file_path );
+            }
+
+            break;
+
+
+
+
+        case ID__ABOUT:
+
+
+
+            break;
+
+
+        case ID_FILE_SAVEAS:
+
+            ZeroMemory( &ofn, sizeof( ofn ));
+
+            ofn.lStructSize = sizeof( ofn );
+            ofn.hwndOwner         = hWnd ;
+            ofn.Flags             = OFN_OVERWRITEPROMPT;
+            ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0");
+            ofn.lpstrFile = file_path;
+            ofn.nMaxFile = MAX_PATH;
+
+            ofn.lpstrDefExt = TEXT("wav");
+
+            if ( GetSaveFileName ( &ofn )) 
+            {
+
+                write_wav( file_path );
+
+            }
+
+            break;
+
+        case ID_EXIT:
+            DestroyWindow( hWnd );
+            break;
+
+
+            //
+            // Sndrec32 buttons routines
+            //
+
+        case BUTSTART_ID:
+            Beep(200,200);
+            break;
+
+
+        case BUTEND_ID:
+            Beep(300,200);
+            break;
+
+        case BUTPLAY_ID:
+
+            AUD_OUT->play();
+
+            butdisabled[ BUTSTART_ID ] = TRUE;
+            butdisabled[ BUTEND_ID   ] = TRUE;
+            butdisabled[ BUTREC_ID   ] = TRUE;
+            butdisabled[ BUTPLAY_ID  ] = TRUE;
+
+            SetTimer( hWnd, 1, 250, 0 );
+
+            break;
+
+        case BUTSTOP_ID:
+            if ( s_recording )
+            {
+                s_recording = FALSE;
+
+                AUD_IN->stop_recording();
+
+                butdisabled[ BUTSTART_ID ] = FALSE;
+                butdisabled[ BUTEND_ID   ] = FALSE;
+                butdisabled[ BUTREC_ID   ] = FALSE;
+                butdisabled[ BUTPLAY_ID  ] = FALSE;
+
+
+
+                //
+                // Resetting slider position
+                //
+
+                slider_pos = 0;
+                SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos);
+
+
+                samples_max = AUD_BUF->samples_received();
+
+                EnableMenuItem((HMENU)IDR_MENU1, ID_FILE_SAVEAS, MF_ENABLED );
+
+            } else {
+
+                AUD_OUT->pause();
+
+                butdisabled[ BUTSTART_ID ] = FALSE;
+                butdisabled[ BUTEND_ID   ] = FALSE;
+                butdisabled[ BUTREC_ID   ] = FALSE;
+                butdisabled[ BUTPLAY_ID  ] = FALSE;
+
+            }
+
+            KillTimer( hWnd, 1 );
+
+            break;
+
+        case BUTREC_ID:
+
+            s_recording = TRUE;
+
+            samples_max = AUD_BUF->total_samples();
+
+            AUD_IN->start_recording();
+
+            butdisabled[ BUTSTOP_ID  ] = FALSE;
+            butdisabled[ BUTSTART_ID ] = TRUE;
+            butdisabled[ BUTEND_ID   ] = TRUE;
+            butdisabled[ BUTREC_ID   ] = TRUE;
+            butdisabled[ BUTPLAY_ID  ] = TRUE;
+
+            isnew = FALSE;
+
+
+
+            SetTimer( hWnd, 1, 150, 0 );
+
+            break;
+
+
+        default:
+            return DefWindowProc(hWnd, message, wParam, lParam);
+        }
+        break;
+
+
+    case WM_TIMER:
+
+        if ( stopped_flag )
+        {
+            KillTimer(hWnd, 1);
+            slider_pos = 0;
+
+            butdisabled[ BUTPLAY_ID ] = FALSE;
+
+            stopped_flag = FALSE;
+        }
+
+        SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos);
+
+
+
+        break;
+
+
+
+    case WM_PAINT:
+
+        InvalidateRect( hWnd, &rect, TRUE );
+        hdc = BeginPaint(hWnd, &ps);
+
+        EndPaint(hWnd, &ps);
+        break;
+    case WM_DESTROY:
+        PostQuitMessage(0);
+        break;
+    default:
+        return DefWindowProc(hWnd, message, wParam, lParam);
+    }
+    return 0;
+}
+
+
+BOOL open_wav( TCHAR * f )
+{
+
+
+    HANDLE file;
+
+    riff_hdr r;
+    wave_hdr w;
+    data_chunk d;
+
+    BOOL b;
+
+    DWORD bytes_recorded_in_wav = 0;
+    DWORD is_read = 0;
+
+
+
+
+    file = CreateFile( 
+        f, 
+        GENERIC_READ, 
+        0, 0,
+        OPEN_EXISTING,
+        FILE_ATTRIBUTE_NORMAL, 
+        0 
+        );
+
+
+
+    if ( !file )
+    {
+        MessageBox( 
+            main_win, 
+            TEXT("Cannot open file. CreateFile() error."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        return FALSE;
+
+    }
+
+
+    b = ReadFile( file, ( LPVOID ) &r, sizeof ( r ), &is_read, 0 );
+
+    if ( !b )
+    {
+        DWORD t = GetLastError();
+        TCHAR p[100];
+        wsprintf(p,TEXT("Errore n: %i"),t);
+
+        MessageBox( 
+            main_win, 
+            //TEXT("Cannot read RIFF header."), 
+            p,
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+        return FALSE;
+
+    }
+
+
+    b = ReadFile( file, ( LPVOID ) &w, sizeof ( w ), &is_read, 0 );
+
+
+    if ( !b )
+    {
+
+        MessageBox( 
+            main_win, 
+            TEXT("Cannot read WAVE header."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+        return FALSE;
+
+    }
+
+
+
+    b = ReadFile( file, ( LPVOID ) &d, sizeof ( d ), &is_read, 0 );
+
+    if ( !b )
+    {
+
+        MessageBox( 
+            main_win, 
+            TEXT("Cannot read WAVE subchunk."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+        return FALSE;
+
+    }
+
+    bytes_recorded_in_wav = r.chunksize - 36;
+
+
+    /*
+    unsigned char * gg = (unsigned char*)&bytes_recorded_in_wav;
+
+    gg[0] = gg[3];
+    gg[1] = gg[2];
+
+    bytes_recorded_in_wav = (DWORD) *gg;
+
+
+
+    TCHAR p [100];
+    wsprintf(p,TEXT("bytes: %i"),bytes_recorded_in_wav);
+    MessageBox(0,p,0,0);
+
+    */
+
+    if ( bytes_recorded_in_wav == 0 )
+    {
+
+        MessageBox( 
+            main_win, 
+            TEXT("Cannot read file. No audio data."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+        return FALSE;
+
+    }
+
+
+    snd::audio_format openfmt
+        ( w.SampleRate, w.BitsPerSample, w.NumChannels );
+
+
+
+    AUD_BUF->clear();
+
+
+    AUD_BUF->alloc_bytes( bytes_recorded_in_wav );
+
+
+    b = ReadFile(
+        file, 
+        ( LPVOID ) AUD_BUF->audio_buffer(), 
+        bytes_recorded_in_wav,
+        &is_read,
+        0
+        );
+
+
+    AUD_BUF->set_b_received( bytes_recorded_in_wav );
+
+
+    if (( !b ) || ( is_read != bytes_recorded_in_wav ))
+    {
+
+        MessageBox( 
+            main_win, 
+            TEXT("Cannot read file. Error reading audio data."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+
+        AUD_BUF->reset();
+        return FALSE;
+
+    }
+
+    CloseHandle( file );
+
+    butdisabled[ BUTPLAY_ID ] = FALSE;
+    butdisabled[ BUTSTOP_ID ] = FALSE;
+    butdisabled[ BUTEND_ID   ] = FALSE;
+    butdisabled[ BUTSTART_ID   ] = FALSE;
+    butdisabled[ BUTREC_ID   ] = FALSE;
+
+
+
+    samples_max = AUD_BUF->samples_received();
+
+    isnew = FALSE;
+
+    return TRUE;
+
+}
+
+
+BOOL
+    write_wav( TCHAR * f )
+{
+
+    HANDLE file;
+
+
+    DWORD written;
+    BOOL is_writ;
+    int i;
+    riff_hdr r;
+    wave_hdr w;
+    data_chunk d;
+
+
+
+    file = CreateFile( 
+        f, 
+        GENERIC_WRITE, 
+        0, 0,
+        CREATE_NEW,
+        FILE_ATTRIBUTE_NORMAL, 
+        0 
+        );
+
+
+
+    if ( !file )
+    {
+        i = MessageBox( 
+            main_win, 
+            TEXT("File already exist. Overwrite it?"), 
+            TEXT("Warning"), 
+            MB_YESNO|MB_ICONQUESTION
+            );
+
+        if ( i == IDYES )
+        {
+
+            file = CreateFile( 
+                f, 
+                GENERIC_WRITE, 
+                0, 0,
+                CREATE_ALWAYS,
+                FILE_ATTRIBUTE_NORMAL, 
+                0 
+                );
+
+            if ( !file )
+            {
+                MessageBox( 
+                    main_win, 
+                    TEXT("File Error, CreateFile() failed."), 
+                    TEXT("ERROR"), 
+                    MB_OK|MB_ICONERROR
+                    );
+
+
+                return FALSE;
+
+            }
+
+
+        } else
+            return FALSE;
+    }
+
+
+
+
+    r.magic = 0x46464952;
+
+
+    r.format = 0x45564157;
+    r.chunksize = 36 + AUD_BUF->bytes_recorded();
+
+
+    w.Subchunkid = 0x20746d66;
+
+    w.Subchunk1Size = 16;
+    w.AudioFormat = 1;
+    w.NumChannels = AUD_BUF->audinfo().channels();
+    w.SampleRate = AUD_BUF->audinfo().sample_rate();
+    w.ByteRate = AUD_BUF->audinfo().byte_rate();
+    w.BlockAlign = AUD_BUF->audinfo().block_align();
+    w.BitsPerSample = AUD_BUF->audinfo().bits();
+
+
+    d.subc = 0x61746164;
+    d.subc_size = AUD_BUF->bytes_recorded();
+
+
+
+    //
+    // Writing headers
+    //
+
+
+    is_writ = WriteFile( file, ( LPCVOID ) &r, sizeof ( r ), &written, 0 );
+
+    if ( !is_writ )
+    {
+        MessageBox( 
+            main_win, 
+            TEXT("File Error, WriteFile() failed."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+
+        return FALSE;
+
+    }
+
+
+    is_writ = WriteFile( file, ( LPCVOID ) &w, sizeof ( w ), &written, 0 );
+
+    if ( !is_writ )
+    {
+        MessageBox( 
+            main_win, 
+            TEXT("File Error, WriteFile() failed."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+
+        return FALSE;
+
+    }
+
+
+    is_writ = WriteFile( file, ( LPCVOID ) &d, sizeof ( d ), &written, 0 );
+
+
+    if ( !is_writ )
+    {
+        MessageBox( 
+            main_win, 
+            TEXT("File Error, WriteFile() failed."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+
+        return FALSE;
+
+    }
+
+
+
+    is_writ = WriteFile( 
+        file, 
+        ( LPCVOID ) AUD_BUF->audio_buffer(), 
+        AUD_BUF->bytes_recorded(), 
+        &written, 
+        0 
+        );
+
+    if ( !is_writ )
+    {
+        MessageBox( 
+            main_win, 
+            TEXT("File Error, WriteFile() failed."), 
+            TEXT("ERROR"), 
+            MB_OK|MB_ICONERROR
+            );
+
+        CloseHandle( file );
+
+        return FALSE;
+
+    }
+
+
+    CloseHandle( file );
+
+    return TRUE;
+}
+
+
+
+void l_play_finished ( void )
+{
+
+    stopped_flag = true;
+
+
+
+}
+
+void l_audio_arrival ( unsigned int samples_arrival )
+{
+
+
+    slider_pos += (DWORD) (( slider_max * samples_arrival ) / samples_max );
+
+
+}
+
+void l_buffer_resized ( unsigned int new_size )
+{
+
+
+
+
+
+}
+
+VOID enable_but( DWORD id )
+{
+
+
+
+
+
+}
+VOID disable_but( DWORD id )
+{
+
+
+
+}
+
+
diff --git a/reactos/base/applications/sndrec32/sndrec32.h b/reactos/base/applications/sndrec32/sndrec32.h
new file mode 100644 (file)
index 0000000..530e53e
--- /dev/null
@@ -0,0 +1,96 @@
+#pragma once
+
+#include "resource.h"
+
+
+
+#define MAX_LOADSTRING 100
+
+#define MAINWINDOW_W 350
+#define MAINWINDOW_H 190
+
+
+#define CONTROLS_CX 10
+
+#define INITIAL_BUFREC_SECONDS 30.0f
+
+
+#define BUTSTART_ID 0
+#define BUTEND_ID 1
+#define BUTPLAY_ID 2
+#define BUTSTOP_ID 3
+#define BUTREC_ID 4
+#define SLIDER_ID 5
+
+#define BUTTONS_H 30
+#define BUTTONS_W 60
+#define BUTTONS_CY 100
+#define BUTTONS_CX CONTROLS_CX
+#define BUTTONS_SPACE 5
+
+
+#define SLIDER_CX CONTROLS_CX
+#define SLIDER_CY 65
+#define SLIDER_H 30
+#define SLIDER_W 320
+
+
+
+
+struct riff_hdr
+{
+       DWORD magic;
+       DWORD chunksize;
+       DWORD format;
+};
+
+
+struct wave_hdr
+{
+       
+       DWORD Subchunkid;
+       DWORD Subchunk1Size;
+       WORD AudioFormat;
+       WORD NumChannels;
+       DWORD SampleRate;
+       DWORD ByteRate;
+       WORD BlockAlign;
+       WORD BitsPerSample;
+};
+
+struct data_chunk
+{
+       DWORD subc;
+       DWORD subc_size;
+       //unsigned char data[];
+};
+
+
+
+//
+// Functions prototypes
+//
+LRESULT CALLBACK 
+Buttons_proc(HWND, UINT, WPARAM, LPARAM);
+
+
+BOOL
+write_wav( TCHAR * );
+
+BOOL
+open_wav( TCHAR * );
+
+
+VOID enable_but( DWORD );
+VOID disable_but( DWORD );
+
+
+
+void 
+l_play_finished ( void );
+
+void 
+l_audio_arrival ( unsigned int );
+
+void 
+l_buffer_resized ( unsigned int );
diff --git a/reactos/base/applications/sndrec32/sndrec32.rbuild b/reactos/base/applications/sndrec32/sndrec32.rbuild
new file mode 100644 (file)
index 0000000..2915551
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="sndrec32" type="win32gui" installbase="system32" installname="sndrec32.exe">
+       <include base="sndrec32">.</include>
+       <library>winmm</library>
+       <library>user32</library>
+       <library>kernel32</library>
+       <library>msacm32</library>
+       <library>comctl32</library>
+       <library>comdlg32</library>
+       <file>audio_format.cpp</file>
+       <file>audio_membuffer.cpp</file>
+       <file>audio_producer.cpp</file>
+       <file>audio_receiver.cpp</file>
+       <file>audio_resampler_acm.cpp</file>
+       <file>audio_wavein.cpp</file>
+       <file>audio_waveout.cpp</file>
+       <file>sndrec32.cpp</file>
+       <file>sndrec32.rc</file>
+</module>
diff --git a/reactos/base/applications/sndrec32/sndrec32.rc b/reactos/base/applications/sndrec32/sndrec32.rc
new file mode 100644 (file)
index 0000000..e4de736
--- /dev/null
@@ -0,0 +1,179 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Italiano (Italia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)
+#ifdef _WIN32
+LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_REACTOS_SNDREC32LL  ICON                    "reactOS_sndrec32.ico"
+IDI_SMALL               ICON                    "small.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDC_REACTOS_SNDREC32 ACCELERATORS 
+BEGIN
+    "?",            IDM_ABOUT,              ASCII,  ALT
+    "/",            IDM_ABOUT,              ASCII,  ALT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 196, 75
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Informazioni su reactOS_sndrec32"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    ICON            128,IDC_REACTOS_SNDREC32,19,14,21,20
+    LTEXT           "reactOS_sndrec32, versione 1.0",IDC_STATIC,56,16,114,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2009",IDC_STATIC,55,25,114,8
+    DEFPUSHBUTTON   "OK",IDOK,139,54,50,14,WS_GROUP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 189
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 68
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP2_START       BITMAP                  "but_start.bmp"
+IDB_BITMAP2_END         BITMAP                  "but_end.bmp"
+IDB_BITMAP2_PLAY        BITMAP                  "but_play.bmp"
+IDB_BITMAP2_STOP        BITMAP                  "but_stop.bmp"
+IDB_BITMAP2_REC         BITMAP                  "but_rec.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU 
+BEGIN
+    POPUP "File"
+    BEGIN
+        MENUITEM "New",                         ID_NEW
+        MENUITEM "Open...",                     ID_FILE_OPEN
+        MENUITEM "Save",                        ID_FILE_SAVE, GRAYED
+        MENUITEM "Save As...",                  ID_FILE_SAVEAS
+        MENUITEM SEPARATOR
+        MENUITEM "Exit",                        ID_EXIT
+    END
+    MENUITEM "todo1",                       0
+    MENUITEM "todo2",                       0
+    POPUP "?"
+    BEGIN
+        MENUITEM "About...",                    ID__ABOUT
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_APP_TITLE           "reactOS_sndrec32"
+    IDC_REACTOS_SNDREC32    "REACTOS_SNDREC32"
+END
+
+#endif    // Italiano (Italia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/reactos/base/applications/sndrec32/stdafx.h b/reactos/base/applications/sndrec32/stdafx.h
new file mode 100644 (file)
index 0000000..69ca286
--- /dev/null
@@ -0,0 +1,23 @@
+// stdafx.h : file di inclusione per file di inclusione di sistema standard
+// o file di inclusione specifici del progetto utilizzati di frequente, ma
+// modificati raramente
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#define WIN32_LEAN_AND_MEAN             // Escludere gli elementi utilizzati di rado dalle intestazioni di Windows
+// File di intestazione di Windows:
+#include <windows.h>
+#include <commctrl.h>
+#include <Commdlg.h>
+
+// File di intestazione Runtime C
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+
+
+// TODO: fare riferimento qui alle intestazioni aggiuntive richieste dal programma
diff --git a/reactos/base/applications/sndrec32/targetver.h b/reactos/base/applications/sndrec32/targetver.h
new file mode 100644 (file)
index 0000000..92426c6
--- /dev/null
@@ -0,0 +1,24 @@
+#pragma once
+
+// Le macro seguenti definiscono la piattaforma minima richiesta. La piattaforma minima richiesta
+// è costituita dalla versione meno recente di Windows, Internet Explorer e così via contenenti le funzionalità necessarie per eseguire 
+// l'applicazione. Le macro consentono di attivare tutte le funzionalità disponibili nelle versioni delle piattaforme fino 
+// alla versione specificata compresa.
+
+// Modificare le seguenti definizioni se è necessario utilizzare come destinazione una piattaforma prima di quelle specificate di seguito.
+// Fare riferimento a MSDN per informazioni aggiornate sui valori corrispondenti per le differenti piattaforme.
+#ifndef WINVER                          // Specifica che la piattaforma minima richiesta è Windows Vista.
+#define WINVER 0x0600           // Modificare il valore con quello appropriato per altre versioni di Windows.
+#endif
+
+#ifndef _WIN32_WINNT            // Specifica che la piattaforma minima richiesta è Windows Vista.
+#define _WIN32_WINNT 0x0600     // Modificare il valore con quello appropriato per altre versioni di Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS          // Specifica che la piattaforma minima richiesta è Windows 98.
+#define _WIN32_WINDOWS 0x0410 // Modificare il valore con quello appropriato per Windows Me o versioni successive.
+#endif
+
+#ifndef _WIN32_IE                       // Specifica che la piattaforma minima richiesta è Internet Explorer 7.0.
+#define _WIN32_IE 0x0700        // Modificare il valore con quello appropriato per altre versioni di IE.
+#endif