Can be implemented in C or C++
Thread 1: The player thread
While playing, the player thread reads one word from the file, prints it, then sleeps until the next word should be displayed, and so on. Each word should be displayed on a separate line of output. (Words are white-space-separated runs of characters.) At a rate of 1.0, the player should print one word per second. At a rate of -1.0, the player prints one word per second, but proceeding backwards through the file.
For this assignment, the player plays back text files, displaying one word per second at normal rate (1.0).
The player accepts the following commands:
- LoadFile(const char *filename) — Prepares the player to playback the file whose name is passed in. Stops the player if currently playing.
- Stop() — Stops the player if currently playing.
- Start() — Starts the player if currently stopped.
- Rewind() — Sets the position of the player to time 0.
- SeekTo(int byteoffset) — Sets the position of the player to the closest word boundary past the given byte offset from the start of the file.
- SetRate(float rate) — Sets the playback rate: 1.0 is forward at normal speed, –
- 1.0 is reverse, 0.5 is forward at 1/2 speed, etc.
The control threads
The control threads generate commands for the player thread. You can think of each control thread as corresponding to a separate remote control. There are two kinds of control threads. The first kind waits for keypresses, and issues commands to the player thread based on the key pressed:
- ‘ ‘ (blank) — toggles the player’s mode between ‘playing’ and ‘stopped’
- ‘r’ — rewinds the player
- ‘s’ — prompts the user for a time, then seeks the player to that time
- ‘l’ — prompts the user for a file, then loads the file into the player
- ‘t’ — prompts the user for a rate, then uses it to set the player’s rate
Two other control thread are “autonomous” controllers, simulating another user issuing commands. One of the autonomous controllers periodically issues a Stop() command to the player, while the other autonomous controller thread issues a Start() command every so often. Each of these autonomous threads should sleep for a random time interval of between 5 and 30 seconds before issuing each command.
Your program should implement a function for each command (Start(), Stop(), etc.). These functions will be called by the control threads to control the player. Shared, global variables for the state, rate, position, etc. of the player thread are accessed by these routines, as well as the player thread routine.