Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: how to make a short beep


This question is answered. Helpful answers available: 1. Correct answers available: 1.


Permlink Replies: 11 - Last Post: Sep 25, 2014 7:14 AM Last Post By: Michael Leahy
Michael Leahy

Posts: 239
Registered: 5/9/07
how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 17, 2014 2:00 PM
I want to make a short (fast) high pitched beep noise to help with debugging.

How do I play a sine wave at a certain frequency for a fraction of a second in Firemonkey?

I'm okay with making one version for MSWINDOWS and another for MACINTOSH if necessary.
Tom Brunberg

Posts: 329
Registered: 12/27/04
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 18, 2014 1:24 PM   in response to: Michael Leahy in response to: Michael Leahy
Michael Leahy wrote:

I want to make a short (fast) high pitched beep noise to help with debugging.

How do I play a sine wave at a certain frequency for a fraction of a second in Firemonkey?

I'm okay with making one version for MSWINDOWS and another for MACINTOSH if necessary.

Michael,
I can't help you with MAC, but for Win you could take a look at this:
http://www.swissdelphicenter.ch/en/showcode.php?id=1324
It creates a sound in WAVE format in a memory stream of needed frequency, duration and volume and
then uses sndPlaySound to output the sound. I have not used this code but I don't see any reason
why it wouldn't work under FMX.

--
Tom Brunberg
firstname.lastname@welho.com
Chris Dunn

Posts: 160
Registered: 8/22/11
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 18, 2014 1:36 PM   in response to: Michael Leahy in response to: Michael Leahy
I drop a Tmediaplayer on the form. Download a commercial free beep.mp3. and use the code below.

TMediaPlayer1.FileName := TPath.GetDocumentsPath + PathDelim + 'Sounds' + PathDelim + beep.mp3;
TMediaPlayer1.Play;
Michael Leahy

Posts: 239
Registered: 5/9/07
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 18, 2014 2:06 PM   in response to: Chris Dunn in response to: Chris Dunn
Chris Dunn wrote:
I drop a Tmediaplayer on the form. Download a commercial free beep.mp3. and use the code below.

TMediaPlayer1.FileName := TPath.GetDocumentsPath + PathDelim + 'Sounds' + PathDelim + beep.mp3;
TMediaPlayer1.Play;

Playing a short MP3 with the MediaPlayer seems very code heavy for what I'm up to.

I'm hoping for something like the old Beep(800, 500) calls that will very quickly play a short tone so that I can listen to them in a high speed process to help debug it.
Tom Brunberg

Posts: 329
Registered: 12/27/04
Re: how to make a short beep
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 18, 2014 11:39 PM   in response to: Michael Leahy in response to: Michael Leahy
Michael Leahy wrote:

Chris Dunn wrote:
I drop a Tmediaplayer on the form. Download a commercial free beep.mp3. and use the code below.

TMediaPlayer1.FileName := TPath.GetDocumentsPath + PathDelim + 'Sounds' + PathDelim +
beep.mp3; TMediaPlayer1.Play;

Playing a short MP3 with the MediaPlayer seems very code heavy for what I'm up to.

I'm hoping for something like the old Beep(800, 500) calls that will very quickly play a short
tone so that I can listen to them in a high speed process to help debug it.

Did you try the code at the link I gave you in my previous post?
I did, and it didn't work. It's obviously written before D2009 and a change is necessary:
The following, original string constants need to be changed to AnsiString:
   RiffId: ansistring = 'RIFF';
   WaveId: ansistring = 'WAVE';
   FmtId: ansistring = 'fmt ';
   DataId: ansistring = 'data';


I also rearranged the code, to create the sound data only once and then just reuse it, and made a
class of it.
uses
  ...  
  windows, mmsystem;
 
type
  TVolumeLevel = 0..127;
 
  TNoise = class
  private
    ms: TMemoryStream;
  public
    constructor Create(Frequency{Hz}, Duration{mSec}: Integer; Volume: TVolumeLevel);
    destructor Destroy; override;
    procedure Play;
  end;
 
implementation
  ...
{ TNoise }
 
