constantSignalValue = 0.3;
(* from here we assume sample count of 1000 *)
sampleCount = 1000;
originalConstantSignal = constantSignalValue&/@Range[sampleCount];
(* 1 bit quantization of constant signal of 1000 samples *)
quantizedSignal = Round[constantSignalValue]&/@Range[sampleCount];
SetDirectory@NotebookDirectory[];

signalError = originalConstantSignal-quantizedSignal;

ListPlot[quantizedSignal]
ListPlot[signalError]
(* Plot of quantized signal *)

(* Plot of quantization error *)

(*As expected, average of signal error is 0.3 *)
Mean[signalError]

(* Same qantization, but with dithering in range -0.5, 0.5 *)

quantizedDitheredSignal = Round[constantSignalValue+RandomReal[]-0.5]&/@Range[sampleCount];

(* Plot of quantized dithered signal *)

ListPlot[quantizedDitheredSignal,Filling->Axis]

Image[Join[{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},{quantizedDitheredSignal},1]]

(*Dithered signal error *)

ditheredSignalError = originalConstantSignal-quantizedDitheredSignal;
ListPlot[ditheredSignalError]

Mean[ditheredSignalError]

0.02800000000000019

MyPeriodogram[x_,col_:Black,range_:Full]:=ListPlot[Abs@Fourier[x][[;;sampleCount/2]],PlotRange->range,Filling->Axis,FillingStyle->{Thickness[0.05],col}]

(*Frequency plot of error signal*)

MyPeriodogram[signalError]

MyPeriodogram[ditheredSignalError]

ListAnimate[{MyPeriodogram[signalError,Red,{0,10}],MyPeriodogram[ditheredSignalError,Black,{0,10}]}]

Export["spectrum_quantization_noise_comparison.gif",{MyPeriodogram[signalError,Red,{0,10}],MyPeriodogram[ditheredSignalError,Black,{0,10}]},"DisplayDurations"->2];

MyFilter[x_]:=RecurrenceFilter[ToDiscreteTimeModel[ButterworthFilterModel[{5,0.1}],1],x,Padding->"Fixed"]

(* Plot low pass filter applied on quantized signal and its error *)

Show[ListPlot[MyFilter[quantizedDitheredSignal],PlotRange->{0,1}],ListPlot[originalConstantSignal,PlotStyle->Red],ListPlot[quantizedDitheredSignal,PlotStyle->Green]]

ListPlot[MyFilter[ditheredSignalError]]

(*Let's try a different dithering noise function*)

quantizedDitheredSignalGolden = Round[constantSignalValue+FractionalPart[GoldenRatio*#1]-0.5]&/@Range[sampleCount];

ditheredSignalErrorGolden = originalConstantSignal-quantizedDitheredSignalGolden;

Mean[ditheredSignalErrorGolden]

Show[ListPlot[MyFilter[quantizedDitheredSignalGolden],PlotRange->{0,1}],ListPlot[originalConstantSignal,PlotStyle->Red],ListPlot[quantizedDitheredSignalGolden,PlotStyle->Green]]

MyPeriodogram[ditheredSignalErrorGolden]

Image[Join[{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},{quantizedDitheredSignalGolden},1]]

sineFunction[x_]:= 0.5 + Sin[x/250*2*π]*0.5;

originalSineSignal = sineFunction[#1]&/@Range[sampleCount];
(* 1 bit quantization of sine signal*)
quantizedSineSignal = Round[sineFunction[#1]]&/@Range[sampleCount];

Show[ListPlot[originalSineSignal,PlotStyle->Red],
ListPlot[quantizedSineSignal]]

sineSignalError = originalSineSignal-quantizedSineSignal;

ListPlot[sineSignalError]

(*Average error... not bad, huh?*)

Mean[sineSignalError]

(*But error has lots of low and high frequencies*)

MyPeriodogram[quantizedSineSignal]
MyPeriodogram[sineSignalError]

ListPlot[MyFilter[quantizedSineSignal]]

ListPlot[MyFilter[sineSignalError]]

(* 1 bit quantization of dithered sine signal*)
quantizedDitheredSineSignal = Round[sineFunction[#1]+RandomReal[]-0.5]&/@Range[sampleCount];

Show[ListPlot[originalSineSignal,PlotStyle->Red],
ListPlot[quantizedDitheredSineSignal]]

Image[Join[{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},1]]
ditheredSineSignalError = originalSineSignal-quantizedDitheredSineSignal;

ListPlot[ditheredSineSignalError]

ListAnimate[{MyPeriodogram[sineSignalError,Red,{0,4}],MyPeriodogram[ditheredSineSignalError,Black,{0,4}]}]

Export["spectrum_quantization_noise_comparison_sine.gif",{MyPeriodogram[sineSignalError,Red,{0,4}],MyPeriodogram[ditheredSineSignalError,Black,{0,4}]},"DisplayDurations"->2];

Mean[ditheredSineSignalError]

Show[ListPlot[MyFilter[quantizedDitheredSineSignal]],ListPlot[MyFilter[quantizedSineSignal],PlotStyle->Green],ListPlot[originalSineSignal,PlotStyle->Red]]

Show[ListPlot[MyFilter[ditheredSineSignalError],PlotRange->{-0.3,0.3}],ListPlot[MyFilter[sineSignalError],PlotStyle->Red]]

quantizedDitheredSineSignalGolden = Round[sineFunction[#1]+FractionalPart[GoldenRatio*#1]-0.5]&/@Range[sampleCount];
Image[Join[{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},1]]

ditheredSineSignalGoldenError = originalSineSignal-quantizedDitheredSineSignalGolden;

ListAnimate[{MyPeriodogram[sineSignalError,Red,{0,4}],MyPeriodogram[ditheredSineSignalError,Black,{0,4}],MyPeriodogram[ditheredSineSignalGoldenError,Blue,{0,4}]}]
Export["spectrum_quantization_noise_golden__comparison_sine.gif",{MyPeriodogram[sineSignalError,Red,{0,4}],MyPeriodogram[ditheredSineSignalError,Black,{0,4}],MyPeriodogram[ditheredSineSignalGoldenError,Blue,{0,4}]},"DisplayDurations"->2];

Show[ListPlot[MyFilter[quantizedDitheredSineSignalGolden]],ListPlot[originalSineSignal,PlotStyle->Red]]

ListPlot[MyFilter[ditheredSineSignalGoldenError]]

Image[Join[{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignal},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},{quantizedDitheredSineSignalGolden},1]]