Hallo,
ich will Töne anhand der Frequenz und der Dauer erstellen. Console.Beep erledigt das ja schon mal ganz schön. Allerdings will ich die Töne nicht über den Systemlautsprecher ausgeben lassen, sondern über die Soundkarte/externen Lautsprecher. Kann mir da vielleicht jemand weiterhelfen?
Danke.
Hallo klausm,
das Thema wurde schon einige Male besprochen. Bitte benutze die Forumssuche und poste die besten Treffer hier. Vielen Dank!
herbivore
ok, ich hab zwar gesucht aber einfach zu durchschauendes gefunden, sondern nur ellenlange codestücke. aber dann halt so und umständlicher....
Ich habs mit dem Code von hier versucht und Teile davon verwendet. Vielleicht sagen einigen ja 5-Ton-Folgen was, wird zur Alarmierung von Rettungsdienst etc. verwendet. Dabei werden 5 Töne hintereinander abgespielt, je nach "Schleife". Die setzt sich eben aus 5 Zahlen zusammen, jede Zahl ist ein Ton der 70ms dauert, danach folgt der nächste bis eben alle 5 durch sind, und das 2x hintereinander mit einer Unterbrechung von 600ms.
Das klappt zwar alles, allerdings "hängt" das abspielen irgendwie. Vielleicht liegt's an Vista oder an meiner Soundkarte (Realtek AC'97).
hier mein code
private static int[] Hertz = { 2600, 1060, 1160, 1270, 1400, 1530, 1670, 1830, 2000, 2200, 2400 };
public static void play5Ton( int tonfolge, System.Windows.Forms.Form f )
{
/*
* 2 gleiche Töne folgen -> 2400 abspielen an 2. Stelle
* wenn dann wieder der gleiche Ton -> wieder normaler Ton
*/
bool folgen = false;
List<int> hertztoene = new List<int>();
for ( int i = 0; i < 5; i++ )
{
char c = tonfolge.ToString()[i];
int ton = 0;
if ( i > 0 && c.Equals(tonfolge.ToString()[i-1]) && !folgen)
{
ton = 10;
folgen = true;
}
else
{
switch ( c )
{
case '1':
ton = 1; break;
case '2':
ton = 2; break;
case '3':
ton = 3; break;
case '4':
ton = 4; break;
case '5':
ton = 5; break;
case '6':
ton = 6; break;
case '7':
ton = 7; break;
case '8':
ton = 8; break;
case '9':
ton = 9; break;
}
folgen = false;
}
hertztoene.Add( Hertz[ton] );
}
SoundGen sg = new SoundGen( f );
for ( int j = 0; j < 2; j++ )
{
foreach ( int ton in hertztoene )
{
sg.Beep( ton, 70 );
//Console.Beep( ton, 70 );
}
if ( j == 0)
Thread.Sleep( 600 );
}
}
hier noch der Code für die SoundGenerator Klasse
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
namespace SG
{
public class SoundGen
{
private struct Osc
{
public double dphi; // frequency
public double phase; // phase accumulator
public int duration; // duration in msec.
}
#region constants
/// <summary>
/// 10 ms in bytes
/// </summary>
public const int NotifySize = 160 * 2 * 2;
/// <summary>
/// Number of Record notifications
/// </summary>
private const int RecordNotifications = 4;
/// <summary>
/// buffer size in bytes
/// </summary>
public const int OutputBufferSize = NotifySize * RecordNotifications;
/// <summary>
/// Final buffer size
/// 220 ms
/// </summary>
private const int BufferLength = 320 * 2;//*220 msec.
#endregion
#region fields
private SecondaryBuffer buffer = null;
private Device device = null;
private BufferDescription description = null;
private WaveFormat format;
private bool squareWave = false;
private bool playing = false;
Osc osc = new Osc();
#endregion
#region Properties
public bool SquareWave
{
get
{
return squareWave;
}
set
{
if ( squareWave != value )
squareWave = value;
}
}
public SecondaryBuffer Buffer
{
get
{
return buffer;
}
}
#endregion
#region Constructor
/// <summary>
/// Constructor
/// </summary>
public SoundGen(Control control)
: base()
{
try
{
device = new Device();
device.SetCooperativeLevel( control, CooperativeLevel.Normal );
}
catch
{
}
format = new WaveFormat();
format.BlockAlign = 2 * 2;
format.AverageBytesPerSecond = 16000 * 2;
format.FormatTag = WaveFormatTag.Pcm;
format.Channels = 1 * 2; // stereo
format.BitsPerSample = 16;
format.SamplesPerSecond = 8000;
description = new BufferDescription( format );
description.BufferBytes = OutputBufferSize;
description.ControlVolume = true;
description.CanGetCurrentPosition = true;
buffer = new SecondaryBuffer( description, device );
buffer.Volume = -1500;
Clear();
}
#endregion
#region Beep
public void Beep( int frequency, int duration )
{
if ( playing )
return;
osc.duration = duration;
osc.dphi = frequency * 1.25e-4;
osc.phase = 0;
playing = true;
int time = 0;
int lockSize;
int playPos;
int offset = 0;
buffer.Play( 0, BufferPlayFlags.Looping );
Generate( offset );
while ( playing )
{
playPos = buffer.PlayPosition;
lockSize = playPos - offset;
if ( lockSize < 0 )
lockSize += OutputBufferSize;
lockSize -= ( lockSize % BufferLength );
if ( lockSize == 0 )
{ }
else
{
offset += Generate( offset );
offset %= OutputBufferSize;
time += 20;
if ( time >= duration )
playing = false;
}
}
//Hier fällt auf, wenn ich hier stoppe, gibt er keinen Ton von sich!
buffer.Stop();
}
#endregion
private int Generate( int offset )
{
byte[] data = new byte[BufferLength];
Int32 outword;
for ( int i = 0; i < BufferLength; )
{
if ( !squareWave )
// Sine
outword = (Int32)( Math.Sin( osc.phase ) * ( 32767 ) );
else
{
// Square
if ( Math.Sin( osc.phase ) >= 0 )
outword = 0x7fff;
else
outword = 0x8000;
}
osc.phase += 2 * Math.PI * osc.dphi;
if ( osc.phase > Math.PI * 2 )
osc.phase -= Math.PI * 2;
data[i++] = (System.Byte)( outword & 0xff );//lsb
data[i++] = (System.Byte)( ( outword >> 8 ) & 0xff );//msb
data[i++] = (System.Byte)( outword & 0xff );//lsb
data[i++] = (System.Byte)( ( outword >> 8 ) & 0xff );//msb
}
buffer.Write( offset, data, LockFlag.None );
return data.Length;
}
private void Zero( int offset )
{
byte[] data = new byte[BufferLength];
osc.phase = 0;
for ( int i = 0; i < BufferLength; )
{
data[i++] = (System.Byte)( 0 & 0xff );//lsb
data[i++] = (System.Byte)( ( 0 >> 8 ) & 0xff );//msb
data[i++] = (System.Byte)( 0 & 0xff );//lsb
data[i++] = (System.Byte)( ( 0 >> 8 ) & 0xff );//msb
}
buffer.Write( offset, data, LockFlag.None );
}
private void Clear()
{
Zero( 0 );
buffer.SetCurrentPosition( BufferLength );
Zero( BufferLength );
buffer.SetCurrentPosition( BufferLength * 2 );
Zero( BufferLength * 2 );
buffer.SetCurrentPosition( BufferLength * 3 );
Zero( BufferLength * 3 );
buffer.SetCurrentPosition( 0 );
}
}
}
Wo an welcher Stelle was "hängt" kannst du nur mit dem Debugger prüfen oder Profilern.
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Ich weiß alte Karmellen. Wäre aber schon interessant, warum die ersten Töne verzehrt klingen.