constructor TNoise.Create(Frequency, Duration: Integer; Volume: TVolumeLevel);
var
   WaveFormatEx: TWaveFormatEx;
   i, TempInt, DataCount, RiffCount: integer;
   SoundValue: byte;
   w: double; // omega ( 2 * pi * frequency)
const
   Mono: Word = $0001;
   SampleRate: Integer = 11025; // 8000, 11025, 22050, or 44100
   RiffId: ansistring = 'RIFF';
   WaveId: ansistring = 'WAVE';
   FmtId: ansistring = 'fmt ';
   DataId: ansistring = 'data';
begin
   if Frequency > (0.6 * SampleRate) then
   begin
     ShowMessage(Format('Sample rate of %d is too Low to play a tone of %dHz',
       [SampleRate, Frequency]));
     Exit;
   end;
   with WaveFormatEx do
   begin
     wFormatTag := WAVE_FORMAT_PCM;
     nChannels := Mono;
     nSamplesPerSec := SampleRate;
     wBitsPerSample := $0008;
     nBlockAlign := (nChannels * wBitsPerSample) div 8;
     nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
     cbSize := 0;
   end;
   MS := TMemoryStream.Create;
   with MS do
   begin
     {Calculate length of sound data and of file data}
     DataCount := (Duration * SampleRate) div 1000; // sound data
     RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
       SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount; // file data
     {write out the wave header}
     Write(RiffId[1], 4); // 'RIFF'
     Write(RiffCount, SizeOf(DWORD)); // file data size
     Write(WaveId[1], Length(WaveId)); // 'WAVE'
     Write(FmtId[1], Length(FmtId)); // 'fmt '
     TempInt := SizeOf(TWaveFormatEx);
     Write(TempInt, SizeOf(DWORD)); // TWaveFormat data size
     Write(WaveFormatEx, SizeOf(TWaveFormatEx)); // WaveFormatEx record
     Write(DataId[1], Length(DataId)); // 'data'
     Write(DataCount, SizeOf(DWORD)); // sound data size
     {calculate and write out the tone signal} // now the data values
     w := 2 * Pi * Frequency; // omega
     for i := 0 to DataCount - 1 do
     begin
       SoundValue := 127 + trunc(Volume * sin(i * w / SampleRate)); // wt = w * i / SampleRate
       Write(SoundValue, SizeOf(Byte));
     end;
   end;
end;
 
destructor TNoise.Destroy;
begin
  ms.Free;
  inherited;
end;
 
procedure TNoise.Play;
begin
  sndPlaySound(MS.Memory, SND_MEMORY or SND_ASYNC);
end;
 

Note that I also changed to Async mode, not to stop the program for the sound duration.
Usage:
procedure TForm4.Button1Click(Sender: TObject);
begin
  myBeep := TNoise.Create(3800, 100, 120);
end;
 
procedure TForm4.Button2Click(Sender: TObject);
begin
  myBeep.Play;
end;

--
Tom Brunberg
firstname.lastname@welho.com

Michael Leahy

Posts: 239
Registered: 5/9/07
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 23, 2014 10:56 AM   in response to: Tom Brunberg in response to: Tom Brunberg
Tom Brunberg wrote:
Michael Leahy wrote:

Chris Dunn wrote:
I drop a Tmediaplayer on the form. Download a commercial free beep.mp3. and use the code below.

TMediaPlayer1.FileName := TPath.GetDocumentsPath + PathDelim + 'Sounds' + PathDelim +
beep.mp3; TMediaPlayer1.Play;

Playing a short MP3 with the MediaPlayer seems very code heavy for what I'm up to.

I'm hoping for something like the old Beep(800, 500) calls that will very quickly play a short
tone so that I can listen to them in a high speed process to help debug it.

Did you try the code at the link I gave you in my previous post?
I did, and it didn't work. It's obviously written before D2009 and a change is necessary:
The following, original string constants need to be changed to AnsiString:
   RiffId: ansistring = 'RIFF';
   WaveId: ansistring = 'WAVE';
   FmtId: ansistring = 'fmt ';
   DataId: ansistring = 'data';


