diff --git a/ChangeLog b/ChangeLog index beee8c39e9..1841623e79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2005-12-20 Danny McRae + + * include/pattern.h: + * src/tracks/pattern.cpp: + be able to change volume of step in bb-editor via mouse wheel and + change color of step-button accordingly + +2005-12-20 Tobias Doerffel + + * src/lib/sample_buffer.cpp: + first implementation of FLAC-encoding/decoding for compressing buffers + before encoding them to base64 which results in smaller XML-files - + currently disabled as it's still buggy and unusable + + * src/lib/buffer_allocator.cpp: + in cleanup-method use list instead of vector for pool of buffers to be + removed - fixes crash with Qt4 + 2005-12-19 Tobias Doerffel * src/widgets/knob.cpp: @@ -717,7 +735,7 @@ * src/soundgenerators/*.cpp: removed obsolete defaultSettings()-method from each soundgenerator -2005-10-13 Dany McRae +2005-10-13 Danny McRae * include/ladspa_manager.h * include/ladspa_sine_1063.h @@ -725,7 +743,7 @@ * src/soundgenerators/ladspa_sine_1063.cpp: added LADSPA-support and a simple soundgenerator for testing-purposes -2005-10-12 Dany McRae +2005-10-12 Danny McRae * Makefile.am: * include/led_checkbox.h: @@ -734,7 +752,7 @@ inherit ledCheckBox from QWidget instead of QCheckBox since it sometimes caused graphic-errors when running on KDE with Baghira-style... -2005-10-05 Dany McRae +2005-10-05 Danny McRae * resources/note_double_whole.png: * resources/note_eighth.png: @@ -1113,7 +1131,7 @@ tell config-manager to save it's config-file when setupDialog is destroyed -2005-09-13 Stephane Thomas +2005-09-13 Stephane Thomas * locale/fr.ts: added French translation @@ -1231,7 +1249,7 @@ - use macro AS_HELP_STRING for formatting help-strings - removed --with-latency option as it is not needed anymore -2005-09-06 Alireza +2005-09-06 Alireza * resources/ir.ts: added Persian translation @@ -1279,8 +1297,8 @@ added value() and setValue()-method which offers all components of LMMS an easy way for loading/saving their settings at startup/exit -2005-09-02 Mario Izquierdo -2005-09-02 Johnny Saenz +2005-09-02 Mario Izquierdo +2005-09-02 Johnny Saenz * resources/es.ts: added Spanish translation @@ -1531,7 +1549,7 @@ * src/core/track.cpp: removed unsused method setTrackWidgetHeight( int ) -2005-07-26 Pedro Lopez-Cabanillas +2005-07-26 Pedro Lopez-Cabanillas * src/core/browser.cpp: * src/core/config_mgr.cpp: @@ -1574,7 +1592,7 @@ max-value after starting up LMMS - go to start of pattern when pressing home-key -2005-07-23 Alexey Kouznetsov +2005-07-23 Alexey Kouznetsov * resources/ru.ts: added Russian translation diff --git a/include/pattern.h b/include/pattern.h index 2828e1950f..ca190cd411 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -180,6 +180,7 @@ protected: virtual void constructContextMenu( QMenu * ); virtual void mouseDoubleClickEvent( QMouseEvent * _me ); virtual void mousePressEvent( QMouseEvent * _me ); + virtual void wheelEvent( QWheelEvent * _we ); virtual void paintEvent( QPaintEvent * _pe ); void ensureBeatNotes( void ); @@ -189,6 +190,7 @@ protected: private: static QPixmap * s_patternBg; static QPixmap * s_stepBtnOn; + static QPixmap * s_stepBtnOverlay; static QPixmap * s_stepBtnOff; static QPixmap * s_stepBtnOffLight; static QPixmap * s_frozen; diff --git a/resources/step_btn_on_100.png b/resources/step_btn_on_100.png new file mode 100644 index 0000000000..1e75b6091e Binary files /dev/null and b/resources/step_btn_on_100.png differ diff --git a/resources/step_btn_on_yellow.png b/resources/step_btn_on_yellow.png new file mode 100644 index 0000000000..38a971a774 Binary files /dev/null and b/resources/step_btn_on_yellow.png differ diff --git a/src/lib/buffer_allocator.cpp b/src/lib/buffer_allocator.cpp index f57df2994a..578cf74407 100644 --- a/src/lib/buffer_allocator.cpp +++ b/src/lib/buffer_allocator.cpp @@ -97,11 +97,7 @@ const int BUFFER_ALIGN_MASK = BUFFER_ALIGN - 1; void bufferAllocator::cleanUp( Uint16 _level ) { // first insert all unused bufs into an array -#if QT_VERSION >= 0x030100 - vvector bufsToRemove; -#else vlist bufsToRemove; -#endif for( bufIt it = s_buffers.begin(); it != s_buffers.end(); ++it ) { if( ( *it ).free ) @@ -114,11 +110,10 @@ void bufferAllocator::cleanUp( Uint16 _level ) // ( operator<(...) compares bufDesc::timesUsed ) qSort( bufsToRemove ); - const Uint16 todo = tMin( s_buffers.size() - _level, + const Sint16 todo = tMin( s_buffers.size() - _level, bufsToRemove.size() ); - // now cleanup the first n elements of sorted array - for( Uint16 i = 0; i < todo ; ++i ) + for( Sint16 i = 0; i < todo; ++i ) { delete[] bufsToRemove[i].origPtr; s_buffers.erase( qFind( s_buffers.begin(), s_buffers.end(), diff --git a/src/lib/sample_buffer.cpp b/src/lib/sample_buffer.cpp index d241470d77..53a092e78f 100644 --- a/src/lib/sample_buffer.cpp +++ b/src/lib/sample_buffer.cpp @@ -966,6 +966,8 @@ QString sampleBuffer::openAudioFile( void ) const #undef HAVE_FLAC_STREAM_ENCODER_H /* not yet... */ +#undef HAVE_FLAC_STREAM_DECODER_H + #ifdef HAVE_FLAC_STREAM_ENCODER_H FLAC__StreamEncoderWriteStatus flacStreamEncoderWriteCallback( const FLAC__StreamEncoder * @@ -976,25 +978,25 @@ FLAC__StreamEncoderWriteStatus flacStreamEncoderWriteCallback( unsigned int/* _current_frame*/, void * _client_data ) { - if( _bytes == 0 ) +/* if( _bytes == 0 ) { return( FLAC__STREAM_ENCODER_WRITE_STATUS_OK ); - } + }*/ return( ( static_cast( _client_data )->write( - (const char *) _buffer, _bytes ) == -1 ) ? - FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR : - FLAC__STREAM_ENCODER_WRITE_STATUS_OK ); + (const char *) _buffer, _bytes ) == + (int) _bytes ) ? + FLAC__STREAM_ENCODER_WRITE_STATUS_OK : + FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR ); } void flacStreamEncoderMetadataCallback( const FLAC__StreamEncoder *, - const FLAC__StreamMetadata * - /* _metadata*/, - void * /*_client_data*/ ) + const FLAC__StreamMetadata * _metadata, + void * _client_data ) { -/* QBuffer * b = static_cast( _client_data ); + QBuffer * b = static_cast( _client_data ); b->seek( 0 ); - b->write( (const char *) _metadata, sizeof( *_metadata ) );*/ + b->write( (const char *) _metadata, sizeof( *_metadata ) ); } #endif @@ -1007,24 +1009,31 @@ QString sampleBuffer::toBase64( void ) const return( "" ); } #ifdef HAVE_FLAC_STREAM_ENCODER_H - const Uint32 FRAMES_PER_BUF = 1024; + const Uint32 FRAMES_PER_BUF = 1152; FLAC__StreamEncoder * flac_enc = FLAC__stream_encoder_new(); FLAC__stream_encoder_set_channels( flac_enc, DEFAULT_CHANNELS ); FLAC__stream_encoder_set_blocksize( flac_enc, FRAMES_PER_BUF ); - FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, TRUE ); -// FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, TRUE ); +/* FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, TRUE ); + FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, TRUE );*/ FLAC__stream_encoder_set_sample_rate( flac_enc, mixer::inst()->sampleRate() ); QBuffer ba_writer; +#ifdef QT4 + ba_writer.open( QBuffer::WriteOnly ); +#else ba_writer.open( IO_WriteOnly ); +#endif - FLAC__stream_encoder_set_client_data( flac_enc, &ba_writer ); FLAC__stream_encoder_set_write_callback( flac_enc, flacStreamEncoderWriteCallback ); FLAC__stream_encoder_set_metadata_callback( flac_enc, flacStreamEncoderMetadataCallback ); - FLAC__stream_encoder_init( flac_enc ); + FLAC__stream_encoder_set_client_data( flac_enc, &ba_writer ); + if( FLAC__stream_encoder_init( flac_enc ) != FLAC__STREAM_ENCODER_OK ) + { + printf( "error within FLAC__stream_encoder_init()!\n" ); + } Uint32 frame_cnt = 0; while( frame_cnt < m_frames ) { @@ -1036,7 +1045,7 @@ QString sampleBuffer::toBase64( void ) const for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch ) { buf[f*DEFAULT_CHANNELS+ch] = (FLAC__int32)( - mixer::clip( m_data[f][ch] ) * + mixer::clip( m_data[f+frame_cnt][ch] ) * OUTPUT_SAMPLE_MULTIPLIER ); } } @@ -1046,9 +1055,10 @@ QString sampleBuffer::toBase64( void ) const } FLAC__stream_encoder_finish( flac_enc ); FLAC__stream_encoder_delete( flac_enc ); + printf("%d %d\n", frame_cnt, (int)ba_writer.size() ); ba_writer.close(); #ifdef QT4 - return( QByteArray::toBase64( ba_writer.data() ) ); + return( ba_writer.data().toBase64() ); #else QByteArray ba = ba_writer.buffer(); const Uint32 ssize = ba.size(); @@ -1058,7 +1068,8 @@ QString sampleBuffer::toBase64( void ) const #else /* HAVE_FLAC_STREAM_ENCODER_H */ #ifdef QT4 - return( QByteArray( (const char *) m_data, m_frames ).toBase64() ); + return( QByteArray( (const char *) m_data, m_frames * + sizeof( sampleFrame ) ).toBase64() ); #else const Uint32 ssize = m_frames * sizeof( sampleFrame ); const Uint8 * src = (const Uint8 *) m_data; @@ -1083,29 +1094,29 @@ QString sampleBuffer::toBase64( void ) const Uint32 i = 0; while( i < ssize ) { - int chunk = 0; - chunk |= int( src[i++] ) << 16; + Uint32 chunk = 0; + chunk |= Uint32( src[i++] ) << 16; if( i == dsize ) { padlen = 2; } else { - chunk |= int( src[i++] ) << 8; + chunk |= Uint32( src[i++] ) << 8; if( i == ssize ) { padlen = 1; } else { - chunk |= int( src[i++] ); + chunk |= Uint32( src[i++] ); } } - int j = ( chunk & 0x00fc0000 ) >> 18; - int k = ( chunk & 0x0003f000 ) >> 12; - int l = ( chunk & 0x00000fc0 ) >> 6; - int m = ( chunk & 0x0000003f ); + Uint32 j = ( chunk & 0x00fc0000 ) >> 18; + Uint32 k = ( chunk & 0x0003f000 ) >> 12; + Uint32 l = ( chunk & 0x00000fc0 ) >> 6; + Uint32 m = ( chunk & 0x0000003f ); *out++ = alphabet[j]; *out++ = alphabet[k]; if( padlen > 1 ) @@ -1126,7 +1137,7 @@ QString sampleBuffer::toBase64( void ) const } } // terminate string - ptr[dsize] = 0; + ptr[out - ptr] = 0; QString s( ptr ); delete[] ptr; return( s ); @@ -1157,24 +1168,113 @@ void sampleBuffer::setAudioFile( const QString & _audio_file ) +#ifdef HAVE_FLAC_STREAM_DECODER_H + +struct flacStreamDecoderClientData +{ + QBuffer * read_buffer; + QBuffer * write_buffer; +} ; + + + +FLAC__StreamDecoderReadStatus flacStreamDecoderReadCallback( + const FLAC__StreamDecoder * + /*_decoder*/, + FLAC__byte * _buffer, + unsigned int * _bytes, + void * _client_data ) +{ + int res = static_cast( + _client_data )->read_buffer->read( + (char *) _buffer, *_bytes ); + + if( res > 0 ) + { + *_bytes = res; + return( FLAC__STREAM_DECODER_READ_STATUS_CONTINUE ); + + } + *_bytes = 0; + return( FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM ); +} + + + + +FLAC__StreamDecoderWriteStatus flacStreamDecoderWriteCallback( + const FLAC__StreamDecoder * + /*_decoder*/, + const FLAC__Frame * _frame, + const FLAC__int32 * const _buffer[], + void * _client_data ) +{ + if( _frame->header.channels != 2 ) + { + printf( "channels != 2 in " + "flacStreamDecoderWriteCallback()\n" ); + return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT ); + } + + if( _frame->header.bits_per_sample != 16 ) + { + printf( "bits_per_sample != 16 in " + "flacStreamDecoderWriteCallback()\n" ); + return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT ); + } + + const Uint32 frames = _frame->header.blocksize; + for( Uint32 frame = 0; frame < frames; ++frame ) + { + sampleFrame sframe = { _buffer[0][frame] / + OUTPUT_SAMPLE_MULTIPLIER, + _buffer[1][frame] / + OUTPUT_SAMPLE_MULTIPLIER + } ; + static_cast( + _client_data )->write_buffer->write( + (const char *) sframe, sizeof( sframe ) ); + } + return( FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE ); +} + + +void flacStreamDecoderMetadataCallback( const FLAC__StreamDecoder *, + const FLAC__StreamMetadata *, + void * /*_client_data*/ ) +{ + printf("stream decoder metadata callback\n"); +/* QBuffer * b = static_cast( _client_data ); + b->seek( 0 ); + b->write( (const char *) _metadata, sizeof( *_metadata ) );*/ +} + + +void flacStreamDecoderErrorCallback( const FLAC__StreamDecoder *, + FLAC__StreamDecoderErrorStatus _status, + void * /*_client_data*/ ) +{ + printf("error callback! %d\n", _status); + // what to do now?? +} + +#endif + void sampleBuffer::loadFromBase64( const QString & _data ) { - delete[] m_origData; - - m_origFrames = _data.length() * 3 / ( 4 * sizeof( sampleFrame ) ); - m_origData = new sampleFrame[m_origFrames]; #ifdef QT4 - QByteArray data = QByteArray::fromBase64( _data.toAscii() ); - memcpy( m_origData, data.data(), data.size() ); + QByteArray orig_data = QByteArray::fromBase64( _data.toAscii() ); #else + const char * src = _data.ascii(); + csize ssize = _data.length(); + csize dsize = ( _data.length() * 3 ) / 4; + char * dst = new char[dsize]; + // code mostly taken from // qt-x11-opensource-src-4.0.1/src/corelib/tools/qbytearray.cpp unsigned int buf = 0; int nbits = 0; - const char * src = _data.ascii(); - char * dst = (char *) m_origData; - csize ssize = _data.length(); int offset = 0; for( csize i = 0; i < ssize; ++i ) @@ -1209,7 +1309,7 @@ void sampleBuffer::loadFromBase64( const QString & _data ) if( d != -1 ) { - buf = ( buf << 6 ) | d; + buf = ( buf << 6 ) | (Uint32)d; nbits += 6; if( nbits >= 8 ) { @@ -1219,8 +1319,58 @@ void sampleBuffer::loadFromBase64( const QString & _data ) } } } + QByteArray orig_data; + orig_data.setRawData( dst, dsize ); #endif +#ifdef HAVE_FLAC_STREAM_DECODER_H + +#ifdef QT4 + QBuffer ba_reader( &orig_data ); + ba_reader.open( QBuffer::ReadOnly ); +#else + QBuffer ba_reader( orig_data ); + ba_reader.open( IO_ReadOnly ); +#endif + + QBuffer ba_writer; +#ifdef QT4 + ba_writer.open( QBuffer::WriteOnly ); +#else + ba_writer.open( IO_WriteOnly ); +#endif + + flacStreamDecoderClientData cdata = { &ba_reader, &ba_writer } ; + + FLAC__StreamDecoder * flac_dec = FLAC__stream_decoder_new(); + + FLAC__stream_decoder_set_read_callback( flac_dec, + flacStreamDecoderReadCallback ); + FLAC__stream_decoder_set_write_callback( flac_dec, + flacStreamDecoderWriteCallback ); + FLAC__stream_decoder_set_error_callback( flac_dec, + flacStreamDecoderErrorCallback ); + FLAC__stream_decoder_set_metadata_callback( flac_dec, + flacStreamDecoderMetadataCallback ); + FLAC__stream_decoder_set_client_data( flac_dec, &cdata ); + + FLAC__stream_decoder_init( flac_dec ); + + FLAC__stream_decoder_process_until_end_of_stream( flac_dec ); + + FLAC__stream_decoder_finish( flac_dec ); + FLAC__stream_decoder_delete( flac_dec ); + + orig_data = ba_writer.buffer(); + printf("%d\n", (int) orig_data.size() ); +#endif + m_origFrames = orig_data.size() / sizeof( sampleFrame ); + delete[] m_origData; + m_origData = new sampleFrame[m_origFrames]; + memcpy( m_origData, orig_data.data(), orig_data.size() ); update(); +#ifndef QT4 +// delete[] dst; +#endif } diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 195894aa74..49a8f8b213 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -70,6 +70,7 @@ QPixmap * pattern::s_patternBg = NULL; QPixmap * pattern::s_stepBtnOn = NULL; +QPixmap * pattern::s_stepBtnOverlay = NULL; QPixmap * pattern::s_stepBtnOff = NULL; QPixmap * pattern::s_stepBtnOffLight = NULL; QPixmap * pattern::s_frozen = NULL; @@ -148,7 +149,12 @@ void pattern::init( void ) if( s_stepBtnOn == NULL ) { s_stepBtnOn = new QPixmap( embed::getIconPixmap( - "step_btn_on" ) ); + "step_btn_on_100" ) ); + } + if( s_stepBtnOverlay == NULL ) + { + s_stepBtnOverlay = new QPixmap( embed::getIconPixmap( + "step_btn_on_yellow" ) ); } if( s_stepBtnOff == NULL ) { @@ -178,7 +184,8 @@ void pattern::init( void ) setAutoResizeEnabled( FALSE ); toolTip::add( this, - tr( "double-click to open this pattern in piano-roll" ) ); + tr( "double-click to open this pattern in piano-roll\n" + "use mouse wheel to set volume" ) ); } @@ -744,7 +751,7 @@ void pattern::mouseDoubleClickEvent( QMouseEvent * _me ) !( m_patternType == pattern::BEAT_PATTERN && ( pixelsPerTact() >= 192 || m_steps != DEFAULT_STEPS_PER_TACT ) && - _me->y() > height() - s_stepBtnOn->height() ) ) + _me->y() > height() - s_stepBtnOff->height() ) ) { openInPianoRoll(); } @@ -757,17 +764,17 @@ void pattern::mousePressEvent( QMouseEvent * _me ) { /* if( _me->button() != Qt::LeftButton ) { - return; - }*/ + return; +}*/ if( _me->button() == Qt::LeftButton && - m_patternType == pattern::BEAT_PATTERN && - ( pixelsPerTact() >= 192 || - m_steps != DEFAULT_STEPS_PER_TACT ) && - _me->y() > height() - s_stepBtnOn->height() ) + m_patternType == pattern::BEAT_PATTERN && + ( pixelsPerTact() >= 192 || + m_steps != DEFAULT_STEPS_PER_TACT ) && + _me->y() > height() - s_stepBtnOff->height() ) { int step = ( _me->x() - TCO_BORDER_WIDTH ) * - length() / BEATS_PER_TACT / width(); + length() / BEATS_PER_TACT / width(); if( step >= m_steps ) { return; @@ -785,12 +792,12 @@ void pattern::mousePressEvent( QMouseEvent * _me ) update(); } else if( m_frozenPattern != NULL && _me->button() == Qt::LeftButton && - lmmsMainWin::isShiftPressed() == TRUE ) + lmmsMainWin::isShiftPressed() == TRUE ) { new stringPairDrag( "sampledata", - m_frozenPattern->toBase64(), - embed::getIconPixmap( "freeze" ), - this ); + m_frozenPattern->toBase64(), + embed::getIconPixmap( "freeze" ), + this ); } else { @@ -801,6 +808,58 @@ void pattern::mousePressEvent( QMouseEvent * _me ) +void pattern::wheelEvent( QWheelEvent * _we ) +{ +/* if( _me->button() != Qt::LeftButton ) + { + return; +}*/ + + if( m_patternType == pattern::BEAT_PATTERN && + ( pixelsPerTact() >= 192 || + m_steps != DEFAULT_STEPS_PER_TACT ) && + _we->y() > height() - s_stepBtnOff->height() ) + { + int step = ( _we->x() - TCO_BORDER_WIDTH ) * + length() / BEATS_PER_TACT / width(); + if( step >= m_steps ) + { + return; + } + note * n = m_notes[step]; + Uint8 vol = n->getVolume(); + + if( n->length() == 0 && _we->delta() > 0 ) + { + n->setLength( -64 ); + n->setVolume( 5 ); + } + else if( _we->delta() > 0 ) + { + if( vol < 95 ) + { + n->setVolume( vol + 5 ); + } + } + else + { + if( vol > 5 ) + { + n->setVolume( vol - 5 ); + } + else + { + n->setLength( 0 ); + } + } + songEditor::inst()->setModified(); + update(); + } +} + + + + void pattern::paintEvent( QPaintEvent * ) { changeLength( length() ); @@ -909,14 +968,20 @@ void pattern::paintEvent( QPaintEvent * ) ( ppt >= 192 || m_steps != DEFAULT_STEPS_PER_TACT ) ) { QPixmap stepon; + QPixmap stepoverlay; QPixmap stepoff; QPixmap stepoffl; int steps = length() / BEATS_PER_TACT; + #ifdef QT4 stepon = s_stepBtnOn->scaled( width() / steps, - s_stepBtnOn->height(), - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation ); + s_stepBtnOn->height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation ); + stepoverlay = s_stepBtnOverlay->scaled( width() / steps, + s_stepBtnOn->height(), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation ); stepoff = s_stepBtnOff->scaled( width() / steps, s_stepBtnOff->height(), Qt::IgnoreAspectRatio, @@ -926,8 +991,12 @@ void pattern::paintEvent( QPaintEvent * ) Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); #else - stepon.convertFromImage( s_stepBtnOn->convertToImage().scale( + stepon.convertFromImage( + s_stepBtnOn->convertToImage().scale( width() / steps, s_stepBtnOn->height() ) ); + stepoverlay.convertFromImage( + s_stepBtnOverlay->convertToImage().scale( + width() / steps, s_stepBtnOverlay->height() ) ); stepoff.convertFromImage( s_stepBtnOff->convertToImage().scale( width() / steps, s_stepBtnOff->height() ) ); stepoffl.convertFromImage( s_stepBtnOffLight->convertToImage(). @@ -940,10 +1009,21 @@ void pattern::paintEvent( QPaintEvent * ) Sint16 no = it - m_notes.begin(); Sint16 x = TCO_BORDER_WIDTH + static_cast( no * width() / steps ); - Sint16 y = height() - s_stepBtnOn->height() - 1; + Sint16 y = height() - s_stepBtnOff->height() - 1; + + Uint8 vol = ( *it )->getVolume(); + if( ( *it )->length() < 0 ) { - p.drawPixmap( x, y, stepon ); + for( int i = 0; i < vol / 5 + 1; ++i ) + { + p.drawPixmap( x, y, stepon ); + } + for( int i = 0; i < ( 25 + ( vol - 75 ) ) / 5; + ++i ) + { + p.drawPixmap( x, y, stepoverlay ); + } } else if( ( no / BEATS_PER_TACT ) % 2 ) {