Click here to Skip to main content
15,901,122 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Friends,

I am developing a piano application in which i am reading a song text file.In my app i am trying to achieve a functionality where in i am using a stack with in a loop for reading, playing notes On and displaying the notes of song text file simultaneously as the stack advances through the song text file.

Now i have used 2 stacks within a single goto statement, one stack perform for displaying notes,after 15 notes i enable a counter which starts another stack which is responsible for playing notes on.I am keeping an offset of 15 notes between song display and song play so that user can see the upcoming notes.

But due to usage of two stack there is no smoothness of song play,the intervals between songs are irregularly playing,can anybody correct me or guide me another solution.
C++
while ((stopSong==true )&&readFile.ReadString(strLine))
{
//there is a for loop for starting the file index
for (int n=readStartIndex, m=readStartIndex; n < size && m < size; n++, m++)
     {
//there is a while loop for inserting the notes until the dot(.) and end of file 'T'is reached.
//inside while loop notes is pushed
//-------------------------------------------------------------------------
while((s[n]!='.')&&s[n]!='T'&&stopSong==true)
    {
     notesChar.push_back(s[n]);
     c++;
     n++;
    }
//-------------------------------------------------------------------------
//notes are popped according to identification of

//d-notes ON for right hand press
//u-notes OFF for right hand release
//e-notes ON for left hand press
//v-notes OFF for left hand release
//s- for timer delay between notes
//-------------------------------------------------------------------------
      if(s[n]=='.')
       {
           if((s[n-1]=='d')&&stopSong==true) 
	  {
	   c--;
	   notesChar.pop_back();
	   std::string NotesStr(notesChar.begin(),notesChar.end());
	   int Noteid=atoi(NotesStr.c_str());
	  
	    
	    m_Keys.findchords(Noteid);
	    StaticColor=RGB(250,250,100);  		   
            m_Keys1.dischords=m_Keys1.dischords+m_Keys.dischords;
	     
	    displaychords(m_Keys1.dischords);//<-------------displaying chords
	    m_Keys.dischords.Empty();
          }

//Similalry for 'e'.
//---------------------------------------------------------------------------------
        else if(s[n-1]=='u'&&stopSong==true)
	 {
	  c--;
	  notesChar.pop_back();
	  std::string NotesStr(notesChar.begin(),notesChar.end());
	  int Noteid=atoi(NotesStr.c_str());
	  m_Keys.NoteOff(Noteid);
	  ucount++;
	  }
//Similarly for 'v'.
//----------------------------------------------------------------------------------
else if(s[n-1]=='s'&&stopSong==true)
	  {
           
            c--;
	    notesChar.pop_back();
	    std::string NotesStr(notesChar.begin(),notesChar.end());
	    int Noteid=atoi(NotesStr.c_str());  
	    XSleep(Noteid);
	  }
//------------------------------------------------------------------------------------
//for poping out remaining notes.

          for(int p=0;p<c&&stopSong==true;p++)
	  {
	    notesChar.pop_back();
	  }
	  c=0;
	  n++;
//------------------------------------------------------------------------------------        
//Counter is getting incremented, at 'u' after 15 counts.
       if(ucount>15)
       {
/there is a while loop for inserting the notes until the dot(.) and end of file 'T'is reached.
//inside while loop notes is pushed

         while((q[m]!='.')&&q[m]!='T'&&stopSong==true)
	 {
	  //MessageBox("while loop");
	  QueueChar.push_back(q[m]);	 
          m++;
	  h++;
         }
//--------------------------------------------------------------------------------------
//notes are popped according to identification of

//d-notes ON for right hand press
//u-notes OFF for right hand release
//e-notes ON for left hand press
//v-notes OFF for left hand release
//s- for timer delay between notes
         if(q[m]=='.')
	 {
	  if((q[m-1]=='d')&&stopSong==true)
	  {
	   h--;
	   QueueChar.pop_back();
	   std::string NotesStr1(QueueChar.begin(),QueueChar.end());
	   int Noteid=atoi(NotesStr1.c_str());
	   m_Keys.NoteOn(Noteid,RGB(0,250,0));//<---------------------Playing note on
	   m_Keys.dischords.Empty();
	 }

//Similarly for 'e'.
//----------------------------------------------------------------------
	  
	else if((q[m-1]=='u')&&stopSong==true)
	 {
           h--;
	   QueueChar.pop_back();
	   std::string NotesStr1(QueueChar.begin(),QueueChar.end());
	   int Noteid=atoi(NotesStr1.c_str());
           m_Keys.NoteOff(Noteid);//<-------------------------------Playing notes off
	 }
//Similarly for 'v'.
//----------------------------------------------------------------------
	 
        else if((q[m-1]=='s')&&stopSong==true)
	{
          h--;
	  QueueChar.pop_back();
	  std::string NotesStr1(QueueChar.begin(),QueueChar.end());
	  int Noteid=atoi(NotesStr1.c_str());
	  XSleep(Noteid);
        }
//-----------------------------------------------------------------------
//for poping out remaining notes
	 
	for(int p=0; p < m && stopSong==true; p++)							      
         {
	  QueueChar.pop_back();
         }
         h=0;
         m++;
       } 
      goto L1;
     }
    else if(s[n]=='T')
     {
        break;
      }
   }
  if(closed==false)
	{
		readFile.Close();

		closed=true;
		m_Recording.EnableWindow(true);
		m_PlayRecord.EnableWindow(true);
		stopSong=false;
	         
	}
}
and song notes are like this-
60d.250s.60u.65d.250s.65u.65d.5u.67d.150s.67u.T 
Posted
Updated 1-Aug-13 19:04pm
v7
Comments
nv3 30-Jul-13 7:01am    
You are problably talking about queues not stacks, right? Your chances of receiving meaningful help would increase if you would show the loop in which you fetch the notes and feed them to your device. If you'd use a separate thread and timer, the correct timing of the notes should not suffer.
nv3 31-Jul-13 12:50pm    
I really wanted to give it a try and read your code, but this is a dump. Brackets are not matching and the loop body is way too long to be seen on a single page. As it stands the for loop at the top is never reached again, as you are always jumping to it's top by "goto L1".

If you really want that someone reads your code then subdivide the huge body into separate function, each doing something that you can descrribe in a few lines. Then paste the code again. And perhaps you leave all the parts out that are not relevant for answering your question.
SaurabSaini 1-Aug-13 7:41am    
Sorry for inconvenience i will correct and paste again.

There are certainly many things to improve in your code and I would be willing to help you step-by-step to do that. But first to your most pressing problem: Why is the playback of your notes so irregular?

From guessing, how your code might work, I would say that the problem is the 's' section in your display loop. The s-commands are responsible for the correct timing of the notes. But when you are just displaying the next 15 notes you definitely do not want wait in-between notes, but do the display as quickly as possible. So in the first s-section:
C++
    else if(s[n-1]=='s'&&stopSong==true)
{

      c--;
  notesChar.pop_back();
  std::string NotesStr(notesChar.begin(),notesChar.end());
  int Noteid=atoi(NotesStr.c_str());
  XSleep(Noteid);
}

you want to remove the XSleep statement. Actually you could also remove the two lines above it.

Try that and tell us, if that brings the improvement your are looking for. Then we start to attend to the many other improvements that could be made to your code.
 
Share this answer
 
Comments
SaurabSaini 5-Aug-13 9:01am    
I just love code project...thank you so much sir :)It worked accordingly.
nv3 5-Aug-13 9:28am    
You are welcome. And if you like, we can improve a couple of other things in your code. For example, the use of the notesChar stack is a little weird. What you actually want to do is to use a little parser to separate the "nnnx." sequences. A stack is not the most attractive data structure for that. Or another example: stopSong is test many time, which could be centralized. And I would implement the delayed play by a queue and not by parsing the input two times. If you like, open a new question of each of these improvements, one at a time, and we start working on it.
why arent you using a queue for that. After playing the first object it gets removed. And following elements are enqueued at the end.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900