I also rearranged the code, to create the sound data only once and then just reuse it, and made a
class of it.
uses
  ...  
  windows, mmsystem;
 
type
  TVolumeLevel = 0..127;
 
  TNoise = class
  private
    ms: TMemoryStream;
  public
    constructor Create(Frequency{Hz}, Duration{mSec}: Integer; Volume: TVolumeLevel);
    destructor Destroy; override;
    procedure Play;
  end;
 
implementation
  ...
{ TNoise }
 
constructor TNoise.Create(Frequency, Duration: Integer; Volume: TVolumeLevel);
var
   WaveFormatEx: TWaveFormatEx;
   i, TempInt, DataCount, RiffCount: integer;
   SoundValue: byte;
   w: double; // omega ( 2 * pi * frequency)
const
   Mono: Word = $0001;
   SampleRate: Integer = 11025; // 8000, 11025, 22050, or 44100
   RiffId: ansistring = 'RIFF';
   WaveId: ansistring = 'WAVE';
   FmtId: ansistring = 'fmt ';
   DataId: ansistring = 'data';
begin
   if Frequency > (0.6 * SampleRate) then
   begin
     ShowMessage(Format('Sample rate of %d is too Low to play a tone of %dHz',
       [SampleRate, Frequency]));
     Exit;
   end;
   with WaveFormatEx do
   begin
     wFormatTag := WAVE_FORMAT_PCM;
     nChannels := Mono;
     nSamplesPerSec := SampleRate;
     wBitsPerSample := $0008;
     nBlockAlign := (nChannels * wBitsPerSample) div 8;
     nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
     cbSize := 0;
   end;
   MS := TMemoryStream.Create;
   with MS do
   begin
     {Calculate length of sound data and of file data}
     DataCount := (Duration * SampleRate) div 1000; // sound data
     RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
       SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount; // file data
     {write out the wave header}
     Write(RiffId[1], 4); // 'RIFF'
     Write(RiffCount, SizeOf(DWORD)); // file data size
     Write(WaveId[1], Length(WaveId)); // 'WAVE'
     Write(FmtId[1], Length(FmtId)); // 'fmt '
     TempInt := SizeOf(TWaveFormatEx);
     Write(TempInt, SizeOf(DWORD)); // TWaveFormat data size
     Write(WaveFormatEx, SizeOf(TWaveFormatEx)); // WaveFormatEx record
     Write(DataId[1], Length(DataId)); // 'data'
     Write(DataCount, SizeOf(DWORD)); // sound data size
     {calculate and write out the tone signal} // now the data values
     w := 2 * Pi * Frequency; // omega
     for i := 0 to DataCount - 1 do
     begin
       SoundValue := 127 + trunc(Volume * sin(i * w / SampleRate)); // wt = w * i / SampleRate
       Write(SoundValue, SizeOf(Byte));
     end;
   end;
end;
 
destructor TNoise.Destroy;
begin
  ms.Free;
  inherited;
end;
 
procedure TNoise.Play;
begin
  sndPlaySound(MS.Memory, SND_MEMORY or SND_ASYNC);
end;
 

Note that I also changed to Async mode, not to stop the program for the sound duration.
Usage:
procedure TForm4.Button1Click(Sender: TObject);
begin
  myBeep := TNoise.Create(3800, 100, 120);
end;
 
procedure TForm4.Button2Click(Sender: TObject);
begin
  myBeep.Play;
end;

--
Tom Brunberg
firstname dot lastname at welho dot com


Thanks, Tom.

I added this to XE6.

When I click the button, it delays a half second or sometimes a full second or more before playing the sound. I need something that will play nearly instantly every time (<100ms delay) and reset to play again almost immediately (<50ms).

I tried removing SND_ASYNC but it behaved the same way.
Michael Leahy

Posts: 239
Registered: 5/9/07
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 24, 2014 10:50 AM   in response to: Tom Brunberg in response to: Tom Brunberg
Tom Brunberg wrote:
Did you try the code at the link I gave you in my previous post?
I also rearranged the code, to create the sound data only once and then just reuse it, and made a
class of it.

