Well, the first error was produced on line 105 which is your first header() command. The "headers already sent" means prior to line 105 you have outputted something to the browser. This could be a space, tab, carriage return, HTML, etc. You must not send anything prior to the use of header(). Find where you're doing that and remove it.
In the "Content-Disposition" header you currently are specifying the whole URL and that means after the first download, the person may know exactly where the file is located and can just type that URL in their browser window to get the file from then on. The "Content-Disposition" header is suppose to just suggest a filename when the user is prompted to save the file. Use basename() to get that.
I thought you wanted to hide the URL or download location from visitors/users. This isn't going to do it (if you continue using a URL). Put all your download files off your public (web) directory and use full or relative path names instead of URL's. So, if your web directory path is /home/user/www, then make a /home/user/my_music directory or something like it and place all your wave files there.
Also, you're missing an important if not required header, and that is the "Content-Type". This header tells the web client (users browser) what type of file to expect. Example:
$filepath = '/home/user/my_music/' . $row['file_name'] . '.' . $row['extension'];
header('Content-Disposition: attachment; filename="' . basename($filepath) . '"');
header('Content-Type: audio/x-wav'); // or try: audio/vnd.qcelp
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit();
hth.
EDIT: Posted too late.