Wow: Bis gerade eben wußte ich gar nicht, daß man in GoldWave Sounddaten auch als
ASCII ausgeben kann. Man lernt immer noch dazu.
Um alle Samples der Text-Datei "schnell hintereinander" abzuspielen ist es also am einfachsten folgendes zu machen:
1. Die Textdatei mit den Audiodaten (den Samples) in Goldwave laden.
2. Die Audiodatei als WAV abspeichern.
3. Die Wav Datei in Delphi mit SndPlaySound abspielen. (Ja, das ist wirklich nichts anderes als alle Samples (nicht
Töne) in der angegebenen Geschwindigkeit schnell hintereinander abzuspielen)
Wenn es doch die harte Tour sein soll, dann funktioniert der Code von igel457 durchaus. Ein paar klitzekleine Anpassungen, eine Listbox und einen Button auf die Form, und ich konnte mir das Gezirpe auch mit Delphi anhören:
Delphi-Quellcode:
procedure TForm1.MakeSound;
{Reads data from ListBox1, writes tone to memory and plays it}
var
WaveFormatEx: TWaveFormatEx;
MS: TMemoryStream;
i, TempInt, DataCount, RiffCount: integer;
SoundValue: byte;
w: double; // omega ( 2 * pi * frequency)
Sample: smallint;
const
Mono: Word = $0001;
// Eigentlich müßte man hier aus der ersten Zeile der Listbox die Infos zu Abspielfrequenz auslesen anstatt hart 22050 zu setzen
SampleRate: Integer = 22050; // 8000, 11025, 22050, or 44100 <--Hier Samplerate einsetzen
RiffId: string = 'RIFF';
WaveId: string = 'WAVE';
FmtId: string = 'fmt ';
DataId: string = 'data';
begin
with WaveFormatEx do
begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := Mono;
nSamplesPerSec := SampleRate;
wBitsPerSample := $0010;
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 := ListBox1.Items.Count-1; // sound data from Listbox
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
DecimalSeparator := '.';
for i := 1 to ListBox1.Count-1 do
begin
// Sample := round(StrToFloat(ListBox1.Items[i])*127)+128;
Sample := round(StrToFloat(ListBox1.Items[i])*32767);
Write(Sample,SizeOf(Sample));
end;
{now play the sound}
sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
MS.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Items.LoadFromFile('c:\temp\test-1.txt');
MakeSound;
end;
Ich weiß nur nicht, ob es die MemoryStreams schon in Delphi3 gegeben hat...
Gruß
Michael
Edit 09.09.2006: vlees91 hat natürlich recht, das Aufruf von MakeSound erfolgt natürlich ohne Parameter. Hab' mal wieder zwei unterschiedliche Code-Zustände zusammenkopiert. Sorry.