I tried this with XE7 and an actual Windows machine and it is much more responsive.

Perhaps my problem was with VM on the Mac slowing down the sound.
Tom Brunberg

Posts: 329
Registered: 12/27/04
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 24, 2014 11:15 AM   in response to: Michael Leahy in response to: Michael Leahy
Michael Leahy wrote:

Tom Brunberg wrote:
Did you try the code at the link I gave you in my previous post?
I also rearranged the code, to create the sound data only once and then just reuse it, and made
a class of it.

I tried this with XE7 and an actual Windows machine and it is much more responsive.

Perhaps my problem was with VM on the Mac slowing down the sound.

Yeah Michael, that wouldn't surprise me at all.

Cheers

--
Tom Brunberg
firstname.lastname@welho.com
John Frazier


Posts: 726
Registered: 2/17/00
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 23, 2014 12:21 PM   in response to: Michael Leahy in response to: Michael Leahy
Michael Leahy wrote:
I want to make a short (fast) high pitched beep noise to help with debugging.

How do I play a sine wave at a certain frequency for a fraction of a second in Firemonkey?

I'm okay with making one version for MSWINDOWS and another for MACINTOSH if necessary.

Reminds me of old school debugging on the Apple ][ with ASCII chr(7) [aka CTRL-G] :)

http://en.wikipedia.org/wiki/Bell_character

Since you are looking for custom tones, you have found you have to work a bit more for that. One thing I spotted was these libs and might have something useful for you. http://www.mitov.com/products/audiolab#overview
--
John Frazier (Embarcadero Newsgroup Admin)
Michael Leahy

Posts: 239
Registered: 5/9/07
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 24, 2014 11:20 AM   in response to: John Frazier in response to: John Frazier
John Frazier wrote:
Michael Leahy wrote:
I want to make a short (fast) high pitched beep noise to help with debugging.

How do I play a sine wave at a certain frequency for a fraction of a second in Firemonkey?

I'm okay with making one version for MSWINDOWS and another for MACINTOSH if necessary.

Reminds me of old school debugging on the Apple ][ with ASCII chr(7) [aka CTRL-G] :)

http://en.wikipedia.org/wiki/Bell_character

Since you are looking for custom tones, you have found you have to work a bit more for that. One thing I spotted was these libs and might have something useful for you. http://www.mitov.com/products/audiolab#overview
--
John Frazier (Embarcadero Newsgroup Admin)

My legacy VCL code uses Mitov's libraries for multimedia.

I am still looking for a way to make a short fast beep (tone) that works in both MSWINDOWS and MACOS. I may have to repost the question.
John Frazier


Posts: 726
Registered: 2/17/00
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 24, 2014 4:54 PM   in response to: Michael Leahy in response to: Michael Leahy
Michael Leahy wrote:
My legacy VCL code uses Mitov's libraries for multimedia.

I am still looking for a way to make a short fast beep (tone) that works in both MSWINDOWS and MACOS. I may have to repost the question.

I noticed Boian mentions FM here http://www.mitov.com/products/audiolab#downloads though it is not clear if it works on platforms other than Windows. I saw that he has introduced some Android support, might be worth asking if he has anything to test :) I looked briefly and this seemed promising http://mitov.com/installer/104
--
John Frazier (Embarcadero Newsgroup Admin)
Michael Leahy

Posts: 239
Registered: 5/9/07
Re: how to make a short beep  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 25, 2014 7:14 AM   in response to: John Frazier in response to: John Frazier
John Frazier wrote:
Michael Leahy wrote:
My legacy VCL code uses Mitov's libraries for multimedia.

I am still looking for a way to make a short fast beep (tone) that works in both MSWINDOWS and MACOS. I may have to repost the question.

I noticed Boian mentions FM here http://www.mitov.com/products/audiolab#downloads though it is not clear if it works on platforms other than Windows. I saw that he has introduced some Android support, might be worth asking if he has anything to test :) I looked briefly and this seemed promising http://mitov.com/installer/104
--
John Frazier (Embarcadero Newsgroup Admin)

I did ask Boian. The multimedia components are not yet ready for MACOS.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02