Recent

Author Topic: PlaySound ('dog.wav', 0, snd_Async);  (Read 1934 times)

jcaser1948

  • Jr. Member
  • **
  • Posts: 51
PlaySound ('dog.wav', 0, snd_Async);
« on: February 23, 2018, 05:19:16 pm »
I am working through the book "Delpi 7 The Bible
In one of the example programs appears:

Code: Pascal  [Select]
  1. function TDog.Voice: string;
  2. begin
  3.   Voice := 'Arf Arf';
  4.   PlaySound ('dog.wav', 0, snd_Async);
  5. end;
That of course does not compile since I work in Linux and the books was written for Windows.
Has anyone a suggestion how I could program that in Lazarus for Linux?
Sorry for those silly questions
Thanks
« Last Edit: February 23, 2018, 05:38:40 pm by jcaser1948 »

Handoko

  • Hero Member
  • *****
  • Posts: 3200
  • My goal: build my own game engine using Lazarus
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #1 on: February 23, 2018, 05:41:07 pm »

wp

  • Hero Member
  • *****
  • Posts: 6370
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #2 on: February 23, 2018, 06:44:34 pm »
The easiest way to play a soundfile like in "PlaySound" is using the PlaySoundPackage. if you have Laz 1.8 you can find it in the Online Package Manager (Check it, click Install, that's all). Or you go to https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/playsoundpackage/latest_stable/ and download the files uplaysound.pas and aboutplaysound.pas into your project folder; since the latter method does not install the component you must write a few lines of code:
Code: Pascal  [Select]
  1. uses
  2.   uplaysound;
  3.  
  4. procedure TForm1.Playsound(AWavFile: String; ASync: Boolean);
  5. var
  6.   player: TPlaySound;
  7. begin
  8.   player := TPlaySound.Create(nil);
  9.   try
  10.     player.SoundFile := AWavFile;
  11.     if Async then player.PlayStyle := psAsync else player.PlayStyle := psSync;
  12.     player.Execute;
  13.   finally
  14.     player.Free;
  15.   end;
  16. end;
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jcaser1948

  • Jr. Member
  • **
  • Posts: 51
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #3 on: February 25, 2018, 05:57:25 pm »
The given procedure works fine,thank you very much.
But I have still trouble with the book2Delphi 7, the Bible where this procedure is used
Here the code from bokk,,adapted
Code: Pascal  [Select]
  1. unit abstanimf;
  2.  
  3. {$MODE Delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
  9.     StdCtrls, Buttons, ExtCtrls, uplaysound;
  10.  
  11. type
  12.  
  13.   { TFormAnimals }
  14.  
  15.   TFormAnimals = class(TForm)
  16.     playsound1: Tplaysound;
  17.     LabelVoice: TLabel;
  18.     BtnVoice: TButton;
  19.     RbtnAnimal: TRadioButton;
  20.     RbtnDog: TRadioButton;
  21.     RbtnCat: TRadioButton;
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure FormDestroy(Sender: TObject);
  24.     procedure BtnVoiceClick(Sender: TObject);
  25.     procedure RbtnAnimalClick(Sender: TObject);
  26.     procedure RbtnDogClick(Sender: TObject);
  27.     procedure RbtnCatClick(Sender: TObject);
  28.     procedure PlaySound(AWavFile: String; ASync: Boolean);
  29.  
  30.   private
  31.  
  32.   public
  33.     { Public declarations }
  34.  
  35.   end;
  36.  
  37.   TAnimal = class
  38.   public
  39.     constructor Create;
  40.     function GetKind: string;
  41.     function Voice: string; virtual;abstract;
  42.   private
  43.     Kind: string;
  44.   end;
  45.  
  46.   TDog = class (TAnimal)
  47.   public
  48.     constructor Create;
  49.     function Voice: string; override;
  50.     function Eat: string; virtual;
  51.   end;
  52.  
  53.   TCat = class (TAnimal)
  54.   public
  55.     constructor Create;
  56.     function Voice: string;override;
  57.     function Eat: string; virtual;
  58.   end;
  59.  
  60.  
  61. var
  62.  
  63.   FormAnimals: TFormAnimals;
  64.   MyAnimal: TAnimal;
  65.  
  66. implementation
  67.  
  68. {$R *.lfm}
  69.  
  70. procedure TFormAnimals.FormCreate(Sender: TObject);
  71. begin
  72.   MyAnimal := TDog.Create;
  73. end;
  74.  
  75. procedure TFormAnimals.FormDestroy(Sender: TObject);
  76. begin
  77.   MyAnimal.Free;
  78. end;
  79.  
  80. procedure TFormAnimals.BtnVoiceClick(Sender: TObject);
  81. begin
  82.   LabelVoice.Caption := MyAnimal.Voice;
  83. end;
  84.  
  85. constructor TAnimal.Create;
  86. begin
  87.   Kind := 'An animal';
  88. end;
  89.  
  90. function TAnimal.GetKind: string;
  91. begin
  92.   GetKind := Kind;
  93. end;
  94.  
  95. constructor TDog.Create;
  96. begin
  97.   Kind := 'A dog';
  98. end;
  99.  
  100. function TDog.Voice: string;
  101. Var VoiceSound:String;
  102. begin
  103.  
  104.    Voice := 'Arf Arf';
  105.     VoiceSound:= 'dog.wav';
  106.     FormAnimals.PlaySound(VoiceSound,true);
  107.  
  108. end;
  109.  
  110. function TDog.Eat: string;
  111. begin
  112.   Eat := 'A bone, please!';
  113. end;
  114.  
  115. constructor TCat.Create;
  116. begin
  117.   Kind := 'A cat';
  118. end;
  119.  
  120. function TCat.Voice: string;
  121. Var VoiceSound:String;
  122. begin
  123.   Voice := 'Mieow' ;
  124.   VoiceSound:= 'cat.wav';
  125.     FormAnimals.PlaySound(VoiceSound,true);
  126. end;
  127.  
  128. function TCat.Eat: string;
  129. begin
  130.   Eat := 'A mouse, please!';
  131. end;
  132.  
  133. procedure TFormAnimals.RbtnAnimalClick(Sender: TObject);
  134. begin
  135.   MyAnimal.Free;
  136.   MyAnimal := TAnimal.Create;
  137. end;
  138.  
  139. procedure TFormAnimals.RbtnDogClick(Sender: TObject);
  140. begin
  141.   MyAnimal.Free;
  142.   MyAnimal := TDog.Create;
  143. end;
  144.  
  145. procedure TFormAnimals.RbtnCatClick(Sender: TObject);
  146. begin
  147.   MyAnimal.Free;
  148.   MyAnimal := TCat.Create;
  149. end;
  150.  procedure  TFormAnimals.PlaySound(AWavFile: String; ASync: Boolean);
  151.  var
  152.   player: TPlaySound;
  153. begin
  154.   player := TPlaySound.Create(nil);
  155.   try
  156.     player.SoundFile := AWavFile;
  157.     if Async then player.PlayStyle := psAsync else player.PlayStyle := psSync;
  158.     player.Execute;
  159.   finally
  160.     player.Free;
  161.   end;
  162. end;
  163. end.
  164.  
It compile fine but when I get
unit abstanimf;

{$MODE Delphi}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
    StdCtrls, Buttons, ExtCtrls, uplaysound;

type

  { TFormAnimals }

  TFormAnimals = class(TForm)
    playsound1: Tplaysound;
    LabelVoice: TLabel;
    BtnVoice: TButton;
    RbtnAnimal: TRadioButton;
    RbtnDog: TRadioButton;
    RbtnCat: TRadioButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BtnVoiceClick(Sender: TObject);
    procedure RbtnAnimalClick(Sender: TObject);
    procedure RbtnDogClick(Sender: TObject);
    procedure RbtnCatClick(Sender: TObject);
    procedure PlaySound(AWavFile: String; ASync: Boolean);

  private

  public
    { Public declarations }

  end;

  TAnimal = class
  public
    constructor Create;
    function GetKind: string;
    function Voice: string; virtual;abstract;
  private
    Kind: string;
  end;

  TDog = class (TAnimal)
  public
    constructor Create;
    function Voice: string; override;
    function Eat: string; virtual;
  end;

  TCat = class (TAnimal)
  public
    constructor Create;
    function Voice: string;override;
    function Eat: string; virtual;
  end;


var

  FormAnimals: TFormAnimals;
  MyAnimal: TAnimal;

implementation

{$R *.lfm}

procedure TFormAnimals.FormCreate(Sender: TObject);
begin
  MyAnimal := TDog.Create;
end;

procedure TFormAnimals.FormDestroy(Sender: TObject);
begin
  MyAnimal.Free;
end;

procedure TFormAnimals.BtnVoiceClick(Sender: TObject);
begin
  LabelVoice.Caption := MyAnimal.Voice;
end;

constructor TAnimal.Create;
begin
  Kind := 'An animal';
end;

function TAnimal.GetKind: string;
begin
  GetKind := Kind;
end;

constructor TDog.Create;
begin
  Kind := 'A dog';
end;

function TDog.Voice: string;
Var VoiceSound:String;
begin

   Voice := 'Arf Arf';
    VoiceSound:= 'dog.wav';
    FormAnimals.PlaySound(VoiceSound,true);

end;

function TDog.Eat: string;
begin
  Eat := 'A bone, please!';
end;

constructor TCat.Create;
begin
  Kind := 'A cat';
end;

function TCat.Voice: string;
Var VoiceSound:String;
begin
  Voice := 'Mieow' ;
  VoiceSound:= 'cat.wav';
    FormAnimals.PlaySound(VoiceSound,true);
end;

function TCat.Eat: string;
begin
  Eat := 'A mouse, please!';
end;

procedure TFormAnimals.RbtnAnimalClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TAnimal.Create;
end;

procedure TFormAnimals.RbtnDogClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TDog.Create;
end;

procedure TFormAnimals.RbtnCatClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TCat.Create;
end;
 procedure  TFormAnimals.PlaySound(AWavFile: String; ASync: Boolean);
 var
  player: TPlaySound;
begin
  player := TPlaySound.Create(nil);
  try
    player.SoundFile := AWavFile;
    if Async then player.PlayStyle := psAsync else player.PlayStyle := psSync;
    player.Execute;
  finally
    player.Free;
  end;
end;


end.

try to execute it I getunit abstanimf;

{$MODE Delphi}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
    StdCtrls, Buttons, ExtCtrls, uplaysound;

type

  { TFormAnimals }

  TFormAnimals = class(TForm)
    playsound1: Tplaysound;
    LabelVoice: TLabel;
    BtnVoice: TButton;
    RbtnAnimal: TRadioButton;
    RbtnDog: TRadioButton;
    RbtnCat: TRadioButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BtnVoiceClick(Sender: TObject);
    procedure RbtnAnimalClick(Sender: TObject);
    procedure RbtnDogClick(Sender: TObject);
    procedure RbtnCatClick(Sender: TObject);
    procedure PlaySound(AWavFile: String; ASync: Boolean);

  private

  public
    { Public declarations }

  end;

  TAnimal = class
  public
    constructor Create;
    function GetKind: string;
    function Voice: string; virtual;abstract;
  private
    Kind: string;
  end;

  TDog = class (TAnimal)
  public
    constructor Create;
    function Voice: string; override;
    function Eat: string; virtual;
  end;

  TCat = class (TAnimal)
  public
    constructor Create;
    function Voice: string;override;
    function Eat: string; virtual;
  end;


var

  FormAnimals: TFormAnimals;
  MyAnimal: TAnimal;

implementation

{$R *.lfm}

procedure TFormAnimals.FormCreate(Sender: TObject);
begin
  MyAnimal := TDog.Create;
end;

procedure TFormAnimals.FormDestroy(Sender: TObject);
begin
  MyAnimal.Free;
end;

procedure TFormAnimals.BtnVoiceClick(Sender: TObject);
begin
  LabelVoice.Caption := MyAnimal.Voice;
end;

constructor TAnimal.Create;
begin
  Kind := 'An animal';
end;

function TAnimal.GetKind: string;
begin
  GetKind := Kind;
end;

constructor TDog.Create;
begin
  Kind := 'A dog';
end;

function TDog.Voice: string;
Var VoiceSound:String;
begin

   Voice := 'Arf Arf';
    VoiceSound:= 'dog.wav';
    FormAnimals.PlaySound(VoiceSound,true);

end;

function TDog.Eat: string;
begin
  Eat := 'A bone, please!';
end;

constructor TCat.Create;
begin
  Kind := 'A cat';
end;

function TCat.Voice: string;
Var VoiceSound:String;
begin
  Voice := 'Mieow' ;
  VoiceSound:= 'cat.wav';
    FormAnimals.PlaySound(VoiceSound,true);
end;

function TCat.Eat: string;
begin
  Eat := 'A mouse, please!';
end;

procedure TFormAnimals.RbtnAnimalClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TAnimal.Create;
end;

procedure TFormAnimals.RbtnDogClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TDog.Create;
end;

procedure TFormAnimals.RbtnCatClick(Sender: TObject);
begin
  MyAnimal.Free;
  MyAnimal := TCat.Create;
end;
 procedure  TFormAnimals.PlaySound(AWavFile: String; ASync: Boolean);
 var
  player: TPlaySound;
begin
  player := TPlaySound.Create(nil);
  try
    player.SoundFile := AWavFile;
    if Async then player.PlayStyle := psAsync else player.PlayStyle := psSync;
    player.Execute;
  finally
    player.Free;
  end;
end;


end.
It compiles with the following warnings
abstanimf.pas(136,29) Warning: Constructing a class "TAnimal" with abstract method "Voice"
abstanimf.pas(41,14) Hint: Found abstract method: Voice(<TAnimal>;<var AnsiString>):AnsiString;
When I execute it I get Class exception Runerror(211)
in line 82 LabelVoice.Caption:=MyAnimalVoice;
When I go on I get
Abstract method called.

Press OK to ignore and risk data corruption.
Press Abort to kill the program.
It is very clear that I lack some understanding regardind the classes
by I have re read the chapter in the book and I do not find my error
The LFM code is
object FormAnimals: TFormAnimals
  Left = 733
  Height = 233
  Top = 170
  Width = 278
  ActiveControl = BtnVoice
  Caption = 'Animals'
  ClientHeight = 233
  ClientWidth = 278
  Color = clBtnFace
  Font.CharSet = ANSI_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  LCLVersion = '1.8.0.6'
  object LabelVoice: TLabel
    Left = 39
    Height = 17
    Top = 168
    Width = 201
    Alignment = taCenter
    AutoSize = False
    Caption = 'Voice'
    Font.CharSet = ANSI_CHARSET
    Font.Color = clBlack
    Font.Height = -16
    Font.Name = 'Arial'
    Font.Style = [fsBold]
    ParentColor = False
    ParentFont = False
  end
  object BtnVoice: TButton
    Left = 152
    Height = 33
    Top = 56
    Width = 89
    Caption = '&Voice'
    OnClick = BtnVoiceClick
    TabOrder = 0
  end
  object RbtnAnimal: TRadioButton
    Left = 24
    Height = 21
    Top = 40
    Width = 62
    Caption = '&Animal'
    OnClick = RbtnAnimalClick
    TabOrder = 1
  end
  object RbtnDog: TRadioButton
    Left = 24
    Height = 21
    Top = 72
    Width = 46
    Caption = '&Dog'
    Checked = True
    OnClick = RbtnDogClick
    TabOrder = 2
    TabStop = True
  end
  object RbtnCat: TRadioButton
    Left = 24
    Height = 21
    Top = 104
    Width = 43
    Caption = '&Cat'
    OnClick = RbtnCatClick
    TabOrder = 3
  end
  object playsound1: Tplaysound
    About.Description.Strings = (
      'Plays WAVE sounds in Windows or Linux'
    )
    About.Title = 'PlaySound'
    About.Height = 400
    About.Width = 400
    About.Font.Color = clNavy
    About.Font.Height = -13
    About.BackGroundColor = clCream
    About.Version = '0.0.7'
    About.Authorname = 'Gordon Bamber'
    About.Organisation = 'Public Domain'
    About.AuthorEmail = 'minesadorada@charcodelvalle.com'
    About.ComponentName = 'PlaySound'
    About.LicenseType = abModifiedGPL
    PlayCommand = 'play'
    left = 192
    top = 124
  end
end

Thanks again.This forum is my lifeboat


wp

  • Hero Member
  • *****
  • Posts: 6370
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #4 on: February 25, 2018, 06:42:30 pm »
I wonder why you paste the code several times. And since this is a complete project why don't you pack the files into a zip and upload it? It is much easier for someone willing to help you if he can load the code into Lazarus and let Lazarus and/or the debugger do the work.

The root of the problem is here:

Code: Pascal  [Select]
  1. procedure TFormAnimals.RbtnAnimalClick(Sender: TObject);
  2. begin
  3.   MyAnimal.Free;
  4.   MyAnimal := TAnimal.Create;
  5. end;

TAninmal is an "abstract" class. This is because it contains an "abstract" method. This kind of methods is often defined in the very basic classes at the begin of a class hierarchy, but is implemented only in derived classes. Here the abstract method is "function Voice": Every animal (the basic class) has a voice, but every voice is different. Therefore, the derived class (the TDog, or TCat) must implement it. In TAnimal it is just something like a "forward declaration" so that the compiler knows it.

In the click procedure of BtnVoice you call this method:
Code: Pascal  [Select]
  1. procedure TFormAnimals.BtnVoiceClick(Sender: TObject);
  2. begin
  3.   LabelVoice.Caption := MyAnimal.Voice;
  4. end;
Voice is a "virtual" method, too. This means that the compiler uses the method which is implemented in the class created. Therefore, this code runs fine if MyAnimal has been created as TDog or TCat - these do provide an implementation for the abstract method. But if MyAnimal has been created as TAnimal as you do in the first cited code the program will crash with error 211: "Call to abstract method"
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jcaser1948

  • Jr. Member
  • **
  • Posts: 51
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #5 on: February 25, 2018, 07:51:36 pm »
Thanks. This means there is an error in the code Delphi 7 the Bible and Mastering Delphi 7  by Marco Cantu, or I did not understand properly the chapter.
Thanks again

wp

  • Hero Member
  • *****
  • Posts: 6370
Re: PlaySound ('dog.wav', 0, snd_Async);
« Reply #6 on: February 25, 2018, 08:06:24 pm »
I think that the author wanted to demonstrate what happens when an instance of an abstract class is created. Please read the text carefully.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10